euv_engine/easing/
impl.rs1use super::*;
2
3pub(crate) const BACK_OVERSHOOT: f64 = 1.70158;
5
6pub(crate) const BACK_OVERSHOOT_INOUT: f64 = BACK_OVERSHOOT * 1.525;
9
10pub(crate) const BOUNCE_DIVISIONS: f64 = 2.75;
12
13pub(crate) const ELASTIC_PERIOD: f64 = TWO_PI / 3.0;
15
16pub(crate) const ELASTIC_PERIOD_INOUT: f64 = TWO_PI / 4.5;
18
19impl Easing {
21 pub fn evaluate(&self, t: f64) -> f64 {
35 let t: f64 = Numeric::clamp(t, 0.0, 1.0);
36 match self {
37 Easing::Linear => t,
38 Easing::InQuad => t * t,
39 Easing::OutQuad => 1.0 - (1.0 - t) * (1.0 - t),
40 Easing::InOutQuad => {
41 if t < 0.5 {
42 2.0 * t * t
43 } else {
44 1.0 - (-2.0 * t + 2.0).powi(2) / 2.0
45 }
46 }
47 Easing::InCubic => t * t * t,
48 Easing::OutCubic => 1.0 - (1.0 - t).powi(3),
49 Easing::InOutCubic => {
50 if t < 0.5 {
51 4.0 * t * t * t
52 } else {
53 1.0 - (-2.0 * t + 2.0).powi(3) / 2.0
54 }
55 }
56 Easing::InQuart => t * t * t * t,
57 Easing::OutQuart => 1.0 - (1.0 - t).powi(4),
58 Easing::InOutQuart => {
59 if t < 0.5 {
60 8.0 * t * t * t * t
61 } else {
62 1.0 - (-2.0 * t + 2.0).powi(4) / 2.0
63 }
64 }
65 Easing::InQuint => t * t * t * t * t,
66 Easing::OutQuint => 1.0 - (1.0 - t).powi(5),
67 Easing::InOutQuint => {
68 if t < 0.5 {
69 16.0 * t * t * t * t * t
70 } else {
71 1.0 - (-2.0 * t + 2.0).powi(5) / 2.0
72 }
73 }
74 Easing::InSine => 1.0 - (t * HALF_PI).cos(),
75 Easing::OutSine => (t * HALF_PI).sin(),
76 Easing::InOutSine => -((t * PI).cos() - 1.0) / 2.0,
77 Easing::InExpo => {
78 if t == 0.0 {
79 0.0
80 } else {
81 2.0_f64.powf(10.0 * t - 10.0)
82 }
83 }
84 Easing::OutExpo => {
85 if t == 1.0 {
86 1.0
87 } else {
88 1.0 - 2.0_f64.powf(-10.0 * t)
89 }
90 }
91 Easing::InOutExpo => {
92 if t == 0.0 {
93 0.0
94 } else if t == 1.0 {
95 1.0
96 } else if t < 0.5 {
97 2.0_f64.powf(20.0 * t - 10.0) / 2.0
98 } else {
99 (2.0 - 2.0_f64.powf(-20.0 * t + 10.0)) / 2.0
100 }
101 }
102 Easing::InCirc => 1.0 - (1.0 - t * t).sqrt(),
103 Easing::OutCirc => (1.0 - (t - 1.0).powi(2)).sqrt(),
104 Easing::InOutCirc => {
105 if t < 0.5 {
106 (1.0 - (1.0 - (2.0 * t).powi(2)).sqrt()) / 2.0
107 } else {
108 ((1.0 - (-2.0 * t + 2.0).powi(2)).sqrt() + 1.0) / 2.0
109 }
110 }
111 Easing::InBack => {
112 let c: f64 = BACK_OVERSHOOT;
113 (c + 1.0) * t * t * t - c * t * t
114 }
115 Easing::OutBack => {
116 let c: f64 = BACK_OVERSHOOT;
117 1.0 + (c + 1.0) * (t - 1.0).powi(3) + c * (t - 1.0).powi(2)
118 }
119 Easing::InOutBack => {
120 let c: f64 = BACK_OVERSHOOT_INOUT;
121 if t < 0.5 {
122 ((2.0 * t).powi(2) * ((c + 1.0) * 2.0 * t - c)) / 2.0
123 } else {
124 ((2.0 * t - 2.0).powi(2) * ((c + 1.0) * (2.0 * t - 2.0) + c) + 2.0) / 2.0
125 }
126 }
127 Easing::InElastic => {
128 if t == 0.0 {
129 0.0
130 } else if t == 1.0 {
131 1.0
132 } else {
133 -2.0_f64.powf(10.0 * t - 10.0) * ((t * 10.0 - 10.75) * ELASTIC_PERIOD).sin()
134 }
135 }
136 Easing::OutElastic => {
137 if t == 0.0 {
138 0.0
139 } else if t == 1.0 {
140 1.0
141 } else {
142 2.0_f64.powf(-10.0 * t) * ((t * 10.0 - 0.75) * ELASTIC_PERIOD).sin() + 1.0
143 }
144 }
145 Easing::InOutElastic => {
146 if t == 0.0 {
147 0.0
148 } else if t == 1.0 {
149 1.0
150 } else if t < 0.5 {
151 -(2.0_f64.powf(20.0 * t - 10.0)
152 * ((20.0 * t - 11.125) * ELASTIC_PERIOD_INOUT).sin())
153 / 2.0
154 } else {
155 (2.0_f64.powf(-20.0 * t + 10.0)
156 * ((20.0 * t - 11.125) * ELASTIC_PERIOD_INOUT).sin())
157 / 2.0
158 + 1.0
159 }
160 }
161 Easing::InBounce => 1.0 - Easing::OutBounce.evaluate(1.0 - t),
162 Easing::OutBounce => Easing::bounce_out(t),
163 Easing::InOutBounce => {
164 if t < 0.5 {
165 (1.0 - Easing::bounce_out(1.0 - 2.0 * t)) / 2.0
166 } else {
167 (1.0 + Easing::bounce_out(2.0 * t - 1.0)) / 2.0
168 }
169 }
170 }
171 }
172
173 pub fn interpolate(&self, start: f64, end: f64, t: f64) -> f64 {
185 Numeric::lerp(start, end, self.evaluate(t))
186 }
187
188 fn bounce_out(t: f64) -> f64 {
199 let n: f64 = BOUNCE_DIVISIONS;
200 if t < 1.0 / n {
201 7.5625 * t * t
202 } else if t < 2.0 / n {
203 let t: f64 = t - 1.5 / n;
204 7.5625 * t * t + 0.75
205 } else if t < 2.5 / n {
206 let t: f64 = t - 2.25 / n;
207 7.5625 * t * t + 0.9375
208 } else {
209 let t: f64 = t - 2.625 / n;
210 7.5625 * t * t + 0.984375
211 }
212 }
213}