fix(progress_bar): prevent large animation time delta
This commit is contained in:
parent
18a7a75e33
commit
18d76659f2
1 changed files with 9 additions and 17 deletions
|
|
@ -2,44 +2,36 @@ use crate::anim::smootherstep;
|
||||||
use iced::time::Instant;
|
use iced::time::Instant;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// Angular frequency of the critically damped spring (snappiness)
|
const LAG: f32 = 0.1;
|
||||||
const OMEGA: f32 = 15.0;
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Progress {
|
pub struct Progress {
|
||||||
pub current: f32,
|
pub current: f32,
|
||||||
velocity: f32,
|
|
||||||
last: Option<Instant>,
|
last: Option<Instant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Progress {
|
impl Progress {
|
||||||
/// Chases `target` using a critically damped spring.
|
/// Chases `target` using exponential decay.
|
||||||
/// Returns `true` if a redraw should be requested.
|
/// Returns `true` if a redraw should be requested.
|
||||||
pub fn update(&mut self, target: f32, now: Instant) -> bool {
|
pub fn update(&mut self, target: f32, now: Instant) -> bool {
|
||||||
// Don't animate on start
|
// Don't animate on start
|
||||||
let Some(last) = self.last else {
|
let Some(last) = self.last else {
|
||||||
self.current = target;
|
self.current = target;
|
||||||
self.velocity = 0.0;
|
|
||||||
self.last = Some(now);
|
self.last = Some(now);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let dt = (now - last).as_secs_f32();
|
let dt = (now - last).as_secs_f32().min(1.0 / 60.0);
|
||||||
self.last = Some(now);
|
self.last = Some(now);
|
||||||
let displacement = self.current - target;
|
let diff = target - self.current;
|
||||||
|
|
||||||
if displacement.abs() < 0.001 && self.velocity.abs() < 0.001 {
|
|
||||||
self.current = target;
|
|
||||||
self.velocity = 0.0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let exp = (-OMEGA * dt).exp();
|
|
||||||
let coeff = self.velocity + OMEGA * displacement;
|
|
||||||
self.current = target + (displacement + coeff * dt) * exp;
|
|
||||||
self.velocity = (self.velocity - OMEGA * coeff * dt) * exp;
|
|
||||||
|
|
||||||
|
if diff.abs() > 0.001 {
|
||||||
|
self.current += diff * (1.0 - (-dt / LAG).exp());
|
||||||
true
|
true
|
||||||
|
} else {
|
||||||
|
self.current = target;
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue