animate-core 0.2.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},
};

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

pub static FRAME_TIME: 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, Default)]
pub(crate) struct StateInner<T> {
    pub current: T,
    pub start: T,
    pub target: T,
    pub started_at: Option<usize>,
    pub last_update: usize,
}

#[derive(Debug)]
pub(crate) struct AnimateState<T, E, I>
where
    E: Fn(f64) -> f64,
    I: Fn(&T, &T, f64) -> T,
{
    pub inner: UnsafeCell<StateInner<T>>,
    pub duration: f64,
    pub easing: E,
    pub interp: I,
}

impl<T: Default, E, I> AnimateState<T, E, I>
where
    E: Fn(f64) -> f64,
    I: Fn(&T, &T, f64) -> T,
{
    pub fn new(initial: T, duration: f64, easing: E, interp: I) -> Self {
        Self {
            inner: UnsafeCell::new(StateInner {
                current: initial,
                start: Default::default(),
                target: Default::default(),
                started_at: None,
                last_update: 0,
            }),
            duration: duration.max(f64::MIN_POSITIVE),
            easing,
            interp,
        }
    }
}

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

#[inline(always)]
pub fn tick(delta: usize) {
    FRAME_TIME.fetch_add(delta, Ordering::Relaxed);
    IS_ANIMATING.store(false, Ordering::Relaxed);
}

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