Skip to main content

animate_core/tween/
mod.rs

1mod alternate;
2mod cycle;
3mod once;
4
5pub mod easing;
6
7use crate::{Animate, Mode, Once};
8use std::marker::PhantomData;
9
10#[derive(Debug)]
11pub struct Tween<T, E, I, M = Once>
12where
13    M: Mode,
14    T: TweenAnim + PartialEq,
15    E: Fn(f64) -> f64,
16    I: Fn(&T, &T, f64) -> T,
17{
18    pub(crate) state: TweenState<T, E, I>,
19    _mode: PhantomData<M>,
20}
21
22impl<T, E, I, M> Tween<T, E, I, M>
23where
24    M: Mode,
25    T: TweenAnim + PartialEq + Default,
26    E: Fn(f64) -> f64,
27    I: Fn(&T, &T, f64) -> T,
28{
29    pub fn new(initial: T, duration: f64, easing: E, interp: I) -> Self {
30        Self {
31            state: TweenState::new(initial, duration, easing, interp),
32            _mode: PhantomData,
33        }
34    }
35}
36
37
38pub trait TweenAnim {
39    fn tween(start: &Self, end: &Self, t: f64) -> Self;
40}
41
42#[derive(Debug)]
43pub(crate) struct TweenState<T, E, I>
44where
45    E: Fn(f64) -> f64,
46    I: Fn(&T, &T, f64) -> T,
47{
48    pub current: T,
49    pub start: T,
50    pub target: T,
51    pub started_at: Option<usize>,
52    pub pending: bool,
53    pub duration: f64,
54    pub easing: E,
55    pub interp: I,
56}
57
58impl<T: Default, E, I> TweenState<T, E, I>
59where
60    E: Fn(f64) -> f64,
61    I: Fn(&T, &T, f64) -> T,
62{
63    pub fn new(initial: T, duration: f64, easing: E, interp: I) -> Self {
64        Self {
65            current: initial,
66            start: Default::default(),
67            target: Default::default(),
68            started_at: None,
69            pending: false,
70            duration: duration.max(f64::MIN_POSITIVE),
71            easing,
72            interp,
73        }
74    }
75}
76
77impl<T, E, I, M> std::ops::Deref for Tween<T, E, I, M>
78where
79    M: Mode,
80    T: TweenAnim + PartialEq + Default,
81    E: Fn(f64) -> f64,
82    I: Fn(&T, &T, f64) -> T,
83    Self: Animate<Value = T>,
84{
85    type Target = T;
86    fn deref(&self) -> &T {
87        Animate::get(self)
88    }
89}
90
91impl<T, E, I, M> std::fmt::Display for Tween<T, E, I, M>
92where
93    M: Mode,
94    T: TweenAnim + PartialEq + Default + std::fmt::Display,
95    E: Fn(f64) -> f64,
96    I: Fn(&T, &T, f64) -> T,
97    Self: Animate<Value = T>,
98{
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        Animate::get(self).fmt(f)
101    }
102}
103
104impl<T, E, I, M> std::ops::AddAssign<T> for Tween<T, E, I, M>
105where
106    M: Mode,
107    T: TweenAnim + PartialEq + Default,
108    E: Fn(f64) -> f64,
109    I: Fn(&T, &T, f64) -> T,
110    for<'b> &'b T: std::ops::Add<T, Output = T>,
111    Self: Animate<Value = T>,
112{
113    fn add_assign(&mut self, rhs: T) {
114        let v = Animate::target(self) + rhs;
115        Animate::set(self, v);
116    }
117}
118
119impl<T, E, I, M> std::ops::SubAssign<T> for Tween<T, E, I, M>
120where
121    M: Mode,
122    T: TweenAnim + PartialEq + Default,
123    E: Fn(f64) -> f64,
124    I: Fn(&T, &T, f64) -> T,
125    for<'b> &'b T: std::ops::Sub<T, Output = T>,
126    Self: Animate<Value = T>,
127{
128    fn sub_assign(&mut self, rhs: T) {
129        let v = Animate::target(self) - rhs;
130        Animate::set(self, v);
131    }
132}
133
134impl<T, E, I, M> std::ops::MulAssign<T> for Tween<T, E, I, M>
135where
136    M: Mode,
137    T: TweenAnim + PartialEq + Default,
138    E: Fn(f64) -> f64,
139    I: Fn(&T, &T, f64) -> T,
140    for<'b> &'b T: std::ops::Mul<T, Output = T>,
141    Self: Animate<Value = T>,
142{
143    fn mul_assign(&mut self, rhs: T) {
144        let v = Animate::target(self) * rhs;
145        Animate::set(self, v);
146    }
147}
148
149impl<T, E, I, M> std::ops::DivAssign<T> for Tween<T, E, I, M>
150where
151    M: Mode,
152    T: TweenAnim + PartialEq + Default,
153    E: Fn(f64) -> f64,
154    I: Fn(&T, &T, f64) -> T,
155    for<'b> &'b T: std::ops::Div<T, Output = T>,
156    Self: Animate<Value = T>,
157{
158    fn div_assign(&mut self, rhs: T) {
159        let v = Animate::target(self) / rhs;
160        Animate::set(self, v);
161    }
162}