photonic_effects/
easing.rs1use 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}