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
22 namespace OHOS::Ace::AnimateModel {
23
AnimateTo(ArkUI_ContextHandle context, ArkUI_AnimateOption* option, ArkUI_ContextCallback* update, ArkUI_AnimateCompleteCallback* complete)24 int32_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
KeyframeAnimateTo(ArkUI_ContextHandle context, ArkUI_KeyframeAnimateOption* option)66 int32_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
ConvertAnimatorOption(ArkUI_AnimatorOption* option)103 ArkUIAnimatorOption* 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
CreateAnimator(ArkUI_ContextHandle context, ArkUI_AnimatorOption* option)159 ArkUI_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
DisposeAnimator(ArkUI_AnimatorHandle animatorHandle)172 void 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
AnimatorReset(ArkUI_AnimatorHandle animatorHandle, ArkUI_AnimatorOption* option)191 int32_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
AnimatorPlay(ArkUI_AnimatorHandle animatorHandle)213 int32_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
AnimatorFinish(ArkUI_AnimatorHandle animatorHandle)223 int32_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
AnimatorPause(ArkUI_AnimatorHandle animatorHandle)233 int32_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
AnimatorCancel(ArkUI_AnimatorHandle animatorHandle)243 int32_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
AnimatorReverse(ArkUI_AnimatorHandle animatorHandle)253 int32_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
InitCurve(ArkUI_AnimationCurve animationCurve)263 ArkUI_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
StepsCurve(int32_t count, bool end)274 ArkUI_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
CubicBezierCurve(float x1, float y1, float x2, float y2)285 ArkUI_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
SpringCurve(float velocity, float mass, float stiffness, float damping)298 ArkUI_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
SpringMotion(float response, float dampingFraction, float overlapDuration)318 ArkUI_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
ResponsiveSpringMotion(float response, float dampingFraction, float overlapDuration)341 ArkUI_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
InterpolatingSpring(float velocity, float mass, float stiffness, float damping)364 ArkUI_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
CustomCurve(void* userData, float (*interpolate)(float fraction, void* userdata))384 ArkUI_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
DisposeCurve(ArkUI_CurveHandle curveHandle)395 void 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