1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "easing_curve.h"
16
17 #include <base/math/mathf.h>
18
19 META_BEGIN_NAMESPACE()
20
21 namespace Curves {
22 namespace Easing {
23
AreEqual(float v1,float v2)24 bool AreEqual(float v1, float v2)
25 {
26 return BASE_NS::Math::abs(v1 - v2) < BASE_NS::Math::EPSILON;
27 }
Pow2(float v)28 float Pow2(float v)
29 {
30 return v * v;
31 }
Pow3(float v)32 float Pow3(float v)
33 {
34 return v * v * v;
35 }
Pow4(float v)36 float Pow4(float v)
37 {
38 return v * v * v * v;
39 }
Pow5(float v)40 float Pow5(float v)
41 {
42 return v * v * v * v * v;
43 }
EaseLinear(float t)44 float EaseLinear(float t)
45 {
46 return t;
47 }
EaseInSine(float t)48 float EaseInSine(float t)
49 {
50 return 1.f - BASE_NS::Math::cos((t * BASE_NS::Math::PI) / 2.f);
51 }
EaseOutSine(float t)52 float EaseOutSine(float t)
53 {
54 return BASE_NS::Math::sin((t * BASE_NS::Math::PI) / 2.f);
55 }
EaseInOutSine(float t)56 float EaseInOutSine(float t)
57 {
58 return -(BASE_NS::Math::cos(BASE_NS::Math::PI * t) - 1.f) / 2.f;
59 }
EaseInQuad(float t)60 float EaseInQuad(float t)
61 {
62 return Pow2(t);
63 }
EaseOutQuad(float t)64 float EaseOutQuad(float t)
65 {
66 return 1.f - Pow2(1.f - t);
67 }
EaseInOutQuad(float t)68 float EaseInOutQuad(float t)
69 {
70 if (t < 0.5f) {
71 return 2 * t * t;
72 }
73 return 1.f - (Pow2(-2.f * t + 2.f) / 2.f);
74 }
EaseInCubic(float t)75 float EaseInCubic(float t)
76 {
77 return Pow3(t);
78 }
EaseOutCubic(float t)79 float EaseOutCubic(float t)
80 {
81 return 1.f - Pow3(1.f - t);
82 }
EaseInOutCubic(float t)83 float EaseInOutCubic(float t)
84 {
85 if (t < 0.5f) {
86 return 4 * t * t * t;
87 }
88 return 1.f - (Pow3(-2.f * t + 2.f) / 2.f);
89 }
EaseInQuart(float t)90 float EaseInQuart(float t)
91 {
92 return Pow4(t);
93 }
EaseOutQuart(float t)94 float EaseOutQuart(float t)
95 {
96 return 1.f - Pow4(1.f - t);
97 }
EaseInOutQuart(float t)98 float EaseInOutQuart(float t)
99 {
100 if (t < 0.5f) {
101 return 8 * Pow4(t);
102 }
103 return 1.f - (Pow4(-2.f * t + 2.f) / 2.f);
104 }
EaseInQuint(float t)105 float EaseInQuint(float t)
106 {
107 return Pow5(t);
108 }
EaseOutQuint(float t)109 float EaseOutQuint(float t)
110 {
111 return 1.f - Pow5(1.f - t);
112 }
EaseInOutQuint(float t)113 float EaseInOutQuint(float t)
114 {
115 if (t < 0.5f) {
116 return 16 * Pow5(t);
117 }
118 return 1.f - (Pow5(-2.f * t + 2.f) / 2.f);
119 }
EaseInExpo(float t)120 float EaseInExpo(float t)
121 {
122 if (AreEqual(t, 0.f)) {
123 return 0;
124 }
125 return BASE_NS::Math::pow(2.f, 10 * t - 10);
126 }
EaseOutExpo(float t)127 float EaseOutExpo(float t)
128 {
129 if (AreEqual(t, 1.f)) {
130 return 1;
131 }
132 return 1.f - BASE_NS::Math::pow(2.f, -10 * t);
133 }
EaseInOutExpo(float t)134 float EaseInOutExpo(float t)
135 {
136 if (AreEqual(t, 0.f)) {
137 return 0.f;
138 }
139 if (AreEqual(t, 1.f)) {
140 return 1.f;
141 }
142 if (t < .5f) {
143 return BASE_NS::Math::pow(2.f, 20 * t - 10) / 2.f;
144 }
145 return (2.f - BASE_NS::Math::pow(2.f, -20 * t + 10)) / 2.f;
146 }
EaseInCirc(float t)147 float EaseInCirc(float t)
148 {
149 return 1.f - BASE_NS::Math::sqrt(1.f - Pow2(t));
150 }
EaseOutCirc(float t)151 float EaseOutCirc(float t)
152 {
153 return BASE_NS::Math::sqrt(1.f - Pow2(t - 1.f));
154 }
EaseInOutCirc(float t)155 float EaseInOutCirc(float t)
156 {
157 if (t < 0.5f) {
158 return (1.f - BASE_NS::Math::sqrt(1.f - Pow2(2.f * t))) / 2.f;
159 }
160 return (BASE_NS::Math::sqrt(1.f - Pow2(-2.f * t + 2.f)) + 1.f) / 2.f;
161 }
EaseInBack(float t)162 float EaseInBack(float t)
163 {
164 constexpr float c1 = 1.70158f;
165 constexpr float c3 = c1 + 1.f;
166 return c3 * Pow3(t) - c1 * Pow2(t);
167 }
EaseOutBack(float t)168 float EaseOutBack(float t)
169 {
170 constexpr float c1 = 1.70158f;
171 constexpr float c3 = c1 + 1.f;
172 return 1.f + c3 * Pow3(t - 1.f) + c1 * Pow2(t - 1.f);
173 }
EaseInOutBack(float t)174 float EaseInOutBack(float t)
175 {
176 constexpr float c1 = 1.70158f;
177 constexpr float c2 = c1 * 1.525f;
178 if (t < 0.5f) {
179 return (Pow2(2.f * t) * ((c2 + 1.f) * 2.f * t - c2)) / 2.f;
180 }
181 return (Pow2(2.f * t - 2.f) * ((c2 + 1.f) * (t * 2.f - 2.f) + c2) + 2.f) / 2.f;
182 }
EaseInElastic(float t)183 float EaseInElastic(float t)
184 {
185 constexpr float c4 = (2.f * BASE_NS::Math::PI) / 3.f;
186 if (AreEqual(t, 0.f)) {
187 return 0;
188 }
189 if (AreEqual(t, 1.f)) {
190 return 1;
191 }
192 return -BASE_NS::Math::pow(2.f, 10 * t - 10) * BASE_NS::Math::sin((t * 10 - 10.75f) * c4);
193 }
EaseOutElastic(float t)194 float EaseOutElastic(float t)
195 {
196 constexpr float c4 = (2.f * BASE_NS::Math::PI) / 3.f;
197 if (AreEqual(t, 0.f)) {
198 return 0;
199 }
200 if (AreEqual(t, 1.f)) {
201 return 1;
202 }
203 return BASE_NS::Math::pow(2.f, -10 * t) * BASE_NS::Math::sin((t * 10 - 0.75f) * c4) + 1.f;
204 }
EaseInOutElastic(float t)205 float EaseInOutElastic(float t)
206 {
207 constexpr float c5 = (2.f * BASE_NS::Math::PI) / 4.5f;
208 if (AreEqual(t, 0.f)) {
209 return 0;
210 }
211 if (AreEqual(t, 1.f)) {
212 return 1;
213 }
214 if (t < 0.5f) {
215 return -(BASE_NS::Math::pow(2.f, 20 * t - 10) * BASE_NS::Math::sin((20 * t - 11.125f) * c5)) / 2.f;
216 }
217 return (BASE_NS::Math::pow(2.f, -20 * t + 10) * BASE_NS::Math::sin((20 * t - 11.125f) * c5)) / 2.f + 1.f;
218 }
EaseOutBounce(float t)219 float EaseOutBounce(float t)
220 {
221 constexpr float n1 = 7.5625f;
222 constexpr float d1 = 2.75f;
223 if (t < 1.f / d1) {
224 return n1 * Pow2(t);
225 }
226 if (t < (2.f / d1)) {
227 return n1 * Pow2(t - (1.5f / d1)) + 0.75f;
228 }
229 if (t < (2.5f / d1)) {
230 return n1 * Pow2(t - (2.25f / d1)) + 0.9375f;
231 }
232 return n1 * Pow2(t - (2.625f / d1)) + 0.984375f;
233 }
EaseInBounce(float t)234 float EaseInBounce(float t)
235 {
236 return 1.f - EaseOutBounce(1.f - t);
237 }
EaseInOutBounce(float t)238 float EaseInOutBounce(float t)
239 {
240 if (t < 0.5f) {
241 return (1.f - EaseOutBounce(1.f - 2.f * t)) / 2.f;
242 }
243 return (1.f + EaseOutBounce(2.f * t - 1.f)) / 2.f;
244 }
EaseStepStart(float)245 float EaseStepStart(float)
246 {
247 return 1.f;
248 }
EaseStepEnd(float t)249 float EaseStepEnd(float t)
250 {
251 return t < 1.f ? 0.f : 1.f;
252 }
253
254 // Declares the implementation
255 #define IMPLEMENT_EASING_CURVE(name) \
256 float name##EasingCurve::Transform(float t) const \
257 { \
258 return Ease##name(t); \
259 }
260
261 IMPLEMENT_EASING_CURVE(Linear)
262 IMPLEMENT_EASING_CURVE(InQuad)
263 IMPLEMENT_EASING_CURVE(OutQuad)
264 IMPLEMENT_EASING_CURVE(InOutQuad)
265 IMPLEMENT_EASING_CURVE(InCubic)
266 IMPLEMENT_EASING_CURVE(OutCubic)
267 IMPLEMENT_EASING_CURVE(InOutCubic)
268 IMPLEMENT_EASING_CURVE(InSine)
269 IMPLEMENT_EASING_CURVE(OutSine)
270 IMPLEMENT_EASING_CURVE(InOutSine)
271 IMPLEMENT_EASING_CURVE(InQuart)
272 IMPLEMENT_EASING_CURVE(OutQuart)
273 IMPLEMENT_EASING_CURVE(InOutQuart)
274 IMPLEMENT_EASING_CURVE(InQuint)
275 IMPLEMENT_EASING_CURVE(OutQuint)
276 IMPLEMENT_EASING_CURVE(InOutQuint)
277 IMPLEMENT_EASING_CURVE(InExpo)
278 IMPLEMENT_EASING_CURVE(OutExpo)
279 IMPLEMENT_EASING_CURVE(InOutExpo)
280 IMPLEMENT_EASING_CURVE(InCirc)
281 IMPLEMENT_EASING_CURVE(OutCirc)
282 IMPLEMENT_EASING_CURVE(InOutCirc)
283 IMPLEMENT_EASING_CURVE(InBack)
284 IMPLEMENT_EASING_CURVE(OutBack)
285 IMPLEMENT_EASING_CURVE(InOutBack)
286 IMPLEMENT_EASING_CURVE(InElastic)
287 IMPLEMENT_EASING_CURVE(OutElastic)
288 IMPLEMENT_EASING_CURVE(InOutElastic)
289 IMPLEMENT_EASING_CURVE(InBounce)
290 IMPLEMENT_EASING_CURVE(OutBounce)
291 IMPLEMENT_EASING_CURVE(InOutBounce)
292 IMPLEMENT_EASING_CURVE(StepStart)
293 IMPLEMENT_EASING_CURVE(StepEnd)
294
295 } // namespace Easing
296 } // namespace Curves
297
298 META_END_NAMESPACE()
299