freya_animation/
anim_num.rs

1use std::time::Duration;
2
3use crate::{
4    easing::{
5        Function,
6        apply_value,
7    },
8    hook::{
9        AnimDirection,
10        AnimatedValue,
11        Ease,
12        ReadAnimatedValue,
13    },
14};
15
16/// Animate a numeric value.
17#[derive(Clone, PartialEq, Default)]
18pub struct AnimNum {
19    origin: f32,
20    destination: f32,
21    time: Duration,
22    ease: Ease,
23    function: Function,
24
25    value: f32,
26}
27
28impl AnimNum {
29    pub fn new(origin: f32, destination: f32) -> Self {
30        Self {
31            origin,
32            destination,
33            time: Duration::default(),
34            ease: Ease::default(),
35            function: Function::default(),
36
37            value: origin,
38        }
39    }
40
41    /// Set the animation duration using milliseconds. Use `Self::duration` if you want to specify the duration in another form.
42    pub fn time(mut self, time: u64) -> Self {
43        self.time = Duration::from_millis(time);
44        self
45    }
46
47    /// Set the animation duration using milliseconds.
48    pub fn duration(mut self, duration: Duration) -> Self {
49        self.time = duration;
50        self
51    }
52
53    /// Set the easing type. See `Ease` for all the types.
54    pub fn ease(mut self, ease: Ease) -> Self {
55        self.ease = ease;
56        self
57    }
58
59    /// Set the easing function. See `Function` for all the types.
60    pub fn function(mut self, function: Function) -> Self {
61        self.function = function;
62        self
63    }
64
65    /// Read the value of the [AnimNum] as a f32.
66    pub fn value(&self) -> f32 {
67        self.value
68    }
69}
70
71impl From<&AnimNum> for f32 {
72    fn from(value: &AnimNum) -> Self {
73        value.value()
74    }
75}
76
77impl AnimatedValue for AnimNum {
78    fn prepare(&mut self, direction: AnimDirection) {
79        match direction {
80            AnimDirection::Forward => self.value = self.origin,
81            AnimDirection::Reverse => {
82                self.value = self.destination;
83            }
84        }
85    }
86
87    fn is_finished(&self, index: u128, direction: AnimDirection) -> bool {
88        match direction {
89            AnimDirection::Forward => {
90                index >= self.time.as_millis() && self.value == self.destination
91            }
92            AnimDirection::Reverse => index >= self.time.as_millis() && self.value == self.origin,
93        }
94    }
95
96    fn advance(&mut self, index: u128, direction: AnimDirection) {
97        let (origin, destination) = match direction {
98            AnimDirection::Forward => (self.origin, self.destination),
99            AnimDirection::Reverse => (self.destination, self.origin),
100        };
101        self.value = apply_value(
102            origin,
103            destination,
104            index.min(self.time.as_millis()),
105            self.time,
106            self.ease,
107            self.function,
108        );
109    }
110
111    fn finish(&mut self, direction: AnimDirection) {
112        self.advance(self.time.as_millis(), direction);
113    }
114
115    /// Reverses the `origin` and the `destination` of the [AnimNum].
116    fn into_reversed(self) -> AnimNum {
117        Self {
118            origin: self.destination,
119            destination: self.origin,
120            ..self
121        }
122    }
123}
124
125impl ReadAnimatedValue for AnimNum {
126    type Output = f32;
127    fn value(&self) -> Self::Output {
128        self.value()
129    }
130}