ferroui_base/animation/easings/
easing.rs1use crate::animation::easings::*;
2use crate::animation::KeySpline;
3use crate::utilities::FormatError;
4use std::fmt;
5use std::rc::Rc;
6use std::str::FromStr;
7
8#[derive(Clone)]
16pub struct Easing(Rc<dyn IEasing>);
17
18impl Easing {
19 pub fn new(easing: impl IEasing) -> Self {
21 Self(Rc::new(easing))
22 }
23
24 pub fn from_rc(easing: Rc<dyn IEasing>) -> Self {
26 Self(easing)
27 }
28
29 pub fn as_rc(&self) -> &Rc<dyn IEasing> {
31 &self.0
32 }
33
34 #[inline]
36 pub fn ease(&self, progress: f64) -> f64 {
37 self.0.ease(progress)
38 }
39
40 pub fn parse(e: &str) -> Result<Easing, FormatError> {
43 if e.contains(',') {
44 return Ok(Easing::new(SplineEasing::with_key_spline(KeySpline::parse(e)?)));
45 }
46
47 Ok(match e {
48 "BackEaseIn" => Easing::new(BackEaseIn::new()),
49 "BackEaseInOut" => Easing::new(BackEaseInOut::new()),
50 "BackEaseOut" => Easing::new(BackEaseOut::new()),
51 "BounceEaseIn" => Easing::new(BounceEaseIn::new()),
52 "BounceEaseInOut" => Easing::new(BounceEaseInOut::new()),
53 "BounceEaseOut" => Easing::new(BounceEaseOut::new()),
54 "CircularEaseIn" => Easing::new(CircularEaseIn::new()),
55 "CircularEaseInOut" => Easing::new(CircularEaseInOut::new()),
56 "CircularEaseOut" => Easing::new(CircularEaseOut::new()),
57 "CubicEaseIn" => Easing::new(CubicEaseIn::new()),
58 "CubicEaseInOut" => Easing::new(CubicEaseInOut::new()),
59 "CubicEaseOut" => Easing::new(CubicEaseOut::new()),
60 "ElasticEaseIn" => Easing::new(ElasticEaseIn::new()),
61 "ElasticEaseInOut" => Easing::new(ElasticEaseInOut::new()),
62 "ElasticEaseOut" => Easing::new(ElasticEaseOut::new()),
63 "ExponentialEaseIn" => Easing::new(ExponentialEaseIn::new()),
64 "ExponentialEaseInOut" => Easing::new(ExponentialEaseInOut::new()),
65 "ExponentialEaseOut" => Easing::new(ExponentialEaseOut::new()),
66 "LinearEasing" => Easing::new(LinearEasing::new()),
67 "QuadraticEaseIn" => Easing::new(QuadraticEaseIn::new()),
68 "QuadraticEaseInOut" => Easing::new(QuadraticEaseInOut::new()),
69 "QuadraticEaseOut" => Easing::new(QuadraticEaseOut::new()),
70 "QuarticEaseIn" => Easing::new(QuarticEaseIn::new()),
71 "QuarticEaseInOut" => Easing::new(QuarticEaseInOut::new()),
72 "QuarticEaseOut" => Easing::new(QuarticEaseOut::new()),
73 "QuinticEaseIn" => Easing::new(QuinticEaseIn::new()),
74 "QuinticEaseInOut" => Easing::new(QuinticEaseInOut::new()),
75 "QuinticEaseOut" => Easing::new(QuinticEaseOut::new()),
76 "SineEaseIn" => Easing::new(SineEaseIn::new()),
77 "SineEaseInOut" => Easing::new(SineEaseInOut::new()),
78 "SineEaseOut" => Easing::new(SineEaseOut::new()),
79 "SplineEasing" => Easing::new(SplineEasing::new()),
80 "SpringEasing" => Easing::new(SpringEasing::new()),
81 _ => {
82 return Err(FormatError::from_string(format!(
83 "Easing \"{e}\" was not found in the easings module."
84 )))
85 }
86 })
87 }
88}
89
90impl IEasing for Easing {
91 fn to_shared(&self) -> std::sync::Arc<crate::animation::easings::SharedEasing> {
92 self.0.to_shared()
93 }
94
95 #[inline]
96 fn ease(&self, progress: f64) -> f64 {
97 self.0.ease(progress)
98 }
99
100 #[inline]
101 fn derives_from_easing(&self) -> bool {
102 self.0.derives_from_easing()
103 }
104}
105
106impl Default for Easing {
107 fn default() -> Self {
109 Easing::new(LinearEasing::new())
110 }
111}
112
113impl PartialEq for Easing {
114 fn eq(&self, other: &Self) -> bool {
115 std::ptr::addr_eq(Rc::as_ptr(&self.0), Rc::as_ptr(&other.0))
116 }
117}
118
119impl fmt::Debug for Easing {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 f.write_str("Easing")
122 }
123}
124
125impl FromStr for Easing {
126 type Err = FormatError;
127 fn from_str(s: &str) -> Result<Self, Self::Err> {
128 Easing::parse(s)
129 }
130}
131
132macro_rules! easing_from {
133 ($($name:ident),+ $(,)?) => {
134 $(impl From<$name> for Easing {
135 fn from(value: $name) -> Self {
136 Easing::new(value)
137 }
138 })+
139 };
140}
141
142easing_from!(
143 BackEaseIn, BackEaseInOut, BackEaseOut, BounceEaseIn, BounceEaseInOut, BounceEaseOut, CircularEaseIn, CircularEaseInOut, CircularEaseOut, CubicEaseIn, CubicEaseInOut, CubicEaseOut, ElasticEaseIn, ElasticEaseInOut, ElasticEaseOut, ExponentialEaseIn, ExponentialEaseInOut, ExponentialEaseOut, LinearEasing, QuadraticEaseIn, QuadraticEaseInOut, QuadraticEaseOut, QuarticEaseIn, QuarticEaseInOut, QuarticEaseOut, QuinticEaseIn, QuinticEaseInOut, QuinticEaseOut, SineEaseIn, SineEaseInOut, SineEaseOut, SplineEasing, SpringEasing
144);