animate_core/tween/
cycle.rs1use crate::{Animate, Cycle, TweenAnim, Tween, FRAME_TIME, IS_ANIMATING};
2use std::sync::atomic::Ordering;
3
4impl<T, E, I> Animate for Tween<T, E, I, Cycle>
5where
6 T: TweenAnim + PartialEq + Default,
7 E: Fn(f64) -> f64,
8 I: Fn(&T, &T, f64) -> T,
9{
10 type Value = T;
11
12 fn update(&mut self) {
13 if self.state.pending {
14 self.state.start = std::mem::take(&mut self.state.current);
15 self.state.pending = false;
16 }
17
18 if let Some(start_t) = self.state.started_at {
19 if self.state.duration > 0.0 {
20 let now = FRAME_TIME.load(Ordering::Relaxed);
21 let elapsed = now.saturating_sub(start_t) as f64;
22 let t_raw = (elapsed % self.state.duration) / self.state.duration;
23
24 self.state.current =
25 (self.state.interp)(&self.state.start, &self.state.target, (self.state.easing)(t_raw));
26 }
27 IS_ANIMATING.store(true, Ordering::Relaxed);
28 }
29 }
30
31 fn get(&self) -> &T {
32 &self.state.current
33 }
34
35 fn set(&mut self, target: T) {
36 let now = FRAME_TIME.load(Ordering::Relaxed);
37
38 self.state.target = target;
39 self.state.started_at = Some(now);
40 self.state.pending = true;
41 }
42
43 fn target(&self) -> &T {
44 &self.state.target
45 }
46}