#[cfg(feature = "dioxus")]
use dioxus::prelude::Store;
use easer::functions::{Easing, Linear};
pub use instant::Duration;
#[cfg_attr(feature = "dioxus", derive(Store))]
#[derive(Debug, Clone, Copy)]
pub struct Tween {
pub duration: Duration,
pub easing: fn(f32, f32, f32, f32) -> f32,
}
impl PartialEq for Tween {
fn eq(&self, other: &Self) -> bool {
self.duration == other.duration && std::ptr::fn_addr_eq(self.easing, other.easing)
}
}
impl Default for Tween {
fn default() -> Self {
Self {
duration: Duration::from_millis(300),
easing: Linear::ease_in_out,
}
}
}
impl Tween {
pub fn new(duration: Duration) -> Self {
Self {
duration,
easing: Linear::ease_in_out,
}
}
pub fn with_easing(mut self, easing: fn(f32, f32, f32, f32) -> f32) -> Self {
self.easing = easing;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use easer::functions::{Cubic, Easing};
#[test]
fn test_tween_new() {
let tween = Tween {
duration: Duration::from_secs(1),
easing: Cubic::ease_in_out,
};
assert_eq!(tween.duration, Duration::from_secs(1));
}
#[test]
fn test_tween_interpolation() {
let tween = Tween {
duration: Duration::from_secs(1),
easing: Linear::ease_in_out,
};
let progress = 0.5;
let result = (tween.easing)(progress, 0.0, 1.0, 1.0);
assert!((result - 0.5).abs() < f32::EPSILON);
let result = (tween.easing)(0.0, 0.0, 1.0, 1.0);
assert!((result - 0.0).abs() < f32::EPSILON);
let result = (tween.easing)(1.0, 0.0, 1.0, 1.0);
assert!((result - 1.0).abs() < f32::EPSILON);
}
#[test]
fn test_tween_partial_eq_uses_function_identity() {
let base = Tween::new(Duration::from_secs(1));
assert_eq!(base, Tween::new(Duration::from_secs(1)));
assert_ne!(base, Tween::new(Duration::from_secs(2)));
assert_ne!(base, base.with_easing(Cubic::ease_in_out));
}
}