mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-27 11:37:02 -06:00
Merge branch 'main' into worktree-agent-a15cecfec57d5290d
# Conflicts: # crates/effects/src/ocio.rs # crates/engine/src/commands/stubs.rs # docs/parity.md
This commit is contained in:
@@ -438,8 +438,35 @@ pub fn shape_stroke(ids: &mut Ids, color: [f64; 4], width: f64) -> PropGroup {
|
||||
.with(ids.prop("gap", "Gap", Value::Scalar(0.0)).with_ui(ParamUi::Pixels))
|
||||
.with(ids.prop("offset", "Offset", Value::Scalar(0.0)).with_ui(ParamUi::Pixels)),
|
||||
)
|
||||
.with(stroke_taper(ids))
|
||||
.with(stroke_wave(ids))
|
||||
}
|
||||
|
||||
/// Stroke ▸ Taper (After Effects 17.1+): width ramps at the start and end of each path.
|
||||
pub fn stroke_taper(ids: &mut Ids) -> PropGroup {
|
||||
ids.group("taper", "Taper")
|
||||
.with(ids.prop("units", "Length Units", Value::Enum(0)).with_ui(popup(&["Pixels", "Percent"])))
|
||||
.with(ids.prop("startLength", "Start Length", Value::Scalar(0.0)).with_ui(ParamUi::Pixels))
|
||||
.with(ids.prop("endLength", "End Length", Value::Scalar(0.0)).with_ui(ParamUi::Pixels))
|
||||
.with(ids.prop("startWidth", "Start Width", Value::Scalar(100.0)).with_ui(slider(0.0, 100.0, 0.0, 100.0, 1)))
|
||||
.with(ids.prop("endWidth", "End Width", Value::Scalar(100.0)).with_ui(slider(0.0, 100.0, 0.0, 100.0, 1)))
|
||||
.with(ids.prop("startEase", "Start Ease", Value::Scalar(0.0)).with_ui(slider(0.0, 100.0, 0.0, 100.0, 1)))
|
||||
.with(ids.prop("endEase", "End Ease", Value::Scalar(0.0)).with_ui(slider(0.0, 100.0, 0.0, 100.0, 1)))
|
||||
}
|
||||
|
||||
/// Stroke ▸ Wave: the width oscillates along the path.
|
||||
pub fn stroke_wave(ids: &mut Ids) -> PropGroup {
|
||||
ids.group("wave", "Wave")
|
||||
.with(ids.prop("amount", "Amount", Value::Scalar(0.0)).with_ui(slider(0.0, 100.0, 0.0, 100.0, 1)))
|
||||
.with(ids.prop("units", "Units", Value::Enum(0)).with_ui(popup(&["Pixels", "Cycles"])))
|
||||
.with(ids.prop("wavelength", "Wavelength", Value::Scalar(20.0)).with_ui(ParamUi::Pixels))
|
||||
.with(ids.prop("cycles", "Cycles", Value::Scalar(10.0)).with_ui(slider(0.0, 1000.0, 0.0, 50.0, 1)))
|
||||
.with(ids.prop("phase", "Phase", Value::Scalar(0.0)).with_ui(ParamUi::Angle))
|
||||
}
|
||||
|
||||
/// Match ids of the optional Dash/Gap pairs After Effects adds with the Dashes "+" button.
|
||||
pub const EXTRA_DASHES: [(&str, &str); 2] = [("dash2", "gap2"), ("dash3", "gap3")];
|
||||
|
||||
pub fn shape_gradient_fill(ids: &mut Ids, radial: bool, start: [f64; 2], end: [f64; 2], g: Gradient) -> PropGroup {
|
||||
indexed(ids.group("gfill", "Gradient Fill 1"))
|
||||
.with(ids.prop("blend", "Blend Mode", Value::Enum(0)).with_ui(ParamUi::Hidden))
|
||||
@@ -475,6 +502,8 @@ pub fn shape_gradient_stroke(ids: &mut Ids, radial: bool, start: [f64; 2], end:
|
||||
.with(ids.prop("gap", "Gap", Value::Scalar(0.0)).with_ui(ParamUi::Pixels))
|
||||
.with(ids.prop("offset", "Offset", Value::Scalar(0.0)).with_ui(ParamUi::Pixels)),
|
||||
)
|
||||
.with(stroke_taper(ids))
|
||||
.with(stroke_wave(ids))
|
||||
}
|
||||
|
||||
pub fn shape_trim(ids: &mut Ids, start: f64, end: f64, offset: f64) -> PropGroup {
|
||||
|
||||
@@ -264,7 +264,12 @@ pub struct Comp {
|
||||
pub markers: Vec<Marker>,
|
||||
pub shutter_angle: f64,
|
||||
pub shutter_phase: f64,
|
||||
/// Samples Per Frame: the minimum motion-blur samples (and the count for 3D layers).
|
||||
pub motion_blur_samples: u32,
|
||||
/// Adaptive Sample Limit (Composition Settings ▸ Advanced): the most samples a 2D layer gets
|
||||
/// when it moves far within the shutter.
|
||||
#[serde(default = "adaptive_limit_default")]
|
||||
pub motion_blur_adaptive_limit: u32,
|
||||
#[serde(default)]
|
||||
pub renderer: Renderer,
|
||||
/// Comp switches (timeline toolbar).
|
||||
@@ -300,6 +305,10 @@ fn yes() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn adaptive_limit_default() -> u32 {
|
||||
128
|
||||
}
|
||||
|
||||
impl Comp {
|
||||
pub fn new(width: u32, height: u32, frame_rate: FrameRate, duration: Tick) -> Comp {
|
||||
Comp {
|
||||
@@ -316,6 +325,7 @@ impl Comp {
|
||||
shutter_angle: 180.0,
|
||||
shutter_phase: -90.0,
|
||||
motion_blur_samples: 16,
|
||||
motion_blur_adaptive_limit: 128,
|
||||
renderer: Renderer::Classic3D,
|
||||
hide_shy: false,
|
||||
enable_motion_blur: true,
|
||||
|
||||
@@ -529,6 +529,13 @@ impl PropGroup {
|
||||
})
|
||||
}
|
||||
/// Parent group of the node with `uid`.
|
||||
pub fn parent_of(&self, uid: Uid) -> Option<&PropGroup> {
|
||||
if self.children.iter().any(|c| c.uid() == uid) {
|
||||
return Some(self);
|
||||
}
|
||||
self.groups().find_map(|g| g.parent_of(uid))
|
||||
}
|
||||
/// Parent group of the node with `uid`.
|
||||
pub fn parent_of_mut(&mut self, uid: Uid) -> Option<&mut PropGroup> {
|
||||
if self.children.iter().any(|c| c.uid() == uid) {
|
||||
return Some(self);
|
||||
|
||||
Reference in New Issue
Block a user