1use crate::{
4 field::{Fields, FieldsAnimation},
5 interpolate::InterpolationProgress,
6 timeline::{Hold, Sequence},
7 timing::Duration,
8};
9
10pub trait Interpolate: Sized {
12 #[must_use]
14 fn lerp(&self, other: &Self, progress: f32) -> Self {
15 Self::interpolate_progress(self, other, InterpolationProgress::new(progress))
16 }
17
18 #[must_use]
20 fn interpolate(from: &Self, to: &Self, progress: f32) -> Self {
21 Self::interpolate_progress(from, to, InterpolationProgress::new(progress))
22 }
23
24 #[must_use]
26 fn extrapolate(from: &Self, to: &Self, progress: f32) -> Self {
27 Self::interpolate_progress(from, to, InterpolationProgress::extrapolated(progress))
28 }
29
30 #[must_use]
32 fn interpolate_progress(from: &Self, to: &Self, progress: InterpolationProgress) -> Self;
33}
34
35pub trait Animatable: Interpolate + Clone + 'static {}
37
38impl<T: Interpolate + Clone + 'static> Animatable for T {}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum AnimationState {
43 Idle,
45 Running,
47 Paused,
49 Completed,
51 Canceled,
53}
54
55pub trait Animation<T: Animatable>: 'static {
57 #[must_use]
59 fn value(&self) -> &T;
60
61 #[must_use]
63 fn state(&self) -> AnimationState;
64
65 #[must_use]
67 fn duration(&self) -> Option<Duration> {
68 None
69 }
70
71 fn tick(&mut self, delta: Duration);
73
74 fn advance(&mut self, delta: Duration) -> Duration {
76 self.tick(delta);
77 Duration::ZERO
78 }
79
80 fn pause(&mut self);
82
83 fn resume(&mut self);
85
86 fn cancel(&mut self);
88
89 fn seek(&mut self, progress: f32);
91
92 fn finish(&mut self);
94
95 #[must_use]
99 fn retarget(&mut self, _target: &T) -> bool {
100 false
101 }
102
103 #[must_use]
105 fn is_active(&self) -> bool {
106 self.state() == AnimationState::Running
107 }
108
109 fn set_rate(&mut self, _rate: f64) {}
114
115 #[must_use]
121 fn rate(mut self, rate: f64) -> Self
122 where
123 Self: Sized,
124 {
125 self.set_rate(rate);
126 self
127 }
128
129 #[must_use]
135 fn into_value(self: Box<Self>) -> T {
136 self.value().clone()
137 }
138}
139
140pub type BoxAnimation<T> = Box<dyn Animation<T>>;
142
143pub trait AnimationExt<T: Animatable>: Animation<T> + Sized {
145 #[must_use]
147 fn boxed(self) -> BoxAnimation<T> {
148 Box::new(self)
149 }
150
151 #[must_use]
153 fn then(self, next: impl Animation<T>) -> Sequence<T> {
154 let initial = self.value().clone();
155 Sequence::new(initial).then(self).then(next)
156 }
157
158 #[must_use]
160 fn delay(self, duration: impl Into<Duration>) -> Sequence<T> {
161 let initial = self.value().clone();
162 Sequence::new(initial.clone())
163 .then(Hold::new(initial, duration))
164 .then(self)
165 }
166}
167
168impl<T: Animatable, A: Animation<T> + Sized> AnimationExt<T> for A {}
169
170#[doc(hidden)]
172pub enum DirectAnimation {}
173
174#[doc(hidden)]
176pub enum FieldAnimationPlan {}
177
178#[doc(hidden)]
180pub enum AnimationFactory {}
181
182mod private {
183 use super::{Animatable, Animation, AnimationFactory, DirectAnimation, FieldAnimationPlan};
184 use crate::Fields;
185
186 pub trait Sealed<T: Animatable, Kind> {}
187
188 impl<T, A> Sealed<T, DirectAnimation> for A
189 where
190 T: Animatable,
191 A: Animation<T>,
192 {
193 }
194
195 impl<T: Animatable> Sealed<T, FieldAnimationPlan> for Fields<T> {}
196
197 impl<T, A, F> Sealed<T, AnimationFactory> for F
198 where
199 T: Animatable,
200 A: Animation<T>,
201 F: FnOnce(T) -> A,
202 {
203 }
204}
205
206pub trait IntoMotionAnimation<T: Animatable, Kind>: private::Sealed<T, Kind> {
213 type Animation: Animation<T>;
215
216 #[doc(hidden)]
218 fn into_motion_animation(self, current: &T) -> Self::Animation;
219}
220
221impl<T, A> IntoMotionAnimation<T, DirectAnimation> for A
222where
223 T: Animatable,
224 A: Animation<T>,
225{
226 type Animation = A;
227
228 fn into_motion_animation(self, _current: &T) -> Self::Animation {
229 self
230 }
231}
232
233impl<T: Animatable> IntoMotionAnimation<T, FieldAnimationPlan> for Fields<T> {
234 type Animation = FieldsAnimation<T>;
235
236 fn into_motion_animation(self, current: &T) -> Self::Animation {
237 self.build(current)
238 }
239}
240
241impl<T, A, F> IntoMotionAnimation<T, AnimationFactory> for F
242where
243 T: Animatable,
244 A: Animation<T>,
245 F: FnOnce(T) -> A,
246{
247 type Animation = A;
248
249 fn into_motion_animation(self, current: &T) -> Self::Animation {
250 self(current.clone())
251 }
252}
253
254impl<Source: ?Sized, T: Animatable> Animation<T> for Box<Source>
255where
256 Source: Animation<T>,
257{
258 fn value(&self) -> &T {
259 (**self).value()
260 }
261
262 fn state(&self) -> AnimationState {
263 (**self).state()
264 }
265
266 fn duration(&self) -> Option<Duration> {
267 (**self).duration()
268 }
269
270 fn tick(&mut self, delta: Duration) {
271 (**self).tick(delta);
272 }
273
274 fn advance(&mut self, delta: Duration) -> Duration {
275 (**self).advance(delta)
276 }
277
278 fn pause(&mut self) {
279 (**self).pause();
280 }
281
282 fn resume(&mut self) {
283 (**self).resume();
284 }
285
286 fn cancel(&mut self) {
287 (**self).cancel();
288 }
289
290 fn seek(&mut self, progress: f32) {
291 (**self).seek(progress);
292 }
293
294 fn finish(&mut self) {
295 (**self).finish();
296 }
297
298 fn retarget(&mut self, target: &T) -> bool {
299 (**self).retarget(target)
300 }
301
302 fn is_active(&self) -> bool {
303 (**self).is_active()
304 }
305
306 fn set_rate(&mut self, rate: f64) {
307 (**self).set_rate(rate);
308 }
309
310 fn into_value(self: Box<Self>) -> T {
311 (*self).into_value()
312 }
313}