mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-06 02:20:50 +00:00
Text animators: a later animator's Opacity can show characters an earlier one hid
Animator Opacity stacked by multiplying, so once one animator set 0 % no animator below it could raise it again. Each animator now blends the opacity left by the ones above it toward its own value. A single Opacity animator gives the same result as before. Fixes #2838.
This commit is contained in:
1 parent
9d7baea5cc
commit
0af6d2aab8
2 files changed
+20
-1
No files matched your search
@@ -343,7 +343,10 @@ pub fn char_transforms(ctx: &EvalCtx, layer: &Layer, text: &PropGroup, lay: &Tex
|
||||
}
|
||||
angles.apply(c, k);
|
||||
if let Some(o) = op {
|
||||
c.opacity *= 1.0 + (o / 100.0 - 1.0) * k;
|
||||
// Blend toward this animator's value, so a later animator can show characters an
|
||||
// earlier one hid (Lottie files rely on it: Opacity 0 % on every character, then
|
||||
// animators at 100 % that sweep in). With one animator this is the same as before.
|
||||
c.opacity += (o - c.opacity) * k;
|
||||
}
|
||||
if let Some(f) = fill {
|
||||
c.fill = Some(f);
|
||||
|
||||
@@ -548,6 +548,22 @@ fn keyframed_selector_animates() {
|
||||
assert_eq!(selection(&p, cid, 1.0, 1), vec![0.0; 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_later_animator_opacity_shows_characters_an_earlier_one_hid() {
|
||||
let (mut p, cid, comp) = setup(400, 200);
|
||||
let mut l = text_layer(&mut p, &comp, doc("ABCD", 40.0));
|
||||
animator(&mut p, &mut l, &["opacity"], &["range"]);
|
||||
set(&mut l, "text/animators/#1/properties/opacity", Value::Scalar(0.0));
|
||||
animator(&mut p, &mut l, &["opacity"], &["range"]);
|
||||
set(&mut l, "text/animators/#2/properties/opacity", Value::Scalar(60.0));
|
||||
set(&mut l, "text/animators/#2/selectors/#1/end", Value::Scalar(50.0));
|
||||
p.comp_mut(cid).unwrap().layers.push(l);
|
||||
let glyphs = glyph_paths(&ctx(&p, cid, 0.0), &p.comp(cid).unwrap().layers[0]);
|
||||
let opacity: Vec<f64> = glyphs.iter().map(|g| (g.1.opacity * 1000.0).round() / 1000.0).collect();
|
||||
// The second animator selects "AB" only: they come back at 60 %, "CD" stay hidden.
|
||||
assert_eq!(opacity, [60.0, 60.0, 0.0, 0.0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn caret_follows_animators_and_path_text() {
|
||||
let (mut p, cid, comp) = setup(400, 400);
|
||||
|
||||
Reference in new issue
Block a user