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; }
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; }
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; }
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; }
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}