Skip to main content

animate_core/
lib.rs

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}