1use core::f32::consts::TAU;
2
3const SIGMA: f32 = 0.075;
4const SIGMA_IN_OUT: f32 = 0.1125;
5const THREE_DOT_THREE_REPEATING: f32 = 10.0 / 3.0;
6const FORTY_FIVE: f32 = 2.222222;
7
8declare_tween!(
9 pub struct ElasticIn;
11
12 pub fn elastic_in;
14
15 pub fn elastic_in_at;
17
18 pub fn tween<Value: crate::TweenValue>(&mut self, value_delta: Value, mut percent: f32) -> Value {
19 if percent == 0.0 {
20 return value_delta.scale(0.0);
21 }
22
23 if percent == 1.0 {
24 return value_delta;
25 }
26
27 percent -= 1.0;
28
29 #[cfg(feature = "libm")]
30 let scalar = libm::powf(2.0, percent * 10.0);
31
32 #[cfg(feature = "std")]
33 let scalar = 2f32.powf(percent * 10.0);
34
35 let post_fix = value_delta.scale(scalar);
36 let temp = (percent - SIGMA) * TAU * THREE_DOT_THREE_REPEATING;
37
38 #[cfg(feature = "libm")]
39 let scalar = -libm::sinf(temp);
40
41 #[cfg(feature = "std")]
42 let scalar = -temp.sin();
43
44 post_fix.scale(scalar)
45 }
46);
47
48declare_tween!(
49 pub struct ElasticOut;
51
52 pub fn elastic_out;
54
55 pub fn elastic_out_at;
57
58 pub fn tween<Value: crate::TweenValue>(&mut self, value_delta: Value, percent: f32) -> Value {
59 if percent == 0.0 {
60 return value_delta.scale(0.0);
61 }
62
63 if percent == 1.0 {
64 return value_delta;
65 }
66
67 let temp = (percent - SIGMA) * TAU * THREE_DOT_THREE_REPEATING;
68
69 #[cfg(feature = "libm")]
70 let scalar = libm::powf(2.0, -10.0 * percent) * libm::sinf(temp);
71
72 #[cfg(feature = "std")]
73 let scalar = 2f32.powf(-10.0 * percent) * temp.sin();
74
75 value_delta.scale(scalar) + value_delta
76 }
77);
78
79declare_tween!(
80 pub struct ElasticInOut;
82
83 pub fn elastic_in_out;
85
86 pub fn elastic_in_out_at;
88
89 pub fn tween<Value: crate::TweenValue>(&mut self, value_delta: Value, mut percent: f32) -> Value {
90 if percent == 0.0 {
91 return value_delta.scale(0.0);
92 }
93
94 if percent == 1.0 {
95 return value_delta;
96 }
97
98 percent = (percent * 2.0) - 1.0;
99
100 if percent < 0.0 {
101 #[cfg(feature = "libm")]
102 let scalar = libm::powf(2.0, percent * 10.0);
103
104 #[cfg(feature = "std")]
105 let scalar = 2f32.powf(percent * 10.0);
106
107 let post_fix = value_delta.scale(scalar);
108 let temp = (percent - SIGMA_IN_OUT) * TAU * FORTY_FIVE;
109
110 #[cfg(feature = "libm")]
111 let temp_sin = libm::sinf(temp);
112
113 #[cfg(feature = "std")]
114 let temp_sin = temp.sin();
115
116 post_fix.scale(-0.5 * temp_sin)
117 } else {
118 #[cfg(feature = "libm")]
119 let scalar = libm::powf(2.0, percent * -10.0);
120
121 #[cfg(feature = "std")]
122 let scalar = 2f32.powf(-10.0 * percent);
123
124 let post_fix = value_delta.scale(scalar);
125 let temp = (percent - SIGMA_IN_OUT) * TAU * FORTY_FIVE;
126
127 #[cfg(feature = "libm")]
128 let temp_sin = libm::sinf(temp);
129
130 #[cfg(feature = "std")]
131 let temp_sin = temp.sin();
132
133 post_fix.scale(temp_sin * 0.5) + value_delta
134 }
135
136 }
137);
138
139test_tween!(Elastic);