aura_anim_core/traits.rs
1//! Core traits implemented by animatable values and animation sources.
2
3use crate::{interpolate::InterpolationProgress, timing::Duration};
4
5/// Interpolates values of the same type.
6pub trait Interpolate: Sized {
7 /// Interpolates from `self` to `other` using normalized progress.
8 #[must_use]
9 fn lerp(&self, other: &Self, progress: f32) -> Self {
10 Self::interpolate_progress(self, other, InterpolationProgress::new(progress))
11 }
12
13 /// Interpolates from `from` to `to` using normalized progress.
14 #[must_use]
15 fn interpolate(from: &Self, to: &Self, progress: f32) -> Self {
16 Self::interpolate_progress(from, to, InterpolationProgress::new(progress))
17 }
18
19 /// Interpolates or extrapolates from `from` to `to` without clamping finite progress.
20 #[must_use]
21 fn extrapolate(from: &Self, to: &Self, progress: f32) -> Self {
22 Self::interpolate_progress(from, to, InterpolationProgress::extrapolated(progress))
23 }
24
25 /// Interpolates from `from` to `to` using a prepared progress value.
26 #[must_use]
27 fn interpolate_progress(from: &Self, to: &Self, progress: InterpolationProgress) -> Self;
28}
29
30/// Marker trait for cloneable, owned values that can be animated.
31pub trait Animatable: Interpolate + Clone + 'static {}
32
33impl<T: Interpolate + Clone + 'static> Animatable for T {}
34
35/// Lifecycle state of an animation.
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum AnimationState {
38 /// The animation has not started.
39 Idle,
40 /// The animation is advancing.
41 Running,
42 /// The animation is suspended and retains its current value.
43 Paused,
44 /// The animation reached its final value.
45 Completed,
46 /// The animation was canceled before completion.
47 Canceled,
48}
49
50/// A stateful source that produces animated values over time.
51pub trait Animation<T: Animatable>: 'static {
52 /// Returns the animation's current value.
53 #[must_use]
54 fn value(&self) -> &T;
55
56 /// Returns the animation's lifecycle state.
57 #[must_use]
58 fn state(&self) -> AnimationState;
59
60 /// Returns the total duration when it is finite and known.
61 #[must_use]
62 fn duration(&self) -> Option<Duration> {
63 None
64 }
65
66 /// Advances the animation by `delta`.
67 fn tick(&mut self, delta: Duration);
68
69 /// Advances the animation and returns any unconsumed duration.
70 fn advance(&mut self, delta: Duration) -> Duration {
71 self.tick(delta);
72 Duration::ZERO
73 }
74
75 /// Pauses a running animation.
76 fn pause(&mut self);
77
78 /// Resumes a paused animation.
79 fn resume(&mut self);
80
81 /// Cancels the animation.
82 fn cancel(&mut self);
83
84 /// Seeks to normalized progress within the animation.
85 fn seek(&mut self, progress: f32);
86
87 /// Moves the animation to its completed state.
88 fn finish(&mut self);
89
90 /// Attempts to continue the animation toward a new target.
91 ///
92 /// Returns `true` when the animation supports retargeting.
93 #[must_use]
94 fn retarget(&mut self, _target: &T) -> bool {
95 false
96 }
97
98 /// Returns whether the animation is currently running.
99 #[must_use]
100 fn is_active(&self) -> bool {
101 self.state() == AnimationState::Running
102 }
103}