use std::ops::{Add, Sub, Mul};
use std::time::{Duration, Instant};
use crate::functions::EasingFn;
pub struct Interpolated<T> {
start: T,
end: T,
start_time: Instant,
pub speed: f32,
pub transition: EasingFn,
}
impl<T> Interpolated<T>
where
T: Copy + Add<Output = T> + Sub<Output = T> + Mul<f32, Output = T>,
{
pub fn new(initial: T) -> Self {
let now = Instant::now();
Interpolated {
start: initial,
end: initial,
start_time: now,
speed: 1.0,
transition: crate::functions::linear,
}
}
pub fn set_duration(&mut self, d: Duration) {
self.speed = 1.0 / d.as_secs_f32();
}
pub fn set(&mut self, new_end: T) {
self.start = self.value();
self.end = new_end;
self.start_time = Instant::now();
}
pub fn value(&self) -> T {
let t = (Instant::now() - self.start_time).as_secs_f32() * self.speed;
if t >= 1.0 {
return self.end;
}
let r = (self.transition)(t.clamp(0.0, 1.0));
self.start + (self.end - self.start) * r
}
pub fn is_finished(&self) -> bool {
(Instant::now() - self.start_time).as_secs_f32() * self.speed >= 1.0
}
}