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 19META_BEGIN_NAMESPACE() 20 21namespace Curves { 22namespace Easing { 23 24bool AreEqual(float v1, float v2) 25{ 26 return BASE_NS::Math::abs(v1 - v2) < BASE_NS::Math::EPSILON; 27} 28float Pow2(float v) 29{ 30 return v * v; 31} 32float Pow3(float v) 33{ 34 return v * v * v; 35} 36float Pow4(float v) 37{ 38 return v * v * v * v; 39} 40float Pow5(float v) 41{ 42 return v * v * v * v * v; 43} 44float EaseLinear(float t) 45{ 46 return t; 47} 48float EaseInSine(float t) 49{ 50 return 1.f - BASE_NS::Math::cos((t * BASE_NS::Math::PI) / 2.f); 51} 52float EaseOutSine(float t) 53{ 54 return BASE_NS::Math::sin((t * BASE_NS::Math::PI) / 2.f); 55} 56float EaseInOutSine(float t) 57{ 58 return -(BASE_NS::Math::cos(BASE_NS::Math::PI * t) - 1.f) / 2.f; 59} 60float EaseInQuad(float t) 61{ 62 return Pow2(t); 63} 64float EaseOutQuad(float t) 65{ 66 return 1.f - Pow2(1.f - t); 67} 68float 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} 75float EaseInCubic(float t) 76{ 77 return Pow3(t); 78} 79float EaseOutCubic(float t) 80{ 81 return 1.f - Pow3(1.f - t); 82} 83float 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} 90float EaseInQuart(float t) 91{ 92 return Pow4(t); 93} 94float EaseOutQuart(float t) 95{ 96 return 1.f - Pow4(1.f - t); 97} 98float 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} 105float EaseInQuint(float t) 106{ 107 return Pow5(t); 108} 109float EaseOutQuint(float t) 110{ 111 return 1.f - Pow5(1.f - t); 112} 113float 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} 120float 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} 127float 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} 134float 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} 147float EaseInCirc(float t) 148{ 149 return 1.f - BASE_NS::Math::sqrt(1.f - Pow2(t)); 150} 151float EaseOutCirc(float t) 152{ 153 return BASE_NS::Math::sqrt(1.f - Pow2(t - 1.f)); 154} 155float 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} 162float 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} 168float 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} 174float 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} 183float 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} 194float 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} 205float 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} 219float 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} 234float EaseInBounce(float t) 235{ 236 return 1.f - EaseOutBounce(1.f - t); 237} 238float 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} 245float EaseStepStart(float) 246{ 247 return 1.f; 248} 249float 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 261IMPLEMENT_EASING_CURVE(Linear) 262IMPLEMENT_EASING_CURVE(InQuad) 263IMPLEMENT_EASING_CURVE(OutQuad) 264IMPLEMENT_EASING_CURVE(InOutQuad) 265IMPLEMENT_EASING_CURVE(InCubic) 266IMPLEMENT_EASING_CURVE(OutCubic) 267IMPLEMENT_EASING_CURVE(InOutCubic) 268IMPLEMENT_EASING_CURVE(InSine) 269IMPLEMENT_EASING_CURVE(OutSine) 270IMPLEMENT_EASING_CURVE(InOutSine) 271IMPLEMENT_EASING_CURVE(InQuart) 272IMPLEMENT_EASING_CURVE(OutQuart) 273IMPLEMENT_EASING_CURVE(InOutQuart) 274IMPLEMENT_EASING_CURVE(InQuint) 275IMPLEMENT_EASING_CURVE(OutQuint) 276IMPLEMENT_EASING_CURVE(InOutQuint) 277IMPLEMENT_EASING_CURVE(InExpo) 278IMPLEMENT_EASING_CURVE(OutExpo) 279IMPLEMENT_EASING_CURVE(InOutExpo) 280IMPLEMENT_EASING_CURVE(InCirc) 281IMPLEMENT_EASING_CURVE(OutCirc) 282IMPLEMENT_EASING_CURVE(InOutCirc) 283IMPLEMENT_EASING_CURVE(InBack) 284IMPLEMENT_EASING_CURVE(OutBack) 285IMPLEMENT_EASING_CURVE(InOutBack) 286IMPLEMENT_EASING_CURVE(InElastic) 287IMPLEMENT_EASING_CURVE(OutElastic) 288IMPLEMENT_EASING_CURVE(InOutElastic) 289IMPLEMENT_EASING_CURVE(InBounce) 290IMPLEMENT_EASING_CURVE(OutBounce) 291IMPLEMENT_EASING_CURVE(InOutBounce) 292IMPLEMENT_EASING_CURVE(StepStart) 293IMPLEMENT_EASING_CURVE(StepEnd) 294 295} // namespace Easing 296} // namespace Curves 297 298META_END_NAMESPACE() 299