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 From<AnimNum> for f32 {
78    fn from(value: AnimNum) -> Self {
79        value.value()
80    }
81}
82
83impl AnimatedValue for AnimNum {
84    fn prepare(&mut self, direction: AnimDirection) {
85        match direction {
86            AnimDirection::Forward => self.value = self.origin,
87            AnimDirection::Reverse => {
88                self.value = self.destination;
89            }
90        }
91    }
92
93    fn is_finished(&self, index: u128, direction: AnimDirection) -> bool {
94        match direction {
95            AnimDirection::Forward => {
96                index >= self.time.as_millis() && self.value == self.destination
97            }
98            AnimDirection::Reverse => index >= self.time.as_millis() && self.value == self.origin,
99        }
100    }
101
102    fn advance(&mut self, index: u128, direction: AnimDirection) {
103        let (origin, destination) = match direction {
104            AnimDirection::Forward => (self.origin, self.destination),
105            AnimDirection::Reverse => (self.destination, self.origin),
106        };
107        self.value = apply_value(
108            origin,
109            destination,
110            index.min(self.time.as_millis()),
111            self.time,
112            self.ease,
113            self.function,
114        );
115    }
116
117    fn finish(&mut self, direction: AnimDirection) {
118        self.advance(self.time.as_millis(), direction);
119    }
120
121    /// Reverses the `origin` and the `destination` of the [AnimNum].
122    fn into_reversed(self) -> AnimNum {
123        Self {
124            origin: self.destination,
125            destination: self.origin,
126            ..self
127        }
128    }
129}
130
131impl ReadAnimatedValue for AnimNum {
132    type Output = f32;
133    fn value(&self) -> Self::Output {
134        self.value()
135    }
136}