From ec9b708a95335aed6f40494c2b7800743b94f5ee Mon Sep 17 00:00:00 2001 From: cui fliter Date: Thu, 3 Sep 2026 19:48:23 +0800 Subject: [PATCH] Fix zero-duration value animations returning the previous value (#8469) animate_value_with_time returned the previous value for one frame when called with a zero duration because it calculated the current value before updating the animation target. Handle zero-duration animations before interpolation so they immediately return and store the target value. Add a regression test covering consecutive target changes. * Closes * [x] I have followed the instructions in the PR template Signed-off-by: cuishuang Co-authored-by: Emil Ernerfeldt --- crates/egui/src/animation_manager.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/crates/egui/src/animation_manager.rs b/crates/egui/src/animation_manager.rs index 4dc21df09..211873bd7 100644 --- a/crates/egui/src/animation_manager.rs +++ b/crates/egui/src/animation_manager.rs @@ -85,6 +85,13 @@ impl AnimationManager { value } Some(anim) => { + if animation_time == 0.0 { + anim.from_value = value; + anim.to_value = value; + anim.toggle_time = input.time; + return value; + } + let time_since_toggle = (input.time - anim.toggle_time) as f32; // On the frame we toggle we don't want to return the old value, // so we extrapolate forwards by half a frame: @@ -99,12 +106,25 @@ impl AnimationManager { anim.to_value = value; anim.toggle_time = input.time; } - if animation_time == 0.0 { - anim.from_value = value; - anim.to_value = value; - } current_value } } } } + +#[cfg(test)] +mod tests { + use super::AnimationManager; + use crate::{Id, InputState}; + + #[test] + fn zero_duration_value_animation_reaches_target_immediately() { + let mut animations = AnimationManager::default(); + let input = InputState::default(); + let id = Id::new("value_animation"); + + assert_eq!(animations.animate_value(&input, 0.0, id, 0.0), 0.0); + assert_eq!(animations.animate_value(&input, 0.0, id, 1.0), 1.0); + assert_eq!(animations.animate_value(&input, 0.0, id, 2.0), 2.0); + } +}