animate-core 0.1.0

Animation library for Ratatui
Documentation
pub mod easing;
mod macros;
pub mod mode;
pub mod types;

use std::{
    cell::UnsafeCell,
    sync::atomic::{AtomicBool, AtomicUsize, Ordering},
    time::Instant,
};

pub use easing::*;
pub use mode::*;

pub static FRAME: AtomicUsize = AtomicUsize::new(0);
pub static IS_ANIMATING: AtomicBool = AtomicBool::new(false);

pub trait Animate {
    type Value;
    fn get(&self) -> &Self::Value;
    fn set(&mut self, target: Self::Value);
    fn target(&self) -> &Self::Value;
}

#[derive(Debug)]
pub(crate) struct AnimateState<T> {
    pub current: UnsafeCell<T>,
    pub start: UnsafeCell<T>,
    pub target: UnsafeCell<T>,
    pub started_at: UnsafeCell<Option<Instant>>,
    pub last_frame: UnsafeCell<usize>,
    pub duration: f64,
    pub easing: fn(f64) -> f64,
    pub interp: fn(&T, &T, f64) -> T,
}

impl<T: Default> AnimateState<T> {
    pub fn new(
        initial: T,
        duration: f64,
        easing: fn(f64) -> f64,
        interp: fn(&T, &T, f64) -> T,
    ) -> Self {
        Self {
            current: UnsafeCell::new(initial),
            start: UnsafeCell::new(Default::default()),
            target: UnsafeCell::new(Default::default()),
            started_at: UnsafeCell::new(None),
            last_frame: UnsafeCell::new(0),
            duration,
            easing,
            interp,
        }
    }
}

pub trait Lerp {
    fn lerp(start: &Self, end: &Self, t: f64) -> Self;
}

pub fn tick() {
    FRAME.fetch_add(1, Ordering::Relaxed);
}

pub fn is_animating() -> bool {
    IS_ANIMATING.load(Ordering::Relaxed)
}