Clipboard: Orientation and Rotation headers as After Effects writes them (#1908)

This commit is contained in:
tylerjenningsw committed 2026-10-20 08:47:51 -04:00
1 parent 40d5466cc5
commit 9313784304
2 files changed
+8 -6

No files matched your search

+4 -3
View File
@@ -48,13 +48,14 @@ pub(crate) fn text(project: &Project, comp: &Comp, keys: &[KeyRef], statics: &[(
continue;
};
let Some(dims) = rows.first().map(|(_, v)| v.len()).filter(|n| *n > 0) else { continue };
// After Effects labels only the first of Orientation's three columns, and names Z
// Rotation plain Rotation (as AE2Blend expects).
let columns = match dims {
1 => vec![unit.to_string()],
_ if *id == "orientation" => vec![format!("X {unit}")],
_ => ["X", "Y", "Z"].iter().take(dims).map(|axis| format!("{axis} {unit}")).collect(),
};
// 3D layers show Rotation as Z Rotation.
let name = if *id == "rotation" && layer.is_3d() { "Z Rotation" } else { pr.name.as_str() };
blocks.push_str(&format!("Transform\t{name}\n\tFrame\t{}\n", columns.join("\t")));
blocks.push_str(&format!("Transform\t{}\n\tFrame\t{}\n", pr.name, columns.join("\t")));
for (frame, values) in rows {
let values: Vec<String> = values.into_iter().map(num).collect();
blocks.push_str(&format!("\t{frame}\t{}\n", values.join("\t")));
+4 -3
View File
@@ -98,14 +98,15 @@ fn a_copied_transform_group_lists_what_the_layer_shows() {
let names: Vec<&str> = text.lines().filter_map(|line| line.strip_prefix("Transform\t")).collect();
assert_eq!(names, ["Anchor Point", "Position", "Scale", "Rotation", "Opacity"], "a 2D layer has no Orientation or X / Y Rotation");
assert!(text.contains("\tFrame\tX percent\tY percent\tZ percent\n\t0\t50\t50\t100\n\t24\t150\t150\t100\n"), "{text}");
// 3D: Orientation, X / Y Rotation, and Rotation is Z Rotation.
// 3D: Orientation and X / Y Rotation. Z Rotation stays Rotation, and Orientation's three
// values sit under one label, as After Effects writes them.
edit_layer(&mut s, l, |l| l.switches.three_d = true);
s.execute("prop.select", json!({"layer": l.0, "prop": transform, "selectKeys": false})).unwrap();
s.execute("edit.copy", json!({})).unwrap();
let text = s.state.keyframe_text.clone().unwrap();
let names: Vec<&str> = text.lines().filter_map(|line| line.strip_prefix("Transform\t")).collect();
assert_eq!(names, ["Anchor Point", "Position", "Scale", "Orientation", "X Rotation", "Y Rotation", "Z Rotation", "Opacity"]);
assert!(text.contains("Transform\tOrientation\n\tFrame\tX degrees\tY degrees\tZ degrees\n\t\t0\t0\t0\n"), "{text}");
assert_eq!(names, ["Anchor Point", "Position", "Scale", "Orientation", "X Rotation", "Y Rotation", "Rotation", "Opacity"]);
assert!(text.contains("Transform\tOrientation\n\tFrame\tX degrees\n\t\t0\t0\t0\n"), "{text}");
}
#[test]