/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "easing_curve.h" #include META_BEGIN_NAMESPACE() namespace Curves { namespace Easing { bool AreEqual(float v1, float v2) { return BASE_NS::Math::abs(v1 - v2) < BASE_NS::Math::EPSILON; } float Pow2(float v) { return v * v; } float Pow3(float v) { return v * v * v; } float Pow4(float v) { return v * v * v * v; } float Pow5(float v) { return v * v * v * v * v; } float EaseLinear(float t) { return t; } float EaseInSine(float t) { return 1.f - BASE_NS::Math::cos((t * BASE_NS::Math::PI) / 2.f); } float EaseOutSine(float t) { return BASE_NS::Math::sin((t * BASE_NS::Math::PI) / 2.f); } float EaseInOutSine(float t) { return -(BASE_NS::Math::cos(BASE_NS::Math::PI * t) - 1.f) / 2.f; } float EaseInQuad(float t) { return Pow2(t); } float EaseOutQuad(float t) { return 1.f - Pow2(1.f - t); } float EaseInOutQuad(float t) { if (t < 0.5f) { return 2 * t * t; } return 1.f - (Pow2(-2.f * t + 2.f) / 2.f); } float EaseInCubic(float t) { return Pow3(t); } float EaseOutCubic(float t) { return 1.f - Pow3(1.f - t); } float EaseInOutCubic(float t) { if (t < 0.5f) { return 4 * t * t * t; } return 1.f - (Pow3(-2.f * t + 2.f) / 2.f); } float EaseInQuart(float t) { return Pow4(t); } float EaseOutQuart(float t) { return 1.f - Pow4(1.f - t); } float EaseInOutQuart(float t) { if (t < 0.5f) { return 8 * Pow4(t); } return 1.f - (Pow4(-2.f * t + 2.f) / 2.f); } float EaseInQuint(float t) { return Pow5(t); } float EaseOutQuint(float t) { return 1.f - Pow5(1.f - t); } float EaseInOutQuint(float t) { if (t < 0.5f) { return 16 * Pow5(t); } return 1.f - (Pow5(-2.f * t + 2.f) / 2.f); } float EaseInExpo(float t) { if (AreEqual(t, 0.f)) { return 0; } return BASE_NS::Math::pow(2.f, 10 * t - 10); } float EaseOutExpo(float t) { if (AreEqual(t, 1.f)) { return 1; } return 1.f - BASE_NS::Math::pow(2.f, -10 * t); } float EaseInOutExpo(float t) { if (AreEqual(t, 0.f)) { return 0.f; } if (AreEqual(t, 1.f)) { return 1.f; } if (t < .5f) { return BASE_NS::Math::pow(2.f, 20 * t - 10) / 2.f; } return (2.f - BASE_NS::Math::pow(2.f, -20 * t + 10)) / 2.f; } float EaseInCirc(float t) { return 1.f - BASE_NS::Math::sqrt(1.f - Pow2(t)); } float EaseOutCirc(float t) { return BASE_NS::Math::sqrt(1.f - Pow2(t - 1.f)); } float EaseInOutCirc(float t) { if (t < 0.5f) { return (1.f - BASE_NS::Math::sqrt(1.f - Pow2(2.f * t))) / 2.f; } return (BASE_NS::Math::sqrt(1.f - Pow2(-2.f * t + 2.f)) + 1.f) / 2.f; } float EaseInBack(float t) { constexpr float c1 = 1.70158f; constexpr float c3 = c1 + 1.f; return c3 * Pow3(t) - c1 * Pow2(t); } float EaseOutBack(float t) { constexpr float c1 = 1.70158f; constexpr float c3 = c1 + 1.f; return 1.f + c3 * Pow3(t - 1.f) + c1 * Pow2(t - 1.f); } float EaseInOutBack(float t) { constexpr float c1 = 1.70158f; constexpr float c2 = c1 * 1.525f; if (t < 0.5f) { return (Pow2(2.f * t) * ((c2 + 1.f) * 2.f * t - c2)) / 2.f; } return (Pow2(2.f * t - 2.f) * ((c2 + 1.f) * (t * 2.f - 2.f) + c2) + 2.f) / 2.f; } float EaseInElastic(float t) { constexpr float c4 = (2.f * BASE_NS::Math::PI) / 3.f; if (AreEqual(t, 0.f)) { return 0; } if (AreEqual(t, 1.f)) { return 1; } return -BASE_NS::Math::pow(2.f, 10 * t - 10) * BASE_NS::Math::sin((t * 10 - 10.75f) * c4); } float EaseOutElastic(float t) { constexpr float c4 = (2.f * BASE_NS::Math::PI) / 3.f; if (AreEqual(t, 0.f)) { return 0; } if (AreEqual(t, 1.f)) { return 1; } return BASE_NS::Math::pow(2.f, -10 * t) * BASE_NS::Math::sin((t * 10 - 0.75f) * c4) + 1.f; } float EaseInOutElastic(float t) { constexpr float c5 = (2.f * BASE_NS::Math::PI) / 4.5f; if (AreEqual(t, 0.f)) { return 0; } if (AreEqual(t, 1.f)) { return 1; } if (t < 0.5f) { return -(BASE_NS::Math::pow(2.f, 20 * t - 10) * BASE_NS::Math::sin((20 * t - 11.125f) * c5)) / 2.f; } return (BASE_NS::Math::pow(2.f, -20 * t + 10) * BASE_NS::Math::sin((20 * t - 11.125f) * c5)) / 2.f + 1.f; } float EaseOutBounce(float t) { constexpr float n1 = 7.5625f; constexpr float d1 = 2.75f; if (t < 1.f / d1) { return n1 * Pow2(t); } if (t < (2.f / d1)) { return n1 * Pow2(t - (1.5f / d1)) + 0.75f; } if (t < (2.5f / d1)) { return n1 * Pow2(t - (2.25f / d1)) + 0.9375f; } return n1 * Pow2(t - (2.625f / d1)) + 0.984375f; } float EaseInBounce(float t) { return 1.f - EaseOutBounce(1.f - t); } float EaseInOutBounce(float t) { if (t < 0.5f) { return (1.f - EaseOutBounce(1.f - 2.f * t)) / 2.f; } return (1.f + EaseOutBounce(2.f * t - 1.f)) / 2.f; } float EaseStepStart(float) { return 1.f; } float EaseStepEnd(float t) { return t < 1.f ? 0.f : 1.f; } // Declares the implementation #define IMPLEMENT_EASING_CURVE(name) \ float name##EasingCurve::Transform(float t) const \ { \ return Ease##name(t); \ } IMPLEMENT_EASING_CURVE(Linear) IMPLEMENT_EASING_CURVE(InQuad) IMPLEMENT_EASING_CURVE(OutQuad) IMPLEMENT_EASING_CURVE(InOutQuad) IMPLEMENT_EASING_CURVE(InCubic) IMPLEMENT_EASING_CURVE(OutCubic) IMPLEMENT_EASING_CURVE(InOutCubic) IMPLEMENT_EASING_CURVE(InSine) IMPLEMENT_EASING_CURVE(OutSine) IMPLEMENT_EASING_CURVE(InOutSine) IMPLEMENT_EASING_CURVE(InQuart) IMPLEMENT_EASING_CURVE(OutQuart) IMPLEMENT_EASING_CURVE(InOutQuart) IMPLEMENT_EASING_CURVE(InQuint) IMPLEMENT_EASING_CURVE(OutQuint) IMPLEMENT_EASING_CURVE(InOutQuint) IMPLEMENT_EASING_CURVE(InExpo) IMPLEMENT_EASING_CURVE(OutExpo) IMPLEMENT_EASING_CURVE(InOutExpo) IMPLEMENT_EASING_CURVE(InCirc) IMPLEMENT_EASING_CURVE(OutCirc) IMPLEMENT_EASING_CURVE(InOutCirc) IMPLEMENT_EASING_CURVE(InBack) IMPLEMENT_EASING_CURVE(OutBack) IMPLEMENT_EASING_CURVE(InOutBack) IMPLEMENT_EASING_CURVE(InElastic) IMPLEMENT_EASING_CURVE(OutElastic) IMPLEMENT_EASING_CURVE(InOutElastic) IMPLEMENT_EASING_CURVE(InBounce) IMPLEMENT_EASING_CURVE(OutBounce) IMPLEMENT_EASING_CURVE(InOutBounce) IMPLEMENT_EASING_CURVE(StepStart) IMPLEMENT_EASING_CURVE(StepEnd) } // namespace Easing } // namespace Curves META_END_NAMESPACE()