1#[derive(Clone, Copy, Default)]
3pub enum Easing {
4 #[default]
5 Linear,
6 EaseIn,
7 EaseOut,
8 EaseInOut,
9}
10
11impl Easing {
12 fn apply(&self, t: f32) -> f32 {
13 match self {
14 Easing::Linear => t,
15 Easing::EaseIn => t * t,
16 Easing::EaseOut => 1.0 - (1.0 - t) * (1.0 - t),
17 Easing::EaseInOut => {
18 if t < 0.5 {
19 2.0 * t * t
20 } else {
21 1.0 - (-2.0 * t + 2.0).powi(2) / 2.0
22 }
23 }
24 }
25 }
26}
27
28pub struct Tween {
30 current: f32,
31 target: f32,
32 speed: f32,
34 easing: Easing,
35 progress: f32,
37 start_value: f32,
38}
39
40impl Tween {
41 pub fn new(initial: f32, speed: f32) -> Self {
42 Self {
43 current: initial,
44 target: initial,
45 speed,
46 easing: Easing::Linear,
47 progress: 1.0,
48 start_value: initial,
49 }
50 }
51
52 pub fn with_easing(mut self, easing: Easing) -> Self {
53 self.easing = easing;
54 self
55 }
56
57 pub fn set_target(&mut self, target: f32) {
59 if (target - self.target).abs() > f32::EPSILON {
60 self.target = target;
61 self.start_value = self.current;
62 self.progress = 0.0;
63 }
64 }
65
66 pub fn update(&mut self) {
68 if self.progress >= 1.0 {
69 self.current = self.target;
70 return;
71 }
72
73 self.progress = (self.progress + self.speed).min(1.0);
74 let eased = self.easing.apply(self.progress);
75 self.current = self.start_value + (self.target - self.start_value) * eased;
76 }
77
78 pub fn value(&self) -> f32 {
80 self.current
81 }
82
83 pub fn done(&self) -> bool {
85 self.progress >= 1.0
86 }
87
88 pub fn snap(&mut self) {
90 self.current = self.target;
91 self.progress = 1.0;
92 }
93}