1pub mod easing;
2mod macros;
3pub mod mode;
4pub mod types;
5
6use std::{
7 cell::UnsafeCell,
8 sync::atomic::{AtomicBool, AtomicUsize, Ordering},
9 time::Instant,
10};
11
12pub use easing::*;
13pub use mode::*;
14
15pub static FRAME: AtomicUsize = AtomicUsize::new(0);
16pub static IS_ANIMATING: AtomicBool = AtomicBool::new(false);
17
18pub trait Animate {
19 type Value;
20 fn get(&self) -> &Self::Value;
21 fn set(&mut self, target: Self::Value);
22 fn target(&self) -> &Self::Value;
23}
24
25#[derive(Debug)]
26pub(crate) struct AnimateState<T> {
27 pub current: UnsafeCell<T>,
28 pub start: UnsafeCell<T>,
29 pub target: UnsafeCell<T>,
30 pub started_at: UnsafeCell<Option<Instant>>,
31 pub last_frame: UnsafeCell<usize>,
32 pub duration: f64,
33 pub easing: fn(f64) -> f64,
34 pub interp: fn(&T, &T, f64) -> T,
35}
36
37impl<T: Default> AnimateState<T> {
38 pub fn new(
39 initial: T,
40 duration: f64,
41 easing: fn(f64) -> f64,
42 interp: fn(&T, &T, f64) -> T,
43 ) -> Self {
44 Self {
45 current: UnsafeCell::new(initial),
46 start: UnsafeCell::new(Default::default()),
47 target: UnsafeCell::new(Default::default()),
48 started_at: UnsafeCell::new(None),
49 last_frame: UnsafeCell::new(0),
50 duration,
51 easing,
52 interp,
53 }
54 }
55}
56
57pub trait Lerp {
58 fn lerp(start: &Self, end: &Self, t: f64) -> Self;
59}
60
61pub fn tick() {
62 FRAME.fetch_add(1, Ordering::Relaxed);
63}
64
65pub fn is_animating() -> bool {
66 IS_ANIMATING.load(Ordering::Relaxed)
67}