1
0
Fork 0
forked from wry/wry

Use configured curve for spawn animations

This commit is contained in:
atagen 2026-05-24 14:40:22 +10:00
parent b211b53528
commit dfcb2d0fd6
2 changed files with 21 additions and 6 deletions

View file

@ -391,6 +391,7 @@ impl AnimationState {
retained: Option<Rc<RetainedToplevel>>,
now_nsec: u64,
duration_ms: u32,
curve: AnimationCurve,
) -> bool {
let start = spawn_in_start_rect(target);
self.set_target(
@ -400,7 +401,7 @@ impl AnimationState {
retained,
now_nsec,
duration_ms,
AnimationCurve::Linear,
curve,
)
}
@ -413,6 +414,7 @@ impl AnimationState {
layer: RetainedExitLayer,
now_nsec: u64,
duration_ms: u32,
curve: AnimationCurve,
) -> bool {
if from.is_empty() || duration_ms == 0 {
return false;
@ -430,6 +432,7 @@ impl AnimationState {
to,
start_nsec: now_nsec,
duration_nsec: duration_ms as u64 * 1_000_000,
curve,
last_damage: from,
retained,
frame_inset,
@ -681,6 +684,7 @@ struct ExitAnimation {
to: Rect,
start_nsec: u64,
duration_nsec: u64,
curve: AnimationCurve,
last_damage: Rect,
retained: Rc<RetainedToplevel>,
frame_inset: i32,
@ -700,6 +704,7 @@ impl ExitAnimation {
}
let elapsed = now_nsec.saturating_sub(self.start_nsec);
let t = (elapsed as f64 / self.duration_nsec as f64).clamp(0.0, 1.0);
let t = self.curve.sample(t);
lerp_rect(self.from, self.to, t)
}
}
@ -872,11 +877,12 @@ mod tests {
}
#[test]
fn spawn_out_frames_shrink_linearly_and_expire() {
fn spawn_out_frames_use_configured_curve_and_expire() {
let state = AnimationState::default();
let retained = retained_for_tests();
let from = Rect::new_sized_saturating(10, 20, 100, 80);
let to = spawn_in_start_rect(from);
let curve = AnimationCurve::from_config(3);
assert!(state.set_spawn_out(
from,
2,
@ -884,7 +890,8 @@ mod tests {
true,
RetainedExitLayer::Floating,
0,
160
160,
curve
));
let start = state.exit_frames(0);
@ -897,7 +904,8 @@ mod tests {
let middle = state.exit_frames(80_000_000);
assert_eq!(middle.len(), 1);
assert_eq!(middle[0].rect, lerp_rect(from, to, 0.5));
assert_eq!(middle[0].rect, lerp_rect(from, to, curve.sample(0.5)));
assert_ne!(middle[0].rect, lerp_rect(from, to, 0.5));
assert!(state.exit_frames(160_000_000).is_empty());
}
@ -1034,12 +1042,17 @@ mod tests {
}
#[test]
fn spawn_in_uses_linear_curve() {
fn spawn_in_uses_configured_curve() {
let state = AnimationState::default();
let id = NodeId(1);
let target = Rect::new_sized_saturating(10, 20, 100, 50);
assert!(state.set_spawn_in(id, target, None, 0, 160));
let curve = AnimationCurve::from_config(3);
assert!(state.set_spawn_in(id, target, None, 0, 160, curve));
assert_eq!(
state.visual_rect(id, target, 80_000_000),
lerp_rect(spawn_in_start_rect(target), target, curve.sample(0.5))
);
assert_ne!(
state.visual_rect(id, target, 80_000_000),
Rect::new_sized_saturating(35, 33, 50, 25)
);

View file

@ -1812,6 +1812,7 @@ impl State {
retained,
now,
self.animations.duration_ms.get(),
self.animations.curve.get(),
);
if started {
self.damage(expand_damage_rect(
@ -1842,6 +1843,7 @@ impl State {
layer,
now,
self.animations.duration_ms.get(),
self.animations.curve.get(),
);
if started {
self.damage(expand_damage_rect(