18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci#include "easing_curve.h" 168bf80f4bSopenharmony_ci 178bf80f4bSopenharmony_ci#include <base/math/mathf.h> 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 208bf80f4bSopenharmony_ci 218bf80f4bSopenharmony_cinamespace Curves { 228bf80f4bSopenharmony_cinamespace Easing { 238bf80f4bSopenharmony_ci 248bf80f4bSopenharmony_cibool AreEqual(float v1, float v2) 258bf80f4bSopenharmony_ci{ 268bf80f4bSopenharmony_ci return BASE_NS::Math::abs(v1 - v2) < BASE_NS::Math::EPSILON; 278bf80f4bSopenharmony_ci} 288bf80f4bSopenharmony_cifloat Pow2(float v) 298bf80f4bSopenharmony_ci{ 308bf80f4bSopenharmony_ci return v * v; 318bf80f4bSopenharmony_ci} 328bf80f4bSopenharmony_cifloat Pow3(float v) 338bf80f4bSopenharmony_ci{ 348bf80f4bSopenharmony_ci return v * v * v; 358bf80f4bSopenharmony_ci} 368bf80f4bSopenharmony_cifloat Pow4(float v) 378bf80f4bSopenharmony_ci{ 388bf80f4bSopenharmony_ci return v * v * v * v; 398bf80f4bSopenharmony_ci} 408bf80f4bSopenharmony_cifloat Pow5(float v) 418bf80f4bSopenharmony_ci{ 428bf80f4bSopenharmony_ci return v * v * v * v * v; 438bf80f4bSopenharmony_ci} 448bf80f4bSopenharmony_cifloat EaseLinear(float t) 458bf80f4bSopenharmony_ci{ 468bf80f4bSopenharmony_ci return t; 478bf80f4bSopenharmony_ci} 488bf80f4bSopenharmony_cifloat EaseInSine(float t) 498bf80f4bSopenharmony_ci{ 508bf80f4bSopenharmony_ci return 1.f - BASE_NS::Math::cos((t * BASE_NS::Math::PI) / 2.f); 518bf80f4bSopenharmony_ci} 528bf80f4bSopenharmony_cifloat EaseOutSine(float t) 538bf80f4bSopenharmony_ci{ 548bf80f4bSopenharmony_ci return BASE_NS::Math::sin((t * BASE_NS::Math::PI) / 2.f); 558bf80f4bSopenharmony_ci} 568bf80f4bSopenharmony_cifloat EaseInOutSine(float t) 578bf80f4bSopenharmony_ci{ 588bf80f4bSopenharmony_ci return -(BASE_NS::Math::cos(BASE_NS::Math::PI * t) - 1.f) / 2.f; 598bf80f4bSopenharmony_ci} 608bf80f4bSopenharmony_cifloat EaseInQuad(float t) 618bf80f4bSopenharmony_ci{ 628bf80f4bSopenharmony_ci return Pow2(t); 638bf80f4bSopenharmony_ci} 648bf80f4bSopenharmony_cifloat EaseOutQuad(float t) 658bf80f4bSopenharmony_ci{ 668bf80f4bSopenharmony_ci return 1.f - Pow2(1.f - t); 678bf80f4bSopenharmony_ci} 688bf80f4bSopenharmony_cifloat EaseInOutQuad(float t) 698bf80f4bSopenharmony_ci{ 708bf80f4bSopenharmony_ci if (t < 0.5f) { 718bf80f4bSopenharmony_ci return 2 * t * t; 728bf80f4bSopenharmony_ci } 738bf80f4bSopenharmony_ci return 1.f - (Pow2(-2.f * t + 2.f) / 2.f); 748bf80f4bSopenharmony_ci} 758bf80f4bSopenharmony_cifloat EaseInCubic(float t) 768bf80f4bSopenharmony_ci{ 778bf80f4bSopenharmony_ci return Pow3(t); 788bf80f4bSopenharmony_ci} 798bf80f4bSopenharmony_cifloat EaseOutCubic(float t) 808bf80f4bSopenharmony_ci{ 818bf80f4bSopenharmony_ci return 1.f - Pow3(1.f - t); 828bf80f4bSopenharmony_ci} 838bf80f4bSopenharmony_cifloat EaseInOutCubic(float t) 848bf80f4bSopenharmony_ci{ 858bf80f4bSopenharmony_ci if (t < 0.5f) { 868bf80f4bSopenharmony_ci return 4 * t * t * t; 878bf80f4bSopenharmony_ci } 888bf80f4bSopenharmony_ci return 1.f - (Pow3(-2.f * t + 2.f) / 2.f); 898bf80f4bSopenharmony_ci} 908bf80f4bSopenharmony_cifloat EaseInQuart(float t) 918bf80f4bSopenharmony_ci{ 928bf80f4bSopenharmony_ci return Pow4(t); 938bf80f4bSopenharmony_ci} 948bf80f4bSopenharmony_cifloat EaseOutQuart(float t) 958bf80f4bSopenharmony_ci{ 968bf80f4bSopenharmony_ci return 1.f - Pow4(1.f - t); 978bf80f4bSopenharmony_ci} 988bf80f4bSopenharmony_cifloat EaseInOutQuart(float t) 998bf80f4bSopenharmony_ci{ 1008bf80f4bSopenharmony_ci if (t < 0.5f) { 1018bf80f4bSopenharmony_ci return 8 * Pow4(t); 1028bf80f4bSopenharmony_ci } 1038bf80f4bSopenharmony_ci return 1.f - (Pow4(-2.f * t + 2.f) / 2.f); 1048bf80f4bSopenharmony_ci} 1058bf80f4bSopenharmony_cifloat EaseInQuint(float t) 1068bf80f4bSopenharmony_ci{ 1078bf80f4bSopenharmony_ci return Pow5(t); 1088bf80f4bSopenharmony_ci} 1098bf80f4bSopenharmony_cifloat EaseOutQuint(float t) 1108bf80f4bSopenharmony_ci{ 1118bf80f4bSopenharmony_ci return 1.f - Pow5(1.f - t); 1128bf80f4bSopenharmony_ci} 1138bf80f4bSopenharmony_cifloat EaseInOutQuint(float t) 1148bf80f4bSopenharmony_ci{ 1158bf80f4bSopenharmony_ci if (t < 0.5f) { 1168bf80f4bSopenharmony_ci return 16 * Pow5(t); 1178bf80f4bSopenharmony_ci } 1188bf80f4bSopenharmony_ci return 1.f - (Pow5(-2.f * t + 2.f) / 2.f); 1198bf80f4bSopenharmony_ci} 1208bf80f4bSopenharmony_cifloat EaseInExpo(float t) 1218bf80f4bSopenharmony_ci{ 1228bf80f4bSopenharmony_ci if (AreEqual(t, 0.f)) { 1238bf80f4bSopenharmony_ci return 0; 1248bf80f4bSopenharmony_ci } 1258bf80f4bSopenharmony_ci return BASE_NS::Math::pow(2.f, 10 * t - 10); 1268bf80f4bSopenharmony_ci} 1278bf80f4bSopenharmony_cifloat EaseOutExpo(float t) 1288bf80f4bSopenharmony_ci{ 1298bf80f4bSopenharmony_ci if (AreEqual(t, 1.f)) { 1308bf80f4bSopenharmony_ci return 1; 1318bf80f4bSopenharmony_ci } 1328bf80f4bSopenharmony_ci return 1.f - BASE_NS::Math::pow(2.f, -10 * t); 1338bf80f4bSopenharmony_ci} 1348bf80f4bSopenharmony_cifloat EaseInOutExpo(float t) 1358bf80f4bSopenharmony_ci{ 1368bf80f4bSopenharmony_ci if (AreEqual(t, 0.f)) { 1378bf80f4bSopenharmony_ci return 0.f; 1388bf80f4bSopenharmony_ci } 1398bf80f4bSopenharmony_ci if (AreEqual(t, 1.f)) { 1408bf80f4bSopenharmony_ci return 1.f; 1418bf80f4bSopenharmony_ci } 1428bf80f4bSopenharmony_ci if (t < .5f) { 1438bf80f4bSopenharmony_ci return BASE_NS::Math::pow(2.f, 20 * t - 10) / 2.f; 1448bf80f4bSopenharmony_ci } 1458bf80f4bSopenharmony_ci return (2.f - BASE_NS::Math::pow(2.f, -20 * t + 10)) / 2.f; 1468bf80f4bSopenharmony_ci} 1478bf80f4bSopenharmony_cifloat EaseInCirc(float t) 1488bf80f4bSopenharmony_ci{ 1498bf80f4bSopenharmony_ci return 1.f - BASE_NS::Math::sqrt(1.f - Pow2(t)); 1508bf80f4bSopenharmony_ci} 1518bf80f4bSopenharmony_cifloat EaseOutCirc(float t) 1528bf80f4bSopenharmony_ci{ 1538bf80f4bSopenharmony_ci return BASE_NS::Math::sqrt(1.f - Pow2(t - 1.f)); 1548bf80f4bSopenharmony_ci} 1558bf80f4bSopenharmony_cifloat EaseInOutCirc(float t) 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci if (t < 0.5f) { 1588bf80f4bSopenharmony_ci return (1.f - BASE_NS::Math::sqrt(1.f - Pow2(2.f * t))) / 2.f; 1598bf80f4bSopenharmony_ci } 1608bf80f4bSopenharmony_ci return (BASE_NS::Math::sqrt(1.f - Pow2(-2.f * t + 2.f)) + 1.f) / 2.f; 1618bf80f4bSopenharmony_ci} 1628bf80f4bSopenharmony_cifloat EaseInBack(float t) 1638bf80f4bSopenharmony_ci{ 1648bf80f4bSopenharmony_ci constexpr float c1 = 1.70158f; 1658bf80f4bSopenharmony_ci constexpr float c3 = c1 + 1.f; 1668bf80f4bSopenharmony_ci return c3 * Pow3(t) - c1 * Pow2(t); 1678bf80f4bSopenharmony_ci} 1688bf80f4bSopenharmony_cifloat EaseOutBack(float t) 1698bf80f4bSopenharmony_ci{ 1708bf80f4bSopenharmony_ci constexpr float c1 = 1.70158f; 1718bf80f4bSopenharmony_ci constexpr float c3 = c1 + 1.f; 1728bf80f4bSopenharmony_ci return 1.f + c3 * Pow3(t - 1.f) + c1 * Pow2(t - 1.f); 1738bf80f4bSopenharmony_ci} 1748bf80f4bSopenharmony_cifloat EaseInOutBack(float t) 1758bf80f4bSopenharmony_ci{ 1768bf80f4bSopenharmony_ci constexpr float c1 = 1.70158f; 1778bf80f4bSopenharmony_ci constexpr float c2 = c1 * 1.525f; 1788bf80f4bSopenharmony_ci if (t < 0.5f) { 1798bf80f4bSopenharmony_ci return (Pow2(2.f * t) * ((c2 + 1.f) * 2.f * t - c2)) / 2.f; 1808bf80f4bSopenharmony_ci } 1818bf80f4bSopenharmony_ci return (Pow2(2.f * t - 2.f) * ((c2 + 1.f) * (t * 2.f - 2.f) + c2) + 2.f) / 2.f; 1828bf80f4bSopenharmony_ci} 1838bf80f4bSopenharmony_cifloat EaseInElastic(float t) 1848bf80f4bSopenharmony_ci{ 1858bf80f4bSopenharmony_ci constexpr float c4 = (2.f * BASE_NS::Math::PI) / 3.f; 1868bf80f4bSopenharmony_ci if (AreEqual(t, 0.f)) { 1878bf80f4bSopenharmony_ci return 0; 1888bf80f4bSopenharmony_ci } 1898bf80f4bSopenharmony_ci if (AreEqual(t, 1.f)) { 1908bf80f4bSopenharmony_ci return 1; 1918bf80f4bSopenharmony_ci } 1928bf80f4bSopenharmony_ci return -BASE_NS::Math::pow(2.f, 10 * t - 10) * BASE_NS::Math::sin((t * 10 - 10.75f) * c4); 1938bf80f4bSopenharmony_ci} 1948bf80f4bSopenharmony_cifloat EaseOutElastic(float t) 1958bf80f4bSopenharmony_ci{ 1968bf80f4bSopenharmony_ci constexpr float c4 = (2.f * BASE_NS::Math::PI) / 3.f; 1978bf80f4bSopenharmony_ci if (AreEqual(t, 0.f)) { 1988bf80f4bSopenharmony_ci return 0; 1998bf80f4bSopenharmony_ci } 2008bf80f4bSopenharmony_ci if (AreEqual(t, 1.f)) { 2018bf80f4bSopenharmony_ci return 1; 2028bf80f4bSopenharmony_ci } 2038bf80f4bSopenharmony_ci return BASE_NS::Math::pow(2.f, -10 * t) * BASE_NS::Math::sin((t * 10 - 0.75f) * c4) + 1.f; 2048bf80f4bSopenharmony_ci} 2058bf80f4bSopenharmony_cifloat EaseInOutElastic(float t) 2068bf80f4bSopenharmony_ci{ 2078bf80f4bSopenharmony_ci constexpr float c5 = (2.f * BASE_NS::Math::PI) / 4.5f; 2088bf80f4bSopenharmony_ci if (AreEqual(t, 0.f)) { 2098bf80f4bSopenharmony_ci return 0; 2108bf80f4bSopenharmony_ci } 2118bf80f4bSopenharmony_ci if (AreEqual(t, 1.f)) { 2128bf80f4bSopenharmony_ci return 1; 2138bf80f4bSopenharmony_ci } 2148bf80f4bSopenharmony_ci if (t < 0.5f) { 2158bf80f4bSopenharmony_ci return -(BASE_NS::Math::pow(2.f, 20 * t - 10) * BASE_NS::Math::sin((20 * t - 11.125f) * c5)) / 2.f; 2168bf80f4bSopenharmony_ci } 2178bf80f4bSopenharmony_ci return (BASE_NS::Math::pow(2.f, -20 * t + 10) * BASE_NS::Math::sin((20 * t - 11.125f) * c5)) / 2.f + 1.f; 2188bf80f4bSopenharmony_ci} 2198bf80f4bSopenharmony_cifloat EaseOutBounce(float t) 2208bf80f4bSopenharmony_ci{ 2218bf80f4bSopenharmony_ci constexpr float n1 = 7.5625f; 2228bf80f4bSopenharmony_ci constexpr float d1 = 2.75f; 2238bf80f4bSopenharmony_ci if (t < 1.f / d1) { 2248bf80f4bSopenharmony_ci return n1 * Pow2(t); 2258bf80f4bSopenharmony_ci } 2268bf80f4bSopenharmony_ci if (t < (2.f / d1)) { 2278bf80f4bSopenharmony_ci return n1 * Pow2(t - (1.5f / d1)) + 0.75f; 2288bf80f4bSopenharmony_ci } 2298bf80f4bSopenharmony_ci if (t < (2.5f / d1)) { 2308bf80f4bSopenharmony_ci return n1 * Pow2(t - (2.25f / d1)) + 0.9375f; 2318bf80f4bSopenharmony_ci } 2328bf80f4bSopenharmony_ci return n1 * Pow2(t - (2.625f / d1)) + 0.984375f; 2338bf80f4bSopenharmony_ci} 2348bf80f4bSopenharmony_cifloat EaseInBounce(float t) 2358bf80f4bSopenharmony_ci{ 2368bf80f4bSopenharmony_ci return 1.f - EaseOutBounce(1.f - t); 2378bf80f4bSopenharmony_ci} 2388bf80f4bSopenharmony_cifloat EaseInOutBounce(float t) 2398bf80f4bSopenharmony_ci{ 2408bf80f4bSopenharmony_ci if (t < 0.5f) { 2418bf80f4bSopenharmony_ci return (1.f - EaseOutBounce(1.f - 2.f * t)) / 2.f; 2428bf80f4bSopenharmony_ci } 2438bf80f4bSopenharmony_ci return (1.f + EaseOutBounce(2.f * t - 1.f)) / 2.f; 2448bf80f4bSopenharmony_ci} 2458bf80f4bSopenharmony_cifloat EaseStepStart(float) 2468bf80f4bSopenharmony_ci{ 2478bf80f4bSopenharmony_ci return 1.f; 2488bf80f4bSopenharmony_ci} 2498bf80f4bSopenharmony_cifloat EaseStepEnd(float t) 2508bf80f4bSopenharmony_ci{ 2518bf80f4bSopenharmony_ci return t < 1.f ? 0.f : 1.f; 2528bf80f4bSopenharmony_ci} 2538bf80f4bSopenharmony_ci 2548bf80f4bSopenharmony_ci// Declares the implementation 2558bf80f4bSopenharmony_ci#define IMPLEMENT_EASING_CURVE(name) \ 2568bf80f4bSopenharmony_ci float name##EasingCurve::Transform(float t) const \ 2578bf80f4bSopenharmony_ci { \ 2588bf80f4bSopenharmony_ci return Ease##name(t); \ 2598bf80f4bSopenharmony_ci } 2608bf80f4bSopenharmony_ci 2618bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(Linear) 2628bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InQuad) 2638bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutQuad) 2648bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutQuad) 2658bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InCubic) 2668bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutCubic) 2678bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutCubic) 2688bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InSine) 2698bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutSine) 2708bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutSine) 2718bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InQuart) 2728bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutQuart) 2738bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutQuart) 2748bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InQuint) 2758bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutQuint) 2768bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutQuint) 2778bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InExpo) 2788bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutExpo) 2798bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutExpo) 2808bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InCirc) 2818bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutCirc) 2828bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutCirc) 2838bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InBack) 2848bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutBack) 2858bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutBack) 2868bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InElastic) 2878bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutElastic) 2888bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutElastic) 2898bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InBounce) 2908bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(OutBounce) 2918bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(InOutBounce) 2928bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(StepStart) 2938bf80f4bSopenharmony_ciIMPLEMENT_EASING_CURVE(StepEnd) 2948bf80f4bSopenharmony_ci 2958bf80f4bSopenharmony_ci} // namespace Easing 2968bf80f4bSopenharmony_ci} // namespace Curves 2978bf80f4bSopenharmony_ci 2988bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 299