euv_engine/easing/
impl.rs1use super::*;
2
3impl Easing {
5 pub fn evaluate(&self, t: f64) -> f64 {
19 let t: f64 = Numeric::clamp(t, 0.0, 1.0);
20 match self {
21 Easing::Linear => t,
22 Easing::InQuad => t * t,
23 Easing::OutQuad => 1.0 - (1.0 - t) * (1.0 - t),
24 Easing::InOutQuad => {
25 if t < 0.5 {
26 2.0 * t * t
27 } else {
28 1.0 - (-2.0 * t + 2.0).powi(2) / 2.0
29 }
30 }
31 Easing::InCubic => t * t * t,
32 Easing::OutCubic => 1.0 - (1.0 - t).powi(3),
33 Easing::InOutCubic => {
34 if t < 0.5 {
35 4.0 * t * t * t
36 } else {
37 1.0 - (-2.0 * t + 2.0).powi(3) / 2.0
38 }
39 }
40 Easing::InQuart => t * t * t * t,
41 Easing::OutQuart => 1.0 - (1.0 - t).powi(4),
42 Easing::InOutQuart => {
43 if t < 0.5 {
44 8.0 * t * t * t * t
45 } else {
46 1.0 - (-2.0 * t + 2.0).powi(4) / 2.0
47 }
48 }
49 Easing::InQuint => t * t * t * t * t,
50 Easing::OutQuint => 1.0 - (1.0 - t).powi(5),
51 Easing::InOutQuint => {
52 if t < 0.5 {
53 16.0 * t * t * t * t * t
54 } else {
55 1.0 - (-2.0 * t + 2.0).powi(5) / 2.0
56 }
57 }
58 Easing::InSine => 1.0 - (t * HALF_PI).cos(),
59 Easing::OutSine => (t * HALF_PI).sin(),
60 Easing::InOutSine => -((t * PI).cos() - 1.0) / 2.0,
61 Easing::InExpo => {
62 if t == 0.0 {
63 0.0
64 } else {
65 2.0_f64.powf(10.0 * t - 10.0)
66 }
67 }
68 Easing::OutExpo => {
69 if t == 1.0 {
70 1.0
71 } else {
72 1.0 - 2.0_f64.powf(-10.0 * t)
73 }
74 }
75 Easing::InOutExpo => {
76 if t == 0.0 {
77 0.0
78 } else if t == 1.0 {
79 1.0
80 } else if t < 0.5 {
81 2.0_f64.powf(20.0 * t - 10.0) / 2.0
82 } else {
83 (2.0 - 2.0_f64.powf(-20.0 * t + 10.0)) / 2.0
84 }
85 }
86 Easing::InCirc => 1.0 - (1.0 - t * t).sqrt(),
87 Easing::OutCirc => (1.0 - (t - 1.0).powi(2)).sqrt(),
88 Easing::InOutCirc => {
89 if t < 0.5 {
90 (1.0 - (1.0 - (2.0 * t).powi(2)).sqrt()) / 2.0
91 } else {
92 ((1.0 - (-2.0 * t + 2.0).powi(2)).sqrt() + 1.0) / 2.0
93 }
94 }
95 Easing::InBack => {
96 let c: f64 = BACK_OVERSHOOT;
97 (c + 1.0) * t * t * t - c * t * t
98 }
99 Easing::OutBack => {
100 let c: f64 = BACK_OVERSHOOT;
101 1.0 + (c + 1.0) * (t - 1.0).powi(3) + c * (t - 1.0).powi(2)
102 }
103 Easing::InOutBack => {
104 let c: f64 = BACK_OVERSHOOT_INOUT;
105 if t < 0.5 {
106 ((2.0 * t).powi(2) * ((c + 1.0) * 2.0 * t - c)) / 2.0
107 } else {
108 ((2.0 * t - 2.0).powi(2) * ((c + 1.0) * (2.0 * t - 2.0) + c) + 2.0) / 2.0
109 }
110 }
111 Easing::InElastic => {
112 if t == 0.0 {
113 0.0
114 } else if t == 1.0 {
115 1.0
116 } else {
117 -2.0_f64.powf(10.0 * t - 10.0) * ((t * 10.0 - 10.75) * ELASTIC_PERIOD).sin()
118 }
119 }
120 Easing::OutElastic => {
121 if t == 0.0 {
122 0.0
123 } else if t == 1.0 {
124 1.0
125 } else {
126 2.0_f64.powf(-10.0 * t) * ((t * 10.0 - 0.75) * ELASTIC_PERIOD).sin() + 1.0
127 }
128 }
129 Easing::InOutElastic => {
130 if t == 0.0 {
131 0.0
132 } else if t == 1.0 {
133 1.0
134 } else if t < 0.5 {
135 -(2.0_f64.powf(20.0 * t - 10.0)
136 * ((20.0 * t - 11.125) * ELASTIC_PERIOD_INOUT).sin())
137 / 2.0
138 } else {
139 (2.0_f64.powf(-20.0 * t + 10.0)
140 * ((20.0 * t - 11.125) * ELASTIC_PERIOD_INOUT).sin())
141 / 2.0
142 + 1.0
143 }
144 }
145 Easing::InBounce => 1.0 - Easing::OutBounce.evaluate(1.0 - t),
146 Easing::OutBounce => Easing::bounce_out(t),
147 Easing::InOutBounce => {
148 if t < 0.5 {
149 (1.0 - Easing::bounce_out(1.0 - 2.0 * t)) / 2.0
150 } else {
151 (1.0 + Easing::bounce_out(2.0 * t - 1.0)) / 2.0
152 }
153 }
154 }
155 }
156
157 pub fn interpolate(&self, start: f64, end: f64, t: f64) -> f64 {
169 Numeric::lerp(start, end, self.evaluate(t))
170 }
171
172 fn bounce_out(t: f64) -> f64 {
183 let n: f64 = BOUNCE_DIVISIONS;
184 if t < 1.0 / n {
185 7.5625 * t * t
186 } else if t < 2.0 / n {
187 let t: f64 = t - 1.5 / n;
188 7.5625 * t * t + 0.75
189 } else if t < 2.5 / n {
190 let t: f64 = t - 2.25 / n;
191 7.5625 * t * t + 0.9375
192 } else {
193 let t: f64 = t - 2.625 / n;
194 7.5625 * t * t + 0.984375
195 }
196 }
197}