1a3e0fd82Sopenharmony_ci/* 2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd. 3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License. 5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at 6a3e0fd82Sopenharmony_ci * 7a3e0fd82Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a3e0fd82Sopenharmony_ci * 9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and 13a3e0fd82Sopenharmony_ci * limitations under the License. 14a3e0fd82Sopenharmony_ci */ 15a3e0fd82Sopenharmony_ci 16a3e0fd82Sopenharmony_ci#include "animator/easing_equation.h" 17a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_math.h" 18a3e0fd82Sopenharmony_ci 19a3e0fd82Sopenharmony_cinamespace OHOS { 20a3e0fd82Sopenharmony_cidouble EasingEquation::overshoot_ = 1.7; // The empirical value commonly used in easing equation 21a3e0fd82Sopenharmony_ci 22a3e0fd82Sopenharmony_civoid EasingEquation::SetBackOvershoot(double overshoot) 23a3e0fd82Sopenharmony_ci{ 24a3e0fd82Sopenharmony_ci if ((overshoot >= OVERSHOOT_MIN) && (overshoot <= OVERSHOOT_MAX)) { 25a3e0fd82Sopenharmony_ci overshoot_ = overshoot; 26a3e0fd82Sopenharmony_ci } 27a3e0fd82Sopenharmony_ci} 28a3e0fd82Sopenharmony_ci 29a3e0fd82Sopenharmony_ciint16_t EasingEquation::BackEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 30a3e0fd82Sopenharmony_ci{ 31a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 32a3e0fd82Sopenharmony_ci double t = -(static_cast<double>(curTime) / durationTime); 33a3e0fd82Sopenharmony_ci double x = -t * t * ((overshoot_ + 1) * t + overshoot_); 34a3e0fd82Sopenharmony_ci return static_cast<int16_t>((x * (static_cast<int32_t>(endPos) - startPos)) + startPos); 35a3e0fd82Sopenharmony_ci } 36a3e0fd82Sopenharmony_ci 37a3e0fd82Sopenharmony_ci return endPos; 38a3e0fd82Sopenharmony_ci} 39a3e0fd82Sopenharmony_ci 40a3e0fd82Sopenharmony_ciint16_t EasingEquation::BackEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 41a3e0fd82Sopenharmony_ci{ 42a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 43a3e0fd82Sopenharmony_ci double t = static_cast<double>(curTime) / durationTime; 44a3e0fd82Sopenharmony_ci t -= 1.0; 45a3e0fd82Sopenharmony_ci double x = t * t * ((overshoot_ + 1) * t + overshoot_) + 1; 46a3e0fd82Sopenharmony_ci return static_cast<int16_t>((x * (static_cast<int32_t>(endPos) - startPos)) + startPos); 47a3e0fd82Sopenharmony_ci } 48a3e0fd82Sopenharmony_ci 49a3e0fd82Sopenharmony_ci return endPos; 50a3e0fd82Sopenharmony_ci} 51a3e0fd82Sopenharmony_ci 52a3e0fd82Sopenharmony_ciint16_t EasingEquation::BackEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 53a3e0fd82Sopenharmony_ci{ 54a3e0fd82Sopenharmony_ci uint16_t halfTime = durationTime >> 1; 55a3e0fd82Sopenharmony_ci int16_t halfStep = (endPos >> 1) + (startPos >> 1); 56a3e0fd82Sopenharmony_ci if (curTime < halfTime) { 57a3e0fd82Sopenharmony_ci return BackEaseIn(startPos, halfStep, curTime, halfTime); 58a3e0fd82Sopenharmony_ci } 59a3e0fd82Sopenharmony_ci return BackEaseOut(halfStep, endPos, curTime - halfTime, halfTime); 60a3e0fd82Sopenharmony_ci} 61a3e0fd82Sopenharmony_ci 62a3e0fd82Sopenharmony_ci/* 1 - sqrt(1 - t^2) */ 63a3e0fd82Sopenharmony_ciint16_t EasingEquation::CircEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 64a3e0fd82Sopenharmony_ci{ 65a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 66a3e0fd82Sopenharmony_ci int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 67a3e0fd82Sopenharmony_ci uint32_t x = INTERPOLATION_RANGE - static_cast<int32_t>(Sqrt(INTERPOLATION_RANGE_SQUARE - t * t)); 68a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 69a3e0fd82Sopenharmony_ci startPos); 70a3e0fd82Sopenharmony_ci } 71a3e0fd82Sopenharmony_ci 72a3e0fd82Sopenharmony_ci return endPos; 73a3e0fd82Sopenharmony_ci} 74a3e0fd82Sopenharmony_ci 75a3e0fd82Sopenharmony_ci/* sqrt(1 - (1 - t)^2) */ 76a3e0fd82Sopenharmony_ciint16_t EasingEquation::CircEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 77a3e0fd82Sopenharmony_ci{ 78a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 79a3e0fd82Sopenharmony_ci int32_t t = INTERPOLATION_RANGE - (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 80a3e0fd82Sopenharmony_ci uint32_t x = static_cast<uint32_t>(Sqrt(INTERPOLATION_RANGE_SQUARE - t * t)); 81a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 82a3e0fd82Sopenharmony_ci startPos); 83a3e0fd82Sopenharmony_ci } 84a3e0fd82Sopenharmony_ci 85a3e0fd82Sopenharmony_ci return endPos; 86a3e0fd82Sopenharmony_ci} 87a3e0fd82Sopenharmony_ci 88a3e0fd82Sopenharmony_ciint16_t EasingEquation::CircEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 89a3e0fd82Sopenharmony_ci{ 90a3e0fd82Sopenharmony_ci uint16_t halfTime = durationTime >> 1; 91a3e0fd82Sopenharmony_ci int16_t halfStep = (endPos >> 1) + (startPos >> 1); 92a3e0fd82Sopenharmony_ci if (curTime < halfTime) { 93a3e0fd82Sopenharmony_ci return CircEaseIn(startPos, halfStep, curTime, halfTime); 94a3e0fd82Sopenharmony_ci } 95a3e0fd82Sopenharmony_ci return CircEaseOut(halfStep, endPos, curTime - halfTime, halfTime); 96a3e0fd82Sopenharmony_ci} 97a3e0fd82Sopenharmony_ci 98a3e0fd82Sopenharmony_ci/* t^3 */ 99a3e0fd82Sopenharmony_ciint16_t EasingEquation::CubicEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 100a3e0fd82Sopenharmony_ci{ 101a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 102a3e0fd82Sopenharmony_ci int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 103a3e0fd82Sopenharmony_ci int16_t x = (t * t * t) >> (INTERPOLATION_RANGE_OFFSET << 1); 104a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 105a3e0fd82Sopenharmony_ci startPos); 106a3e0fd82Sopenharmony_ci } 107a3e0fd82Sopenharmony_ci 108a3e0fd82Sopenharmony_ci return endPos; 109a3e0fd82Sopenharmony_ci} 110a3e0fd82Sopenharmony_ci 111a3e0fd82Sopenharmony_ci/* 1 - (1 - t)^3 */ 112a3e0fd82Sopenharmony_ciint16_t EasingEquation::CubicEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 113a3e0fd82Sopenharmony_ci{ 114a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 115a3e0fd82Sopenharmony_ci int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 116a3e0fd82Sopenharmony_ci t = INTERPOLATION_RANGE - t; 117a3e0fd82Sopenharmony_ci int16_t x = INTERPOLATION_RANGE - ((t * t * t) >> (INTERPOLATION_RANGE_OFFSET << 1)); 118a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 119a3e0fd82Sopenharmony_ci startPos); 120a3e0fd82Sopenharmony_ci } 121a3e0fd82Sopenharmony_ci 122a3e0fd82Sopenharmony_ci return endPos; 123a3e0fd82Sopenharmony_ci} 124a3e0fd82Sopenharmony_ci 125a3e0fd82Sopenharmony_ciint16_t EasingEquation::CubicEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 126a3e0fd82Sopenharmony_ci{ 127a3e0fd82Sopenharmony_ci uint16_t halfTime = durationTime >> 1; 128a3e0fd82Sopenharmony_ci int16_t halfStep = (endPos >> 1) + (startPos >> 1); 129a3e0fd82Sopenharmony_ci if (curTime < halfTime) { 130a3e0fd82Sopenharmony_ci return CubicEaseIn(startPos, halfStep, curTime, halfTime); 131a3e0fd82Sopenharmony_ci } 132a3e0fd82Sopenharmony_ci return CubicEaseOut(halfStep, endPos, curTime - halfTime, halfTime); 133a3e0fd82Sopenharmony_ci} 134a3e0fd82Sopenharmony_ci 135a3e0fd82Sopenharmony_ciint16_t EasingEquation::LinearEaseNone(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 136a3e0fd82Sopenharmony_ci{ 137a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 138a3e0fd82Sopenharmony_ci int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 139a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((t * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 140a3e0fd82Sopenharmony_ci startPos); 141a3e0fd82Sopenharmony_ci } 142a3e0fd82Sopenharmony_ci 143a3e0fd82Sopenharmony_ci return endPos; 144a3e0fd82Sopenharmony_ci} 145a3e0fd82Sopenharmony_ci 146a3e0fd82Sopenharmony_ci/* t^2 */ 147a3e0fd82Sopenharmony_ciint16_t EasingEquation::QuadEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 148a3e0fd82Sopenharmony_ci{ 149a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 150a3e0fd82Sopenharmony_ci int32_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 151a3e0fd82Sopenharmony_ci int16_t x = (t * t) >> INTERPOLATION_RANGE_OFFSET; 152a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 153a3e0fd82Sopenharmony_ci startPos); 154a3e0fd82Sopenharmony_ci } 155a3e0fd82Sopenharmony_ci 156a3e0fd82Sopenharmony_ci return endPos; 157a3e0fd82Sopenharmony_ci} 158a3e0fd82Sopenharmony_ci 159a3e0fd82Sopenharmony_ci/* 1 - (1 - t)^2 */ 160a3e0fd82Sopenharmony_ciint16_t EasingEquation::QuadEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 161a3e0fd82Sopenharmony_ci{ 162a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 163a3e0fd82Sopenharmony_ci int32_t t = INTERPOLATION_RANGE - (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 164a3e0fd82Sopenharmony_ci int16_t x = INTERPOLATION_RANGE - ((t * t) >> INTERPOLATION_RANGE_OFFSET); 165a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 166a3e0fd82Sopenharmony_ci startPos); 167a3e0fd82Sopenharmony_ci } 168a3e0fd82Sopenharmony_ci 169a3e0fd82Sopenharmony_ci return endPos; 170a3e0fd82Sopenharmony_ci} 171a3e0fd82Sopenharmony_ci 172a3e0fd82Sopenharmony_ciint16_t EasingEquation::QuadEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 173a3e0fd82Sopenharmony_ci{ 174a3e0fd82Sopenharmony_ci uint16_t halfTime = durationTime >> 1; 175a3e0fd82Sopenharmony_ci int16_t halfStep = (endPos >> 1) + (startPos >> 1); 176a3e0fd82Sopenharmony_ci if (curTime < halfTime) { 177a3e0fd82Sopenharmony_ci return QuadEaseIn(startPos, halfStep, curTime, halfTime); 178a3e0fd82Sopenharmony_ci } 179a3e0fd82Sopenharmony_ci return QuadEaseOut(halfStep, endPos, curTime - halfTime, halfTime); 180a3e0fd82Sopenharmony_ci} 181a3e0fd82Sopenharmony_ci 182a3e0fd82Sopenharmony_ci/* t^5 */ 183a3e0fd82Sopenharmony_ciint16_t EasingEquation::QuintEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 184a3e0fd82Sopenharmony_ci{ 185a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 186a3e0fd82Sopenharmony_ci int64_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 187a3e0fd82Sopenharmony_ci 188a3e0fd82Sopenharmony_ci /* 4: the fourth power of t */ 189a3e0fd82Sopenharmony_ci int16_t x = (t * t * t * t * t) >> (INTERPOLATION_RANGE_OFFSET * 4); 190a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 191a3e0fd82Sopenharmony_ci startPos); 192a3e0fd82Sopenharmony_ci } 193a3e0fd82Sopenharmony_ci 194a3e0fd82Sopenharmony_ci return endPos; 195a3e0fd82Sopenharmony_ci} 196a3e0fd82Sopenharmony_ci 197a3e0fd82Sopenharmony_ci/* 1 - (1 - t)^5 */ 198a3e0fd82Sopenharmony_ciint16_t EasingEquation::QuintEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 199a3e0fd82Sopenharmony_ci{ 200a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 201a3e0fd82Sopenharmony_ci int64_t t = (curTime << INTERPOLATION_RANGE_OFFSET) / durationTime; 202a3e0fd82Sopenharmony_ci t = INTERPOLATION_RANGE - t; 203a3e0fd82Sopenharmony_ci 204a3e0fd82Sopenharmony_ci /* 4: the fourth power of t */ 205a3e0fd82Sopenharmony_ci int16_t x = INTERPOLATION_RANGE - ((t * t * t * t * t) >> (INTERPOLATION_RANGE_OFFSET * 4)); 206a3e0fd82Sopenharmony_ci return static_cast<int16_t>(((x * (static_cast<int32_t>(endPos) - startPos)) >> INTERPOLATION_RANGE_OFFSET) + 207a3e0fd82Sopenharmony_ci startPos); 208a3e0fd82Sopenharmony_ci } 209a3e0fd82Sopenharmony_ci 210a3e0fd82Sopenharmony_ci return endPos; 211a3e0fd82Sopenharmony_ci} 212a3e0fd82Sopenharmony_ci 213a3e0fd82Sopenharmony_ciint16_t EasingEquation::QuintEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 214a3e0fd82Sopenharmony_ci{ 215a3e0fd82Sopenharmony_ci uint16_t halfTime = durationTime >> 1; 216a3e0fd82Sopenharmony_ci int16_t halfStep = (endPos >> 1) + (startPos >> 1); 217a3e0fd82Sopenharmony_ci if (curTime < halfTime) { 218a3e0fd82Sopenharmony_ci return QuintEaseIn(startPos, halfStep, curTime, halfTime); 219a3e0fd82Sopenharmony_ci } 220a3e0fd82Sopenharmony_ci return QuintEaseOut(halfStep, endPos, curTime - halfTime, halfTime); 221a3e0fd82Sopenharmony_ci} 222a3e0fd82Sopenharmony_ci 223a3e0fd82Sopenharmony_ciint16_t EasingEquation::SineEaseIn(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 224a3e0fd82Sopenharmony_ci{ 225a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 226a3e0fd82Sopenharmony_ci int16_t t = (curTime * QUARTER_IN_DEGREE) / durationTime - QUARTER_IN_DEGREE; 227a3e0fd82Sopenharmony_ci float x = Sin(t) + 1; 228a3e0fd82Sopenharmony_ci return static_cast<int16_t>(x * (endPos - startPos)) + startPos; 229a3e0fd82Sopenharmony_ci } 230a3e0fd82Sopenharmony_ci 231a3e0fd82Sopenharmony_ci return endPos; 232a3e0fd82Sopenharmony_ci} 233a3e0fd82Sopenharmony_ci 234a3e0fd82Sopenharmony_ciint16_t EasingEquation::SineEaseOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 235a3e0fd82Sopenharmony_ci{ 236a3e0fd82Sopenharmony_ci if (curTime < durationTime) { 237a3e0fd82Sopenharmony_ci int16_t t = (curTime * QUARTER_IN_DEGREE) / durationTime; 238a3e0fd82Sopenharmony_ci float x = Sin(t); 239a3e0fd82Sopenharmony_ci return static_cast<int16_t>(x * (endPos - startPos)) + startPos; 240a3e0fd82Sopenharmony_ci } 241a3e0fd82Sopenharmony_ci 242a3e0fd82Sopenharmony_ci return endPos; 243a3e0fd82Sopenharmony_ci} 244a3e0fd82Sopenharmony_ci 245a3e0fd82Sopenharmony_ciint16_t EasingEquation::SineEaseInOut(int16_t startPos, int16_t endPos, uint16_t curTime, uint16_t durationTime) 246a3e0fd82Sopenharmony_ci{ 247a3e0fd82Sopenharmony_ci uint16_t halfTime = durationTime >> 1; 248a3e0fd82Sopenharmony_ci int16_t halfStep = (endPos >> 1) + (startPos >> 1); 249a3e0fd82Sopenharmony_ci if (curTime < halfTime) { 250a3e0fd82Sopenharmony_ci return SineEaseIn(startPos, halfStep, curTime, halfTime); 251a3e0fd82Sopenharmony_ci } 252a3e0fd82Sopenharmony_ci return SineEaseOut(halfStep, endPos, curTime - halfTime, halfTime); 253a3e0fd82Sopenharmony_ci} 254a3e0fd82Sopenharmony_ci} // namespace OHOS 255