Skip to main content

photonic_effects/
easing.rs

1use std::fmt::Debug;
2use std::time::Duration;
3
4use num_traits::Float;
5
6#[derive(Debug)]
7pub struct Easing<F: Float> {
8    pub func: fn(F) -> F,
9    pub speed: Duration,
10}
11
12impl<F: Float> Easing<F> {
13    pub fn new(func: fn(F) -> F) -> Self {
14        return Self {
15            func,
16            speed: Duration::from_secs(1),
17        };
18    }
19
20    pub fn with_speed(mut self, speed: Duration) -> Self {
21        self.speed = speed;
22        return self;
23    }
24}
25
26impl<F: Float> From<fn(F) -> F> for Easing<F> {
27    fn from(func: fn(F) -> F) -> Self {
28        return Self::new(func);
29    }
30}
31
32#[derive(Debug)]
33#[cfg_attr(feature = "dynamic", derive(photonic_dynamic::serde::Deserialize))]
34#[cfg_attr(feature = "dynamic", serde(rename_all = "snake_case"))]
35pub enum EasingDirection {
36    In,
37    Out,
38    InOut,
39}
40
41#[derive(Debug)]
42#[cfg_attr(feature = "dynamic", derive(photonic_dynamic::serde::Deserialize))]
43#[cfg_attr(feature = "dynamic", serde(rename_all = "snake_case"))]
44pub enum Easings {
45    Instant,
46    Linear,
47    Quadratic(EasingDirection),
48    Cubic(EasingDirection),
49    Quartic(EasingDirection),
50    Quintic(EasingDirection),
51    Sine(EasingDirection),
52    Circular(EasingDirection),
53    Exponential(EasingDirection),
54    Elastic(EasingDirection),
55    Back(EasingDirection),
56    Bounce(EasingDirection),
57}
58
59impl Easings {
60    pub fn with_speed<F: Float>(self, speed: Duration) -> Easing<F> {
61        return Easing::from(self).with_speed(speed);
62    }
63}
64
65impl<F: Float> From<Easings> for Easing<F> {
66    fn from(value: Easings) -> Self {
67        use ezing::*;
68        return match value {
69            Easings::Instant => |_| F::one(),
70            Easings::Linear => linear,
71            Easings::Quadratic(EasingDirection::In) => quad_in,
72            Easings::Quadratic(EasingDirection::Out) => quad_out,
73            Easings::Quadratic(EasingDirection::InOut) => quad_inout,
74            Easings::Cubic(EasingDirection::In) => cubic_in,
75            Easings::Cubic(EasingDirection::Out) => cubic_out,
76            Easings::Cubic(EasingDirection::InOut) => cubic_inout,
77            Easings::Quartic(EasingDirection::In) => quart_in,
78            Easings::Quartic(EasingDirection::Out) => quart_out,
79            Easings::Quartic(EasingDirection::InOut) => quad_inout,
80            Easings::Quintic(EasingDirection::In) => quint_in,
81            Easings::Quintic(EasingDirection::Out) => quint_out,
82            Easings::Quintic(EasingDirection::InOut) => quint_inout,
83            Easings::Sine(EasingDirection::In) => sine_in,
84            Easings::Sine(EasingDirection::Out) => sine_out,
85            Easings::Sine(EasingDirection::InOut) => sine_inout,
86            Easings::Circular(EasingDirection::In) => circ_in,
87            Easings::Circular(EasingDirection::Out) => circ_out,
88            Easings::Circular(EasingDirection::InOut) => circ_inout,
89            Easings::Exponential(EasingDirection::In) => expo_in,
90            Easings::Exponential(EasingDirection::Out) => expo_out,
91            Easings::Exponential(EasingDirection::InOut) => expo_inout,
92            Easings::Elastic(EasingDirection::In) => elastic_in,
93            Easings::Elastic(EasingDirection::Out) => elastic_out,
94            Easings::Elastic(EasingDirection::InOut) => elastic_inout,
95            Easings::Back(EasingDirection::In) => back_in,
96            Easings::Back(EasingDirection::Out) => back_out,
97            Easings::Back(EasingDirection::InOut) => back_inout,
98            Easings::Bounce(EasingDirection::In) => bounce_in,
99            Easings::Bounce(EasingDirection::Out) => bounce_out,
100            Easings::Bounce(EasingDirection::InOut) => bounce_inout,
101        }
102        .into();
103    }
104}
105
106#[cfg(feature = "dynamic")]
107impl<'de, F: Float> serde::Deserialize<'de> for Easing<F> {
108    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
109    where D: serde::Deserializer<'de> {
110        #[derive(Debug, serde::Deserialize)]
111        struct S {
112            func: Easings,
113
114            #[serde(with = "humantime_serde")]
115            speed: Duration,
116        }
117
118        let s = S::deserialize(deserializer)?;
119
120        return Ok(s.func.with_speed(s.speed));
121    }
122}