From dad5f1e2731dbdccb3044f136a81f18dfead9de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Wed, 22 Apr 2026 12:26:29 +0200 Subject: [PATCH] fix(progress_bar): sync determinate animation clock on target change This prevents the time delta from becoming very large when the widget hasn't animated for a bit, leading to snapping instead of a smooth animation. Also prevents animating on widget creation, since it doesn't feel good in `cosmic-osd`. --- src/widget/progress_bar/animation.rs | 41 +++++++++++++++++----------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/widget/progress_bar/animation.rs b/src/widget/progress_bar/animation.rs index 6baf507..a9d5283 100644 --- a/src/widget/progress_bar/animation.rs +++ b/src/widget/progress_bar/animation.rs @@ -4,29 +4,38 @@ use std::time::Duration; const LAG: f32 = 0.1; +#[derive(Default)] pub struct Progress { pub current: f32, - last: Instant, -} - -impl Default for Progress { - fn default() -> Self { - Self { - current: 0.0, - last: Instant::now(), - } - } + target: Option, + last: Option, } impl Progress { /// Smoothly chases `target` using exponential decay. - /// Returns `true` if still animating and a redraw should be requested. + /// Returns `true` if a redraw should be requested. pub fn update(&mut self, target: f32, now: Instant) -> bool { - let dt = (now - self.last).as_secs_f32(); - self.last = now; - let next = self.current + (target - self.current) * (1.0 - (-dt / LAG).exp()); - if (next - target).abs() > 0.001 { - self.current = next; + // Don't animate on start + let Some(last) = self.last else { + self.current = target; + self.target = Some(target); + self.last = Some(now); + return false; + }; + + // Sync animation clock when target changes + if self.target != Some(target) { + self.target = Some(target); + self.last = Some(now); + return true; + } + + let dt = (now - last).as_secs_f32(); + self.last = Some(now); + let diff = target - self.current; + + if diff.abs() > 0.001 { + self.current += diff * (1.0 - (-dt / LAG).exp()); true } else { self.current = target;