easing_function/
lib.rs

1#![doc = include_str!(".crate-docs.md")]
2use std::fmt::Debug;
3use std::sync::Arc;
4
5use easings::Linear;
6
7pub mod easings;
8
9/// An easing function for customizing animations.
10#[derive(Debug, Clone, PartialEq)]
11pub struct EasingFunction(EasingKind);
12
13impl EasingFunction {
14    /// Returns a new easing function using `func`.
15    pub fn from_fn(func: fn(f32) -> f32) -> Self {
16        Self(EasingKind::Fn(func))
17    }
18
19    /// Returns a new easing function using `easing`.
20    pub fn new<Easing>(easing: Easing) -> Self
21    where
22        Easing: crate::Easing + Debug + Clone,
23    {
24        Self(EasingKind::Custom(Arc::new(easing)))
25    }
26}
27
28impl Easing for EasingFunction {
29    fn ease(&self, progress: f32) -> f32 {
30        self.0.ease(progress)
31    }
32}
33
34impl Default for EasingFunction {
35    fn default() -> Self {
36        Self::from(Linear)
37    }
38}
39
40#[derive(Debug, Clone)]
41enum EasingKind {
42    /// A function pointer to use as an easing function.
43    Fn(fn(f32) -> f32),
44    /// A custom easing implementation.
45    Custom(Arc<dyn Easing>),
46}
47
48impl Easing for EasingKind {
49    fn ease(&self, progress: f32) -> f32 {
50        match self {
51            Self::Fn(func) => func(progress),
52            Self::Custom(func) => func.ease(progress),
53        }
54    }
55}
56
57impl PartialEq for EasingKind {
58    fn eq(&self, other: &Self) -> bool {
59        match (self, other) {
60            (Self::Fn(l0), Self::Fn(r0)) => l0 == r0,
61            (Self::Custom(l0), Self::Custom(r0)) => std::ptr::eq(&**l0, &**r0),
62            _ => false,
63        }
64    }
65}
66
67/// Performs easing for value interpolation.
68pub trait Easing: Debug + Send + Sync + 'static {
69    /// Eases a value ranging between zero and one. The resulting value does not
70    /// need to be bounded between zero and one.
71    fn ease(&self, progress: f32) -> f32;
72}
73
74impl<T> Easing for T
75where
76    T: Fn(f32) -> f32 + Debug + Send + Sync + 'static,
77{
78    fn ease(&self, progress: f32) -> f32 {
79        self(progress)
80    }
81}