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