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