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