rust_animation/
animation.rs

1use keyframe::{ease, functions::*};
2use std::time::Instant;
3use crate::actor::Actor;
4
5#[derive(Copy, Clone, Debug)]
6pub enum EasingFunction {
7  EaseIn,
8  EaseInCubic,
9  EaseInOut,
10  EaseInOutCubic,
11  EaseInOutQuad,
12  EaseInOutQuart,
13  EaseInOutQuint,
14  EaseInQuad,
15  EaseInQuart,
16  EaseInQuint,
17  EaseOut,
18  EaseOutCubic,
19  EaseOutQuad,
20  EaseOutQuart,
21  EaseOutQuint,
22  Linear,
23  Step,
24}
25
26pub struct Animation {
27  animation_time_instance: Instant,
28  translation_x_running: bool,
29  translation_x_starting_time: u128,
30  translation_x_time_duration: f32,
31  translation_x_from_value: i32,
32  translation_x_to_value: i32,
33  translation_x_ease: EasingFunction,
34
35  translation_y_running: bool,
36  translation_y_starting_time: u128,
37  translation_y_time_duration: f32,
38  translation_y_from_value: i32,
39  translation_y_to_value: i32,
40  translation_y_ease: EasingFunction,
41
42  scale_running: bool,
43  scale_starting_time: u128,
44  scale_time_duration: f32,
45  scale_from_value: f32,
46  scale_to_value: f32,
47  scale_ease: EasingFunction,
48
49  rotation_running: bool,
50  rotation_starting_time: u128,
51  rotation_time_duration: f32,
52  rotation_from_value: i32,
53  rotation_to_value: i32,
54  rotation_ease: EasingFunction,
55}
56
57
58impl Animation {
59  pub fn new() -> Animation {
60    Animation {
61      animation_time_instance: Instant::now(),
62      translation_x_running: false,
63      translation_x_starting_time: 0,
64      translation_x_time_duration: 0.0,
65      translation_x_from_value: 0,
66      translation_x_to_value: 0,
67      translation_x_ease: EasingFunction::Linear,
68
69      translation_y_running: false,
70      translation_y_starting_time: 0,
71      translation_y_time_duration: 0.0,
72      translation_y_from_value: 0,
73      translation_y_to_value: 0,
74      translation_y_ease: EasingFunction::Linear,
75
76      scale_running: false,
77      scale_starting_time: 0,
78      scale_time_duration: 0.0,
79      scale_from_value: 0.0,
80      scale_to_value: 0.0,
81      scale_ease: EasingFunction::Linear,
82
83      rotation_running: false,
84      rotation_starting_time: 0,
85      rotation_time_duration: 0.0,
86      rotation_from_value: 0,
87      rotation_to_value: 0,
88      rotation_ease: EasingFunction::Linear,
89    }
90  }
91
92  fn easing_function(easing: EasingFunction, from: f32, to: f32, duration: f32) -> f32 {
93    match easing {
94      EasingFunction::EaseIn => ease(EaseIn, from, to, duration),
95      EasingFunction::EaseInCubic => ease(EaseInCubic, from, to, duration),
96      EasingFunction::EaseInOut => ease(EaseInOut, from, to, duration),
97      EasingFunction::EaseInOutCubic => ease(EaseInOutCubic, from, to, duration),
98      EasingFunction::EaseInOutQuad => ease(EaseInOutQuad, from, to, duration),
99      EasingFunction::EaseInOutQuart => ease(EaseInOutQuart, from, to, duration),
100      EasingFunction::EaseInOutQuint => ease(EaseInOutQuint, from, to, duration),
101      EasingFunction::EaseInQuad => ease(EaseInQuad, from, to, duration),
102      EasingFunction::EaseInQuart => ease(EaseInQuart, from, to, duration),
103      EasingFunction::EaseInQuint => ease(EaseInQuint, from, to, duration),
104      EasingFunction::EaseOut => ease(EaseOut, from, to, duration),
105      EasingFunction::EaseOutCubic => ease(EaseOutCubic, from, to, duration),
106      EasingFunction::EaseOutQuad => ease(EaseOutQuad, from, to, duration),
107      EasingFunction::EaseOutQuart => ease(EaseOutQuart, from, to, duration),
108      EasingFunction::EaseOutQuint => ease(EaseOutQuint, from, to, duration),
109      EasingFunction::Linear => ease(Linear, from, to, duration),
110      EasingFunction::Step => ease(Step, from, to, duration),
111    }
112  }
113
114  pub fn apply_translation_x(
115    &mut self,
116    from_value: i32,
117    to_value: i32,
118    time: f32,
119    easing: EasingFunction,
120  ) {
121    self.translation_x_running = true;
122    self.translation_x_ease = easing;
123    self.translation_x_from_value = from_value;
124    self.translation_x_to_value = to_value;
125    self.translation_x_time_duration = time * 1000.0; // msec.
126  }
127
128  pub fn apply_translation_y(
129    &mut self,
130    from_value: i32,
131    to_value: i32,
132    time: f32,
133    easing: EasingFunction,
134  ) {
135    self.translation_y_running = true;
136    self.translation_y_ease = easing;
137    self.translation_y_from_value = from_value;
138    self.translation_y_to_value = to_value;
139    self.translation_y_time_duration = time * 1000.0; // msec.
140  }
141
142  pub fn apply_rotation(
143    &mut self,
144    from_value: i32,
145    to_value: i32,
146    time: f32,
147    easing: EasingFunction,
148  ) {
149    self.rotation_running = true;
150    self.rotation_ease = easing;
151    self.rotation_from_value = from_value;
152    self.rotation_to_value = to_value;
153    self.rotation_time_duration = time * 1000.0; // msec.
154  }
155
156  pub fn apply_scale(
157    &mut self,
158    from_value: f32,
159    to_value: f32,
160    time: f32,
161    easing: EasingFunction,
162  ) {
163    self.scale_running = true;
164    self.scale_ease = easing;
165    self.scale_from_value = from_value;
166    self.scale_to_value = to_value;
167    self.scale_time_duration = time * 1000.0; // msec.
168  }
169
170  pub fn run(&mut self, actor: &mut Actor) {
171    if self.translation_x_running == true {
172      if self.translation_x_starting_time == 0 {
173         self.translation_x_starting_time =
174           self.animation_time_instance.elapsed().as_millis();
175      }
176      let cur_time = (self.animation_time_instance.elapsed().as_millis()
177        - self.translation_x_starting_time) as f32
178        / self.translation_x_time_duration;
179      if cur_time <= 1.0 {
180        actor.x = Animation::easing_function(
181          self.translation_x_ease,
182          self.translation_x_from_value as f32,
183          self.translation_x_to_value as f32,
184          cur_time,
185        ) as i32;
186      } else {
187        self.translation_x_running = false;
188        self.translation_x_starting_time = 0;
189        actor.x = self.translation_x_to_value;
190      }
191    }
192
193    if self.translation_y_running == true {
194      if self.translation_y_starting_time == 0 {
195        self.translation_y_starting_time =
196          self.animation_time_instance.elapsed().as_millis();
197      }
198      let cur_time = (self.animation_time_instance.elapsed().as_millis()
199        - self.translation_y_starting_time) as f32
200        / self.translation_y_time_duration;
201      if cur_time <= 1.0 {
202        actor.y = Animation::easing_function(
203          self.translation_y_ease,
204          self.translation_y_from_value as f32,
205          self.translation_y_to_value as f32,
206          cur_time,
207        ) as i32;
208      } else {
209        self.translation_y_running = false;
210        self.translation_y_starting_time = 0;
211        actor.y = self.translation_y_to_value;
212      }
213    }
214
215    if self.rotation_running == true {
216      if self.rotation_starting_time == 0 {
217        self.rotation_starting_time = self.animation_time_instance.elapsed().as_millis();
218      }
219
220      let cur_time = (self.animation_time_instance.elapsed().as_millis()
221        - self.rotation_starting_time) as f32
222        / self.rotation_time_duration as f32;
223      if cur_time <= 1.0 {
224        actor.rotation = Animation::easing_function(
225          self.rotation_ease,
226          self.rotation_from_value as f32,
227          self.rotation_to_value as f32,
228          cur_time,
229        ) as i32;
230      } else {
231        self.rotation_running = false;
232        self.rotation_starting_time = 0;
233        actor.rotation = self.rotation_to_value;
234      }
235    }
236
237    if self.scale_running == true {
238      if self.scale_starting_time == 0 {
239        self.scale_starting_time = self.animation_time_instance.elapsed().as_millis();
240      }
241
242      let cur_time = (self.animation_time_instance.elapsed().as_millis()
243        - self.scale_starting_time) as f32
244        / self.scale_time_duration as f32;
245      if cur_time <= 1.0 {
246        actor.scale_x = Animation::easing_function(
247          self.scale_ease,
248          self.scale_from_value,
249          self.scale_to_value,
250          cur_time,
251        ) as f32;
252        actor.scale_y = Animation::easing_function(
253          self.scale_ease,
254          self.scale_from_value,
255          self.scale_to_value,
256          cur_time,
257        ) as f32;
258      } else {
259        self.scale_running = false;
260        self.scale_starting_time = 0;
261        actor.scale_x = self.scale_to_value;
262        actor.scale_y = self.scale_to_value;
263      }
264    }
265
266    if self.translation_x_running == true
267      || self.translation_y_running == true
268      || self.rotation_running == true
269      || self.scale_running == true
270    {
271      actor.animated = true;
272    } else {
273      actor.animated = false;
274    }
275  }
276}