mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Merge pull request #1146 from redonion23/fix/1078-reset-keeps-keyframes
This commit is contained in:
commit
f0fa92ceef
3 files changed
+37
-8
No files matched your search
@@ -631,11 +631,12 @@ fn reset(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let (cid, lid, uid) = prop_ref(s, p, "prop.reset")?;
|
||||
let def = p.get("default").cloned();
|
||||
let own = default_value(s, cid, lid, uid);
|
||||
with_prop(s, "Reset Property", None, cid, lid, uid, |pr, _| {
|
||||
pr.keys.clear();
|
||||
with_prop(s, "Reset Property", None, cid, lid, uid, |pr, t| {
|
||||
pr.expr = None;
|
||||
// An animated property keeps its keyframes and gets the default as a key at the
|
||||
// current time, as in After Effects (#1078).
|
||||
if let Some(d) = def.as_ref().and_then(|d| pr.value.coerce_json(d)).or(own) {
|
||||
pr.value = d;
|
||||
pr.set_value_at(t, d);
|
||||
}
|
||||
Ok(Value::Null)
|
||||
})
|
||||
@@ -1238,7 +1239,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Reset Property",
|
||||
[],
|
||||
None,
|
||||
"{layer?, path|prop, default?} → removes keyframes and expression; the value becomes `default`, else the property's own (an effect parameter's, a Transform property's)",
|
||||
"{layer?, path|prop, default?} → removes the expression; the value becomes `default`, else the property's own (an effect parameter's, a Transform property's), as a keyframe at the current time when the property is animated",
|
||||
has_layers,
|
||||
reset
|
||||
),
|
||||
|
||||
@@ -597,8 +597,10 @@ fn reset_gives_a_property_its_default() {
|
||||
assert_eq!(v(&s, "transform/anchor"), KV::Vec3([50.0, 50.0, 0.0]), "the solid's centre");
|
||||
assert_eq!(v(&s, "transform/position"), KV::Vec3([200.0, 150.0, 0.0]), "the comp's centre");
|
||||
assert_eq!(v(&s, "transform/scale"), KV::Vec3([100.0; 3]));
|
||||
assert_eq!(v(&s, "transform/rotation"), KV::Scalar(0.0));
|
||||
assert!(!prop(&s, l, "transform/rotation").is_animated());
|
||||
// Animated: the default becomes the key at the current time (0 s), the 1 s key stays (#1078).
|
||||
let rot = prop(&s, l, "transform/rotation");
|
||||
assert_eq!(rot.keys.len(), 2);
|
||||
assert_eq!(rot.value_at(effectcraft_time::Tick::ZERO), KV::Scalar(0.0));
|
||||
assert_eq!(v(&s, "transform/opacity"), KV::Scalar(100.0));
|
||||
assert!(prop(&s, l, "transform/opacity").expr.is_none());
|
||||
assert_eq!(v(&s, "effects/#1/blurriness"), blur);
|
||||
@@ -607,6 +609,31 @@ fn reset_gives_a_property_its_default() {
|
||||
assert_eq!(v(&s, "transform/opacity"), KV::Scalar(30.0));
|
||||
}
|
||||
|
||||
/// #1078: resetting an animated property keeps its keyframes and keys the default at the
|
||||
/// current time, as in After Effects; undo brings the old keys back.
|
||||
#[test]
|
||||
fn reset_keys_the_default_on_an_animated_property() {
|
||||
let (mut s, l) = setup();
|
||||
animate(&mut s, l, "transform/scale", &[(0.0, json!([50, 50, 100])), (2.0, json!([150, 150, 100]))]);
|
||||
s.execute("time.set", json!({"time": 1})).unwrap();
|
||||
s.execute("prop.reset", json!({"layer": l, "path": "transform/scale"})).unwrap();
|
||||
let pr = prop(&s, l, "transform/scale");
|
||||
let at = |sec: f64| pr.value_at(effectcraft_time::Tick::from_seconds_f64(sec));
|
||||
assert_eq!(pr.keys.len(), 3, "the 0 s and 2 s keys stay, one is added at 1 s");
|
||||
assert_eq!(at(0.0), KV::Vec3([50.0, 50.0, 100.0]));
|
||||
assert_eq!(at(1.0), KV::Vec3([100.0; 3]));
|
||||
assert_eq!(at(2.0), KV::Vec3([150.0, 150.0, 100.0]));
|
||||
// On a key, the key takes the default.
|
||||
s.execute("time.set", json!({"time": 2})).unwrap();
|
||||
s.execute("prop.reset", json!({"layer": l, "path": "transform/scale"})).unwrap();
|
||||
let pr = prop(&s, l, "transform/scale");
|
||||
assert_eq!(pr.keys.len(), 3);
|
||||
assert_eq!(pr.value_at(effectcraft_time::Tick::from_seconds_f64(2.0)), KV::Vec3([100.0; 3]));
|
||||
s.execute("edit.undo", json!({})).unwrap();
|
||||
s.execute("edit.undo", json!({})).unwrap();
|
||||
assert_eq!(prop(&s, l, "transform/scale").keys.len(), 2);
|
||||
}
|
||||
|
||||
/// #363: dropped on one of the target's values the pick whip picks that dimension
|
||||
/// (`position[0]`), as in After Effects; a multi-dimension property follows it on every axis.
|
||||
#[test]
|
||||
|
||||
+3
-2
@@ -573,8 +573,9 @@ Extension points and the bundled extensions: [plugins.md](plugins.md).
|
||||
(`effectControls.prop.<uid>.value[.<d>]`), it runs `prop.pickWhip`: the reference replaces the
|
||||
property's expression, or is added as one, and the expression is enabled.
|
||||
* A property's menu (right-click its name; entries `timeline.prop.<uid>.menu.<entry>`): Reset
|
||||
(`prop.reset`: no keyframes or expression, and the property's default value, an effect
|
||||
parameter's or a Transform property's), Edit Value… (`prop.set {layer, prop}` without `value`
|
||||
(`prop.reset`: no expression, and the property's default value, an effect parameter's or a
|
||||
Transform property's; an animated property keeps its keyframes and gets the default as a
|
||||
keyframe at the current time), Edit Value… (`prop.set {layer, prop}` without `value`
|
||||
opens the value dialog), Separate Dimensions (Position: `prop.separateDimensions {layer,
|
||||
value}`), Add / Remove Expression (`prop.setExpression {layer, prop}`) and Add Property to
|
||||
Essential Graphics (`essential.addProperty`).
|
||||
|
||||
Reference in new issue
Block a user