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}