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