dioxus_motion/animations/
tween.rs1#[cfg(feature = "dioxus")]
7use dioxus::prelude::Store;
8use easer::functions::{Easing, Linear};
9pub use instant::Duration;
10
11#[cfg_attr(feature = "dioxus", derive(Store))]
22#[derive(Debug, Clone, Copy)]
23pub struct Tween {
24 pub duration: Duration,
26 pub easing: fn(f32, f32, f32, f32) -> f32,
28}
29
30impl PartialEq for Tween {
31 fn eq(&self, other: &Self) -> bool {
32 self.duration == other.duration && std::ptr::fn_addr_eq(self.easing, other.easing)
33 }
34}
35
36impl Default for Tween {
38 fn default() -> Self {
39 Self {
40 duration: Duration::from_millis(300),
41 easing: Linear::ease_in_out,
42 }
43 }
44}
45
46impl Tween {
47 pub fn new(duration: Duration) -> Self {
49 Self {
50 duration,
51 easing: Linear::ease_in_out,
52 }
53 }
54
55 pub fn with_easing(mut self, easing: fn(f32, f32, f32, f32) -> f32) -> Self {
60 self.easing = easing;
61 self
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use easer::functions::{Cubic, Easing};
69
70 #[test]
71 fn test_tween_new() {
72 let tween = Tween {
73 duration: Duration::from_secs(1),
74 easing: Cubic::ease_in_out,
75 };
76
77 assert_eq!(tween.duration, Duration::from_secs(1));
78 }
79
80 #[test]
81 fn test_tween_interpolation() {
82 let tween = Tween {
83 duration: Duration::from_secs(1),
84 easing: Linear::ease_in_out,
85 };
86
87 let progress = 0.5;
89 let result = (tween.easing)(progress, 0.0, 1.0, 1.0);
90 assert!((result - 0.5).abs() < f32::EPSILON);
91
92 let result = (tween.easing)(0.0, 0.0, 1.0, 1.0);
94 assert!((result - 0.0).abs() < f32::EPSILON);
95
96 let result = (tween.easing)(1.0, 0.0, 1.0, 1.0);
98 assert!((result - 1.0).abs() < f32::EPSILON);
99 }
100
101 #[test]
102 fn test_tween_partial_eq_uses_function_identity() {
103 let base = Tween::new(Duration::from_secs(1));
104
105 assert_eq!(base, Tween::new(Duration::from_secs(1)));
106 assert_ne!(base, Tween::new(Duration::from_secs(2)));
107 assert_ne!(base, base.with_easing(Cubic::ease_in_out));
108 }
109}