Shapes: add the Wiggle Transform path operation, which wiggles paths and each Repeater copy

A shape layer's Contents > Add menu had every After Effects path operation
except Wiggle Transform. It is now a shape item (layer.addShapeItem kind
wiggler, "ADBE Vector Filter - Wiggler" for scripts) with Wiggles/Second,
Correlation, Temporal Phase, Spatial Phase, Random Seed and a Transform
group whose Anchor Point, Position, Scale and Rotation set how far each
transformation wiggles.

The values come from the Wiggly selector's noise, with each Repeater copy
as one unit: the copies of a Repeater above the operation, in its group or
a nested one, wiggle independently as far as Correlation allows, and the
copies of a Repeater below it wiggle the same way. A paint above it whose
paths all move by one matrix moves its gradient and stroke scale with them.
The layer cache keys a layer with a Wiggle Transform by time.
This commit is contained in:
dotCooCoo
2026-10-24 18:11:29 -07:00
parent 991904888a
commit 62cd2364d5
11 changed files with 362 additions and 6 deletions
+8
View File
@@ -147,6 +147,7 @@ pub const SHAPE_ITEMS: &[(&str, &str)] = &[
("trim", "ADBE Vector Filter - Trim"),
("twist", "ADBE Vector Filter - Twist"),
("wiggle", "ADBE Vector Filter - Roughen"),
("wiggler", "ADBE Vector Filter - Wiggler"),
("zigzag", "ADBE Vector Filter - Zigzag"),
];
@@ -208,6 +209,12 @@ const SHAPE_PROPS: &[(&str, &str, &str)] = &[
("pucker", "amount", "ADBE Vector PuckerBloat Amount"),
("twist", "angle", "ADBE Vector Twist Angle"),
("twist", "center", "ADBE Vector Twist Center"),
("wiggler", "speed", "ADBE Vector Xform Temporal Freq"),
("wiggler", "correlation", "ADBE Vector Correlation"),
("wiggler", "phase", "ADBE Vector Temporal Phase"),
("wiggler", "spatialPhase", "ADBE Vector Spatial Phase"),
("wiggler", "seed", "ADBE Vector Random Seed"),
("wiggler", "transform", "ADBE Vector Wiggler Transform"),
("merge", "mode", "ADBE Vector Merge Type"),
];
@@ -393,6 +400,7 @@ pub fn shape_kind(name: &str) -> Option<&'static str> {
"twist" => "twist",
"zigzag" => "zigzag",
"wigglepaths" => "wiggle",
"wiggletransform" => "wiggler",
"mergepaths" => "merge",
_ => return None,
})
+25
View File
@@ -321,6 +321,31 @@ fn match_names_and_lookups() {
assert_eq!(sh.props.prop("contents/#1/contents/fill/color").unwrap().value, KV::Color([1.0, 0.0, 0.0, 1.0]));
}
/// Scripts add a Wiggle Transform by its match name or display name and reach its properties.
#[test]
fn wiggle_transform_by_match_name() {
let mut s = session();
let o = ok(
&mut s,
r#"
var c = app.project.items.addComp("W", 200, 200, 1, 2, 30);
var sh = c.layers.addShape();
var root = sh.property("ADBE Root Vectors Group");
var w = root.addProperty("ADBE Vector Filter - Wiggler");
var byName = root.addProperty("Wiggle Transform");
w.property("ADBE Vector Wiggler Transform").property("Position").setValue([20, 10]);
[
w.matchName, w.name, byName.matchName, w.property("ADBE Vector Xform Temporal Freq").value,
w.property("ADBE Vector Spatial Phase").name, w.property("ADBE Vector Wiggler Transform").name
]
"#,
);
assert_eq!(o.result, json!(["ADBE Vector Filter - Wiggler", "Wiggle Transform 1", "ADBE Vector Filter - Wiggler", 2, "Spatial Phase", "Transform"]));
let (_, c) = comp_named(&s, "W");
let sh = c.layers.iter().find(|l| l.props.sub("contents").is_some()).unwrap();
assert_eq!(sh.props.prop("contents/wiggler/transform/position").unwrap().value, KV::Vec2([20.0, 10.0]));
}
#[test]
fn keyframes_eases_and_interpolation() {
let mut s = session();