use crate::utils::easing::Easing;
pub trait Interpolatable: Clone {
fn lerp(&self, other: &Self, t: f64) -> Self;
}
impl Interpolatable for f32 {
fn lerp(&self, other: &Self, t: f64) -> Self {
*self + (*other - *self) * t as f32
}
}
impl Interpolatable for f64 {
fn lerp(&self, other: &Self, t: f64) -> Self {
*self + (*other - *self) * t
}
}
impl Interpolatable for i32 {
fn lerp(&self, other: &Self, t: f64) -> Self {
(*self as f64 + (*other - *self) as f64 * t).round() as i32
}
}
impl Interpolatable for u8 {
fn lerp(&self, other: &Self, t: f64) -> Self {
(*self as f64 + (*other as f64 - *self as f64) * t).round() as u8
}
}
impl Interpolatable for u16 {
fn lerp(&self, other: &Self, t: f64) -> Self {
(*self as f64 + (*other as f64 - *self as f64) * t).round() as u16
}
}
impl Interpolatable for (f64, f64) {
fn lerp(&self, other: &Self, t: f64) -> Self {
(self.0.lerp(&other.0, t), self.1.lerp(&other.1, t))
}
}
impl Interpolatable for (f64, f64, f64) {
fn lerp(&self, other: &Self, t: f64) -> Self {
(
self.0.lerp(&other.0, t),
self.1.lerp(&other.1, t),
self.2.lerp(&other.2, t),
)
}
}
#[derive(Clone, Debug)]
pub struct Keyframe<T: Interpolatable> {
pub time: f64,
pub value: T,
pub easing: Easing,
}
impl<T: Interpolatable> Keyframe<T> {
pub fn new(time: f64, value: T) -> Self {
Self {
time: time.clamp(0.0, 1.0),
value,
easing: Easing::Linear,
}
}
pub fn easing(mut self, easing: Easing) -> Self {
self.easing = easing;
self
}
}
#[derive(Clone)]
pub struct SequenceStep {
pub duration: std::time::Duration,
pub easing: Easing,
pub target: f64,
}
impl SequenceStep {
pub fn new(duration: std::time::Duration, target: f64) -> Self {
Self {
duration,
easing: Easing::Linear,
target: target.clamp(0.0, 1.0),
}
}
pub fn easing(mut self, easing: Easing) -> Self {
self.easing = easing;
self
}
}