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 16#include "node/animate_impl.h" 17 18#include "node/node_model.h" 19 20#include "base/error/error_code.h" 21 22namespace OHOS::Ace::AnimateModel { 23 24int32_t AnimateTo(ArkUI_ContextHandle context, ArkUI_AnimateOption* option, ArkUI_ContextCallback* update, 25 ArkUI_AnimateCompleteCallback* complete) 26{ 27 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 28 if (!impl || !context || !option || !update || !update->callback) { 29 return ERROR_CODE_PARAM_INVALID; 30 } 31 32 ArkUIAnimateOption animateOption {}; 33 animateOption.duration = option->duration; 34 animateOption.tempo = option->tempo; 35 animateOption.curve = static_cast<ArkUI_Int32>(option->curve); 36 animateOption.delay = option->delay; 37 animateOption.iterations = option->iterations; 38 if (option->iCurve) { 39 animateOption.iCurve = option->iCurve->curve; 40 animateOption.curveType = option->iCurve->baseCurveType; 41 } 42 animateOption.playMode = static_cast<ArkUI_Int32>(option->playMode); 43 if (option->expectedFrameRateRange) { 44 animateOption.expectedFrameRateRange = 45 reinterpret_cast<ArkUIExpectedFrameRateRange*>(option->expectedFrameRateRange); 46 } 47 48 if (complete && complete->callback) { 49 animateOption.onFinishCallback = reinterpret_cast<void*>(complete->callback); 50 } 51 52 if (complete && complete->userData) { 53 animateOption.user = complete->userData; 54 } 55 auto finishCallbackType = static_cast<ArkUI_Int32>(ARKUI_FINISH_CALLBACK_REMOVED); 56 if (complete && complete->type == ARKUI_FINISH_CALLBACK_LOGICALLY) { 57 finishCallbackType = static_cast<ArkUI_Int32>(ARKUI_FINISH_CALLBACK_LOGICALLY); 58 } 59 animateOption.finishCallbackType = finishCallbackType; 60 61 impl->getAnimation()->animateTo(reinterpret_cast<ArkUIContext*>(context), animateOption, 62 reinterpret_cast<void*>(update->callback), update->userData); 63 return ERROR_CODE_NO_ERROR; 64} 65 66int32_t KeyframeAnimateTo(ArkUI_ContextHandle context, ArkUI_KeyframeAnimateOption* option) 67{ 68 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 69 if (!impl || !context || !option || option->keyframes.size() == 0) { 70 return ERROR_CODE_PARAM_INVALID; 71 } 72 73 ArkUIKeyframeAnimateOption animateOption {}; 74 animateOption.delay = option->delay; 75 animateOption.iterations = option->iterations; 76 animateOption.onFinish = option->onFinish; 77 animateOption.userData = option->userData; 78 ArkUIKeyframeState keyframes[option->keyframes.size()]; 79 for (size_t i = 0; i < option->keyframes.size(); i++) { 80 keyframes[i].duration = option->keyframes[i].duration; 81 keyframes[i].event = option->keyframes[i].event; 82 keyframes[i].userData = option->keyframes[i].userData; 83 84 auto curve = option->keyframes[i].curve; 85 if (!curve) { 86 continue; 87 } 88 //不支持当前curve 89 if (curve->type == ARKUI_CURVE_TYPE_SPRING_MOTION || curve->type == ARKUI_CURVE_TYPE_RESPONSIVE_SPRING_MOTION || 90 curve->type == ARKUI_CURVE_TYPE_INTERPOLATING_SPRING) { 91 continue; 92 } 93 keyframes[i].curve = curve->curve; 94 keyframes[i].curveType = curve->type; 95 } 96 animateOption.keyframes = keyframes; 97 animateOption.keyframeSize = static_cast<int32_t>(option->keyframes.size()); 98 99 impl->getAnimation()->keyframeAnimateTo(reinterpret_cast<ArkUIContext*>(context), &animateOption); 100 return ERROR_CODE_NO_ERROR; 101} 102 103ArkUIAnimatorOption* ConvertAnimatorOption(ArkUI_AnimatorOption* option) 104{ 105 ArkUIAnimatorOption* animatorOption = new ArkUIAnimatorOption; 106 animatorOption->duration = option->duration; 107 animatorOption->delay = option->delay; 108 animatorOption->iterations = option->iterations; 109 animatorOption->begin = option->begin; 110 animatorOption->end = option->end; 111 animatorOption->fill = option->fill; 112 animatorOption->direction = option->direction; 113 if (option->easing) { 114 animatorOption->easing = option->easing->curve; 115 animatorOption->curveType = option->easing->type; 116 } else { 117 animatorOption->easing = nullptr; 118 } 119 120 if (option->expectedFrameRateRange) { 121 animatorOption->isHasExpectedFrameRateRange = 1; 122 animatorOption->expectedFrameRateRange = { option->expectedFrameRateRange->min, 123 option->expectedFrameRateRange->max, option->expectedFrameRateRange->expected }; 124 } else { 125 animatorOption->isHasExpectedFrameRateRange = 0; 126 } 127 128 int32_t keyframeSize = static_cast<int32_t>(option->keyframes.size()); 129 if (keyframeSize > 0) { 130 animatorOption->keyframes = new ArkUIKeyframe[keyframeSize]; 131 for (int32_t i = 0; i < keyframeSize; ++i) { 132 animatorOption->keyframes[i].keyTime = option->keyframes[i].keyTime; 133 animatorOption->keyframes[i].keyValue = option->keyframes[i].keyValue; 134 if (option->keyframes[i].curve) { 135 animatorOption->keyframes[i].curve = option->keyframes[i].curve->curve; 136 animatorOption->keyframes[i].curveType = option->keyframes[i].curve->type; 137 } else { 138 animatorOption->keyframes[i].curve = nullptr; 139 animatorOption->keyframes[i].curveType = 0; // 默认或无效的曲线类型 140 } 141 } 142 } else { 143 animatorOption->keyframes = nullptr; 144 } 145 animatorOption->keyframeSize = keyframeSize; 146 147 animatorOption->onFrame = option->onFrame; 148 animatorOption->onFinish = option->onFinish; 149 animatorOption->onCancel = option->onCancel; 150 animatorOption->onRepeat = option->onRepeat; 151 152 animatorOption->frameUserData = option->frameUserData; 153 animatorOption->finishUserData = option->finishUserData; 154 animatorOption->cancelUserData = option->cancelUserData; 155 animatorOption->repeatUserData = option->repeatUserData; 156 return animatorOption; 157} 158 159ArkUI_AnimatorHandle CreateAnimator(ArkUI_ContextHandle context, ArkUI_AnimatorOption* option) 160{ 161 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 162 if (!impl || !context || !option) { 163 return nullptr; 164 } 165 166 auto animatorOption = ConvertAnimatorOption(option); 167 auto animator = impl->getAnimation()->createAnimator(reinterpret_cast<ArkUIContext*>(context), animatorOption); 168 ArkUI_Animator* animatorHandle = new ArkUI_Animator { animator, option, animatorOption }; 169 return animatorHandle; 170} 171 172void DisposeAnimator(ArkUI_AnimatorHandle animatorHandle) 173{ 174 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 175 if (!animatorHandle || !animatorHandle->animator) { 176 return; 177 } 178 impl->getAnimation()->disposeAnimator(animatorHandle->animator); 179 if (animatorHandle->animatorOption) { 180 auto* animatorOption = reinterpret_cast<ArkUIAnimatorOption*>(animatorHandle->animatorOption); 181 if (animatorOption->keyframes) { 182 delete[] animatorOption->keyframes; 183 animatorOption->keyframes = nullptr; 184 } 185 delete animatorOption; 186 animatorHandle->animatorOption = nullptr; 187 } 188 delete animatorHandle; 189} 190 191int32_t AnimatorReset(ArkUI_AnimatorHandle animatorHandle, ArkUI_AnimatorOption* option) 192{ 193 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 194 if (!impl || !animatorHandle || !animatorHandle->animator || !option) { 195 return ERROR_CODE_PARAM_INVALID; 196 } 197 198 auto animatorOption = ConvertAnimatorOption(option); 199 impl->getAnimation()->animatorReset(animatorHandle->animator, animatorOption); 200 if (animatorHandle->animatorOption) { 201 auto* animatorOption = reinterpret_cast<ArkUIAnimatorOption*>(animatorHandle->animatorOption); 202 if (animatorOption->keyframes) { 203 delete[] animatorOption->keyframes; 204 animatorOption->keyframes = nullptr; 205 } 206 delete animatorOption; 207 animatorHandle->animatorOption = nullptr; 208 } 209 animatorHandle->animatorOption = animatorOption; 210 return ERROR_CODE_NO_ERROR; 211} 212 213int32_t AnimatorPlay(ArkUI_AnimatorHandle animatorHandle) 214{ 215 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 216 if (!impl || !animatorHandle || !animatorHandle->animator) { 217 return ERROR_CODE_PARAM_INVALID; 218 } 219 impl->getAnimation()->animatorPlay(animatorHandle->animator); 220 return ERROR_CODE_NO_ERROR; 221} 222 223int32_t AnimatorFinish(ArkUI_AnimatorHandle animatorHandle) 224{ 225 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 226 if (!impl || !animatorHandle || !animatorHandle->animator) { 227 return ERROR_CODE_PARAM_INVALID; 228 } 229 impl->getAnimation()->animatorFinish(animatorHandle->animator); 230 return ERROR_CODE_NO_ERROR; 231} 232 233int32_t AnimatorPause(ArkUI_AnimatorHandle animatorHandle) 234{ 235 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 236 if (!impl || !animatorHandle || !animatorHandle->animator) { 237 return ERROR_CODE_PARAM_INVALID; 238 } 239 impl->getAnimation()->animatorPause(animatorHandle->animator); 240 return ERROR_CODE_NO_ERROR; 241} 242 243int32_t AnimatorCancel(ArkUI_AnimatorHandle animatorHandle) 244{ 245 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 246 if (!impl || !animatorHandle || !animatorHandle->animator) { 247 return ERROR_CODE_PARAM_INVALID; 248 } 249 impl->getAnimation()->animatorCancel(animatorHandle->animator); 250 return ERROR_CODE_NO_ERROR; 251} 252 253int32_t AnimatorReverse(ArkUI_AnimatorHandle animatorHandle) 254{ 255 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 256 if (!impl || !animatorHandle || !animatorHandle->animator) { 257 return ERROR_CODE_PARAM_INVALID; 258 } 259 impl->getAnimation()->animatorReverse(animatorHandle->animator); 260 return ERROR_CODE_NO_ERROR; 261} 262 263ArkUI_CurveHandle InitCurve(ArkUI_AnimationCurve animationCurve) 264{ 265 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 266 if (!impl) { 267 return nullptr; 268 } 269 auto curve = impl->getAnimation()->initCurve(animationCurve); 270 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_BASE, curve, animationCurve }); 271 return iCurve; 272} 273 274ArkUI_CurveHandle StepsCurve(int32_t count, bool end) 275{ 276 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 277 if (!impl || count < 1) { 278 return nullptr; 279 } 280 auto curve = impl->getAnimation()->stepsCurve(count, end); 281 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_STEPS, curve }); 282 return iCurve; 283} 284 285ArkUI_CurveHandle CubicBezierCurve(float x1, float y1, float x2, float y2) 286{ 287 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 288 if (!impl) { 289 return nullptr; 290 } 291 x1 = std::clamp(x1, 0.0f, 1.0f); 292 x2 = std::clamp(x2, 0.0f, 1.0f); 293 auto curve = impl->getAnimation()->cubicBezierCurve(x1, y1, x2, y2); 294 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_CUBIC_BEZIER, curve }); 295 return iCurve; 296} 297 298ArkUI_CurveHandle SpringCurve(float velocity, float mass, float stiffness, float damping) 299{ 300 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 301 if (!impl) { 302 return nullptr; 303 } 304 if (mass <= 0) { 305 mass = 1; 306 } 307 if (stiffness <= 0) { 308 stiffness = 1; 309 } 310 if (damping <= 0) { 311 damping = 1; 312 } 313 auto curve = impl->getAnimation()->springCurve(velocity, mass, stiffness, damping); 314 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_SPRING, curve }); 315 return iCurve; 316} 317 318ArkUI_CurveHandle SpringMotion(float response, float dampingFraction, float overlapDuration) 319{ 320 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 321 if (!impl) { 322 return nullptr; 323 } 324 //default 325 if (response <= 0) { 326 response = 0.55f; 327 } 328 //default 329 if (dampingFraction <= 0) { 330 dampingFraction = 0.825f; 331 } 332 //default 333 if (overlapDuration < 0) { 334 overlapDuration = 0; 335 } 336 auto curve = impl->getAnimation()->springMotion(response, dampingFraction, overlapDuration); 337 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_SPRING_MOTION, curve }); 338 return iCurve; 339} 340 341ArkUI_CurveHandle ResponsiveSpringMotion(float response, float dampingFraction, float overlapDuration) 342{ 343 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 344 if (!impl) { 345 return nullptr; 346 } 347 //default 348 if (response <= 0) { 349 response = 0.15f; 350 } 351 //default 352 if (dampingFraction < 0) { 353 dampingFraction = 0.86f; 354 } 355 //default 356 if (overlapDuration < 0) { 357 overlapDuration = 0.25f; 358 } 359 auto curve = impl->getAnimation()->responsiveSpringMotion(response, dampingFraction, overlapDuration); 360 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_RESPONSIVE_SPRING_MOTION, curve }); 361 return iCurve; 362} 363 364ArkUI_CurveHandle InterpolatingSpring(float velocity, float mass, float stiffness, float damping) 365{ 366 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 367 if (!impl) { 368 return nullptr; 369 } 370 if (mass <= 0) { 371 mass = 1; 372 } 373 if (stiffness <= 0) { 374 stiffness = 1; 375 } 376 if (damping <= 0) { 377 damping = 1; 378 } 379 auto curve = impl->getAnimation()->interpolatingSpring(velocity, mass, stiffness, damping); 380 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_INTERPOLATING_SPRING, curve }); 381 return iCurve; 382} 383 384ArkUI_CurveHandle CustomCurve(void* userData, float (*interpolate)(float fraction, void* userdata)) 385{ 386 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 387 if (!impl) { 388 return nullptr; 389 } 390 auto curve = impl->getAnimation()->customCurve(interpolate, userData); 391 ArkUI_Curve* iCurve = new ArkUI_Curve({ ARKUI_CURVE_TYPE_CUSTOM, curve }); 392 return iCurve; 393} 394 395void DisposeCurve(ArkUI_CurveHandle curveHandle) 396{ 397 auto* impl = OHOS::Ace::NodeModel::GetFullImpl(); 398 if (!impl || !curveHandle) { 399 return; 400 } 401 impl->getAnimation()->disposeCurve(curveHandle->curve); 402 delete curveHandle; 403} 404} // namespace OHOS::Ace::AnimateModel