1 /*
2 * Copyright (c) 2022 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 <memory>
17 #include <string>
18
19 #include "animator_option.h"
20 #include "interfaces/napi/kits/utils/napi_utils.h"
21 #include "napi/native_api.h"
22 #include "napi/native_engine/native_value.h"
23 #include "napi/native_node_api.h"
24
25 #include "base/log/log.h"
26 #include "base/memory/ace_type.h"
27 #include "base/memory/referenced.h"
28 #include "bridge/common/utils/utils.h"
29 #include "core/animation/animator.h"
30 #include "core/animation/curve.h"
31 #include "core/animation/curve_animation.h"
32
33 namespace OHOS::Ace::Napi {
34
ParseString(napi_env env,napi_value propertyNapi,std::string & property)35 static void ParseString(napi_env env, napi_value propertyNapi, std::string& property)
36 {
37 if (propertyNapi != nullptr) {
38 napi_valuetype valueType = napi_undefined;
39 napi_typeof(env, propertyNapi, &valueType);
40 if (valueType == napi_undefined) {
41 NapiThrow(env, "Required input parameters are missing.", Framework::ERROR_CODE_PARAM_INVALID);
42 return;
43 } else if (valueType != napi_string) {
44 NapiThrow(env, "The type of parameters is incorrect.", Framework::ERROR_CODE_PARAM_INVALID);
45 return;
46 }
47 auto nativeProperty = reinterpret_cast<NativeValue*>(propertyNapi);
48 auto resultProperty = nativeProperty->ToString();
49 auto nativeStringProperty =
50 reinterpret_cast<NativeString*>(resultProperty->GetInterface(NativeString::INTERFACE_ID));
51 size_t propertyLen = nativeStringProperty->GetLength() + 1;
52 std::unique_ptr<char[]> propertyString = std::make_unique<char[]>(propertyLen);
53 size_t retLen = 0;
54 napi_get_value_string_utf8(env, propertyNapi, propertyString.get(), propertyLen, &retLen);
55 property = propertyString.get();
56 }
57 }
58
ParseInt(napi_env env,napi_value propertyNapi,int32_t & property)59 static void ParseInt(napi_env env, napi_value propertyNapi, int32_t& property)
60 {
61 if (propertyNapi != nullptr) {
62 napi_valuetype valueType = napi_undefined;
63 napi_typeof(env, propertyNapi, &valueType);
64 if (valueType == napi_undefined) {
65 NapiThrow(env, "Required input parameters are missing.", Framework::ERROR_CODE_PARAM_INVALID);
66 return;
67 } else if (valueType != napi_number) {
68 NapiThrow(env, "The type of parameters is incorrect.", Framework::ERROR_CODE_PARAM_INVALID);
69 return;
70 }
71 napi_get_value_int32(env, propertyNapi, &property);
72 }
73 }
74
ParseDouble(napi_env env,napi_value propertyNapi,double & property)75 static void ParseDouble(napi_env env, napi_value propertyNapi, double& property)
76 {
77 if (propertyNapi != nullptr) {
78 napi_valuetype valueType = napi_undefined;
79 napi_typeof(env, propertyNapi, &valueType);
80 if (valueType == napi_undefined) {
81 NapiThrow(env, "Required input parameters are missing.", Framework::ERROR_CODE_PARAM_INVALID);
82 return;
83 } else if (valueType != napi_number) {
84 NapiThrow(env, "The type of parameters is incorrect.", Framework::ERROR_CODE_PARAM_INVALID);
85 return;
86 }
87 napi_get_value_double(env, propertyNapi, &property);
88 }
89 }
90
StringToFillMode(const std::string & fillMode)91 static FillMode StringToFillMode(const std::string& fillMode)
92 {
93 if (fillMode.compare("forwards") == 0) {
94 return FillMode::FORWARDS;
95 } else if (fillMode.compare("backwards") == 0) {
96 return FillMode::BACKWARDS;
97 } else if (fillMode.compare("both") == 0) {
98 return FillMode::BOTH;
99 } else {
100 return FillMode::NONE;
101 }
102 }
103
StringToAnimationDirection(const std::string & direction)104 static AnimationDirection StringToAnimationDirection(const std::string& direction)
105 {
106 if (direction.compare("alternate") == 0) {
107 return AnimationDirection::ALTERNATE;
108 } else if (direction.compare("reverse") == 0) {
109 return AnimationDirection::REVERSE;
110 } else if (direction.compare("alternate-reverse") == 0) {
111 return AnimationDirection::ALTERNATE_REVERSE;
112 } else {
113 return AnimationDirection::NORMAL;
114 }
115 }
116
ParseAnimatorOption(napi_env env,napi_callback_info info,std::shared_ptr<AnimatorOption> & option)117 static void ParseAnimatorOption(napi_env env, napi_callback_info info, std::shared_ptr<AnimatorOption>& option)
118 {
119 LOGI("JsAnimator: ParseAnimatorOption");
120 size_t argc = 1;
121 napi_value argv;
122 napi_get_cb_info(env, info, &argc, &argv, NULL, NULL);
123 if (argc != 1) {
124 NapiThrow(env, "The number of parameters must be equal to 1.", Framework::ERROR_CODE_PARAM_INVALID);
125 return;
126 }
127 napi_value durationNapi = nullptr;
128 napi_value easingNapi = nullptr;
129 napi_value delayNapi = nullptr;
130 napi_value fillNapi = nullptr;
131 napi_value directionNapi = nullptr;
132 napi_value iterationsNapi = nullptr;
133 napi_value beginNapi = nullptr;
134 napi_value endNapi = nullptr;
135 napi_valuetype valueType = napi_undefined;
136 napi_typeof(env, argv, &valueType);
137 if (valueType == napi_object) {
138 napi_get_named_property(env, argv, "duration", &durationNapi);
139 napi_get_named_property(env, argv, "easing", &easingNapi);
140 napi_get_named_property(env, argv, "delay", &delayNapi);
141 napi_get_named_property(env, argv, "fill", &fillNapi);
142 napi_get_named_property(env, argv, "direction", &directionNapi);
143 napi_get_named_property(env, argv, "iterations", &iterationsNapi);
144 napi_get_named_property(env, argv, "begin", &beginNapi);
145 napi_get_named_property(env, argv, "end", &endNapi);
146 } else {
147 NapiThrow(env, "The type of parameters is incorrect.", Framework::ERROR_CODE_PARAM_INVALID);
148 return;
149 }
150
151 int32_t duration = 0;
152 int32_t delay = 0;
153 int32_t iterations = 0;
154 double begin = 0.0;
155 double end = 0.0;
156 std::string easing = "ease";
157 std::string fill = "none";
158 std::string direction = "normal";
159 ParseString(env, easingNapi, easing);
160 ParseString(env, fillNapi, fill);
161 ParseString(env, directionNapi, direction);
162 ParseInt(env, durationNapi, duration);
163 ParseInt(env, delayNapi, delay);
164 ParseInt(env, iterationsNapi, iterations);
165 ParseDouble(env, beginNapi, begin);
166 ParseDouble(env, endNapi, end);
167 option->duration = duration;
168 option->delay = delay;
169 option->iterations = iterations;
170 option->begin = begin;
171 option->end = end;
172 option->easing = easing;
173 option->fill = fill;
174 option->direction = direction;
175 }
176
GetAnimatorInResult(napi_env env,napi_callback_info info)177 static RefPtr<Animator> GetAnimatorInResult(napi_env env, napi_callback_info info)
178 {
179 AnimatorResult* animatorResult = nullptr;
180 napi_value thisVar;
181 napi_get_cb_info(env, info, NULL, NULL, &thisVar, NULL);
182 napi_unwrap(env, thisVar, (void**)&animatorResult);
183 if (!animatorResult) {
184 LOGE("unwrap animator result is failed");
185 return nullptr;
186 }
187 return animatorResult->GetAnimator();
188 }
189
JSReset(napi_env env,napi_callback_info info)190 static napi_value JSReset(napi_env env, napi_callback_info info)
191 {
192 LOGI("JsAnimator: JSReset");
193 AnimatorResult* animatorResult = nullptr;
194 napi_value thisVar;
195 napi_get_cb_info(env, info, NULL, NULL, &thisVar, NULL);
196 napi_unwrap(env, thisVar, (void**)&animatorResult);
197 if (!animatorResult) {
198 LOGE("unwrap animator result is failed");
199 NapiThrow(env, "Internal error. Unwrap animator result is failed.", Framework::ERROR_CODE_INTERNAL_ERROR);
200 return nullptr;
201 }
202 auto option = animatorResult->GetAnimatorOption();
203 if (!option) {
204 LOGE("Option is null in AnimatorResult");
205 NapiThrow(env, "Internal error. Option is null in AnimatorResult.", Framework::ERROR_CODE_INTERNAL_ERROR);
206 return nullptr;
207 }
208 ParseAnimatorOption(env, info, option);
209 auto animator = animatorResult->GetAnimator();
210 if (!animator) {
211 LOGW("animator is null");
212 NapiThrow(env, "Internal error. Animator is null in AnimatorResult.", Framework::ERROR_CODE_INTERNAL_ERROR);
213 return nullptr;
214 }
215 animator->ClearInterpolators();
216 animator->ResetIsReverse();
217 animatorResult->ApplyOption();
218 napi_ref onframeRef = animatorResult->GetOnframeRef();
219 if (onframeRef) {
220 auto curve = Framework::CreateCurve(option->easing);
221 auto animation = AceType::MakeRefPtr<CurveAnimation<double>>(option->begin, option->end, curve);
222 animation->AddListener([env, onframeRef](double value) {
223 napi_value ret = nullptr;
224 napi_value valueNapi = nullptr;
225 napi_value onframe = nullptr;
226 auto result = napi_get_reference_value(env, onframeRef, &onframe);
227 if (result != napi_ok || onframe == nullptr) {
228 LOGW("get onframe in callback failed");
229 return;
230 }
231 napi_create_double(env, value, &valueNapi);
232 napi_call_function(env, nullptr, onframe, 1, &valueNapi, &ret);
233 });
234 animator->AddInterpolator(animation);
235 }
236 napi_value result;
237 napi_get_null(env, &result);
238 return result;
239 }
240
241 // since API 9 deprecated
JSUpdate(napi_env env,napi_callback_info info)242 static napi_value JSUpdate(napi_env env, napi_callback_info info)
243 {
244 LOGI("JsAnimator: JSUpdate");
245 return JSReset(env, info);
246 }
247
JSPlay(napi_env env,napi_callback_info info)248 static napi_value JSPlay(napi_env env, napi_callback_info info)
249 {
250 LOGI("JsAnimator: JSPlay");
251 auto animator = GetAnimatorInResult(env, info);
252 if (!animator) {
253 LOGE("animator is null");
254 return nullptr;
255 }
256 if (!animator->HasScheduler()) {
257 animator->AttachSchedulerOnContainer();
258 }
259 animator->Play();
260 napi_value result = nullptr;
261 napi_get_null(env, &result);
262 return result;
263 }
264
JSFinish(napi_env env,napi_callback_info info)265 static napi_value JSFinish(napi_env env, napi_callback_info info)
266 {
267 LOGI("JsAnimator: JSFinish");
268 auto animator = GetAnimatorInResult(env, info);
269 if (!animator) {
270 LOGE("animator is null");
271 return nullptr;
272 }
273 animator->Finish();
274 napi_value result = nullptr;
275 napi_get_null(env, &result);
276 return result;
277 }
278
JSPause(napi_env env,napi_callback_info info)279 static napi_value JSPause(napi_env env, napi_callback_info info)
280 {
281 LOGI("JsAnimator: JSPause");
282 auto animator = GetAnimatorInResult(env, info);
283 if (!animator) {
284 LOGE("animator is null");
285 return nullptr;
286 }
287 animator->Pause();
288 napi_value result;
289 napi_get_null(env, &result);
290 return result;
291 }
292
JSCancel(napi_env env,napi_callback_info info)293 static napi_value JSCancel(napi_env env, napi_callback_info info)
294 {
295 LOGI("JsAnimator: JSCancel");
296 auto animator = GetAnimatorInResult(env, info);
297 if (!animator) {
298 LOGE("animator is null");
299 return nullptr;
300 }
301 animator->Cancel();
302 napi_value result;
303 napi_get_null(env, &result);
304 return result;
305 }
306
JSReverse(napi_env env,napi_callback_info info)307 static napi_value JSReverse(napi_env env, napi_callback_info info)
308 {
309 LOGI("JsAnimator: JSReverse");
310 auto animator = GetAnimatorInResult(env, info);
311 if (!animator) {
312 LOGE("animator is null");
313 return nullptr;
314 }
315 if (!animator->HasScheduler()) {
316 animator->AttachSchedulerOnContainer();
317 }
318 animator->Reverse();
319 napi_value result;
320 napi_get_null(env, &result);
321 return result;
322 }
323
SetOnframe(napi_env env,napi_callback_info info)324 static napi_value SetOnframe(napi_env env, napi_callback_info info)
325 {
326 LOGI("JsAnimator: SetOnframe");
327 AnimatorResult* animatorResult = nullptr;
328 size_t argc = 1;
329 napi_value thisVar = nullptr;
330 napi_value onframe = nullptr;
331 napi_get_cb_info(env, info, &argc, &onframe, &thisVar, NULL);
332 napi_unwrap(env, thisVar, (void**)&animatorResult);
333 if (!animatorResult) {
334 LOGE("unwrap animator result is failed");
335 return nullptr;
336 }
337 auto option = animatorResult->GetAnimatorOption();
338 if (!option) {
339 LOGE("option is null");
340 return nullptr;
341 }
342 auto animator = animatorResult->GetAnimator();
343 if (!animator) {
344 LOGE("animator is null");
345 return nullptr;
346 }
347 animator->ClearInterpolators();
348 auto curve = Framework::CreateCurve(option->easing);
349 auto animation = AceType::MakeRefPtr<CurveAnimation<double>>(option->begin, option->end, curve);
350 // convert onframe function to reference
351 napi_ref onframeRef = animatorResult->GetOnframeRef();
352 if (onframeRef) {
353 uint32_t count = 0;
354 napi_reference_unref(env, onframeRef, &count);
355 }
356 napi_create_reference(env, onframe, 1, &onframeRef);
357 animatorResult->SetOnframeRef(onframeRef);
358 animation->AddListener([env, onframeRef](double value) {
359 napi_value ret = nullptr;
360 napi_value valueNapi = nullptr;
361 napi_value onframe = nullptr;
362 auto result = napi_get_reference_value(env, onframeRef, &onframe);
363 if (result != napi_ok || onframe == nullptr) {
364 LOGW("get onframe in callback failed");
365 return;
366 }
367 napi_create_double(env, value, &valueNapi);
368 napi_call_function(env, nullptr, onframe, 1, &valueNapi, &ret);
369 });
370 animator->AddInterpolator(animation);
371 if (!animator->HasScheduler()) {
372 animator->AttachSchedulerOnContainer();
373 }
374 napi_value undefined;
375 napi_get_undefined(env, &undefined);
376 return undefined;
377 }
378
SetOnfinish(napi_env env,napi_callback_info info)379 static napi_value SetOnfinish(napi_env env, napi_callback_info info)
380 {
381 LOGI("JsAnimator: SetOnfinish");
382 AnimatorResult* animatorResult = nullptr;
383 size_t argc = 1;
384 napi_value thisVar = nullptr;
385 napi_value onfinish = nullptr;
386 napi_get_cb_info(env, info, &argc, &onfinish, &thisVar, NULL);
387 napi_unwrap(env, thisVar, (void**)&animatorResult);
388 if (!animatorResult) {
389 LOGE("unwrap animator result is failed");
390 return nullptr;
391 }
392 auto option = animatorResult->GetAnimatorOption();
393 if (!option) {
394 LOGE("option is null");
395 return nullptr;
396 }
397 auto animator = animatorResult->GetAnimator();
398 if (!animator) {
399 LOGE("animator is null");
400 return nullptr;
401 }
402 // convert onfinish function to reference
403 napi_ref onfinishRef = animatorResult->GetOnfinishRef();
404 if (onfinishRef) {
405 uint32_t count = 0;
406 napi_reference_unref(env, onfinishRef, &count);
407 }
408 napi_create_reference(env, onfinish, 1, &onfinishRef);
409 animatorResult->SetOnfinishRef(onfinishRef);
410 animator->ClearStopListeners();
411 animator->AddStopListener([env, onfinishRef] {
412 LOGI("JsAnimator: onfinish->AddIdleListener");
413 napi_value ret = nullptr;
414 napi_value onfinish = nullptr;
415 auto result = napi_get_reference_value(env, onfinishRef, &onfinish);
416 if (result != napi_ok || onfinish == nullptr) {
417 LOGW("get onfinish in callback failed");
418 return;
419 }
420 napi_call_function(env, NULL, onfinish, 0, NULL, &ret);
421 });
422 napi_value undefined;
423 napi_get_undefined(env, &undefined);
424 return undefined;
425 }
426
SetOncancel(napi_env env,napi_callback_info info)427 static napi_value SetOncancel(napi_env env, napi_callback_info info)
428 {
429 LOGI("JsAnimator: SetOncancel");
430 AnimatorResult* animatorResult = nullptr;
431 size_t argc = 1;
432 napi_value thisVar = nullptr;
433 napi_value oncancel = nullptr;
434 napi_get_cb_info(env, info, &argc, &oncancel, &thisVar, NULL);
435 napi_unwrap(env, thisVar, (void**)&animatorResult);
436 if (!animatorResult) {
437 LOGE("unwrap animator result is failed");
438 return nullptr;
439 }
440 auto option = animatorResult->GetAnimatorOption();
441 if (!option) {
442 LOGE("option is null");
443 return nullptr;
444 }
445 auto animator = animatorResult->GetAnimator();
446 if (!animator) {
447 LOGE("animator is null");
448 return nullptr;
449 }
450 // convert oncancel function to reference
451 napi_ref oncancelRef = animatorResult->GetOncancelRef();
452 if (oncancelRef) {
453 uint32_t count = 0;
454 napi_reference_unref(env, oncancelRef, &count);
455 }
456 napi_create_reference(env, oncancel, 1, &oncancelRef);
457 animatorResult->SetOncancelRef(oncancelRef);
458 animator->ClearIdleListeners();
459 animator->AddIdleListener([env, oncancelRef] {
460 LOGI("JsAnimator: oncancel->AddIdleListener");
461 napi_value ret = nullptr;
462 napi_value oncancel = nullptr;
463 auto result = napi_get_reference_value(env, oncancelRef, &oncancel);
464 if (result != napi_ok || oncancel == nullptr) {
465 LOGW("get oncancel in callback failed");
466 return;
467 }
468 napi_call_function(env, NULL, oncancel, 0, NULL, &ret);
469 });
470 napi_value undefined;
471 napi_get_undefined(env, &undefined);
472 return undefined;
473 }
474
SetOnrepeat(napi_env env,napi_callback_info info)475 static napi_value SetOnrepeat(napi_env env, napi_callback_info info)
476 {
477 LOGI("JsAnimator: SetOnrepeat");
478 AnimatorResult* animatorResult = nullptr;
479 size_t argc = 1;
480 napi_value thisVar = nullptr;
481 napi_value onrepeat = nullptr;
482 napi_get_cb_info(env, info, &argc, &onrepeat, &thisVar, NULL);
483 napi_unwrap(env, thisVar, (void**)&animatorResult);
484 if (!animatorResult) {
485 LOGE("unwrap animator result is failed");
486 return nullptr;
487 }
488 auto option = animatorResult->GetAnimatorOption();
489 if (!option) {
490 LOGE("option is null");
491 return nullptr;
492 }
493 auto animator = animatorResult->GetAnimator();
494 if (!animator) {
495 LOGE("animator is null");
496 return nullptr;
497 }
498 // convert onrepeat function to reference
499 napi_ref onrepeatRef = animatorResult->GetOnrepeatRef();
500 if (onrepeatRef) {
501 uint32_t count = 0;
502 napi_reference_unref(env, onrepeatRef, &count);
503 }
504 napi_create_reference(env, onrepeat, 1, &onrepeatRef);
505 animatorResult->SetOnrepeatRef(onrepeatRef);
506 animator->ClearRepeatListeners();
507 animator->AddRepeatListener([env, onrepeatRef] {
508 LOGI("JsAnimator: onrepeat->AddIdleListener");
509 napi_value ret = nullptr;
510 napi_value onrepeat = nullptr;
511 auto result = napi_get_reference_value(env, onrepeatRef, &onrepeat);
512 if (result != napi_ok || onrepeat == nullptr) {
513 LOGW("get onrepeat in callback failed");
514 return;
515 }
516 napi_call_function(env, NULL, onrepeat, 0, NULL, &ret);
517 });
518 napi_value undefined;
519 napi_get_undefined(env, &undefined);
520 return undefined;
521 }
522
JSCreate(napi_env env,napi_callback_info info)523 static napi_value JSCreate(napi_env env, napi_callback_info info)
524 {
525 LOGI("JsAnimator: JSCreate");
526 auto option = std::make_shared<AnimatorOption>();
527 ParseAnimatorOption(env, info, option);
528 auto animator = AceType::MakeRefPtr<Animator>();
529 animator->AttachSchedulerOnContainer();
530 AnimatorResult* animatorResult = new AnimatorResult(animator, option);
531 napi_value jsAnimator = nullptr;
532 napi_create_object(env, &jsAnimator);
533 napi_wrap(
534 env, jsAnimator, animatorResult,
535 [](napi_env env, void* data, void* hint) {
536 AnimatorResult* animatorResult = (AnimatorResult*)data;
537 // release four references(onFunc) before releasing animatorResult
538 napi_ref onframeRef = animatorResult->GetOnframeRef();
539 napi_ref onfinishRef = animatorResult->GetOnfinishRef();
540 napi_ref oncancelRef = animatorResult->GetOncancelRef();
541 napi_ref onrepeatRef = animatorResult->GetOnrepeatRef();
542 if (onframeRef != nullptr) {
543 napi_delete_reference(env, onframeRef);
544 }
545 if (onfinishRef != nullptr) {
546 napi_delete_reference(env, onfinishRef);
547 }
548 if (oncancelRef != nullptr) {
549 napi_delete_reference(env, oncancelRef);
550 }
551 if (onrepeatRef != nullptr) {
552 napi_delete_reference(env, onrepeatRef);
553 }
554 delete animatorResult;
555 },
556 nullptr, nullptr);
557 napi_property_descriptor resultFuncs[] = {
558 DECLARE_NAPI_FUNCTION("update", JSUpdate),
559 DECLARE_NAPI_FUNCTION("reset", JSReset),
560 DECLARE_NAPI_FUNCTION("play", JSPlay),
561 DECLARE_NAPI_FUNCTION("finish", JSFinish),
562 DECLARE_NAPI_FUNCTION("pause", JSPause),
563 DECLARE_NAPI_FUNCTION("cancel", JSCancel),
564 DECLARE_NAPI_FUNCTION("reverse", JSReverse),
565 DECLARE_NAPI_SETTER("onframe", SetOnframe),
566 DECLARE_NAPI_SETTER("onfinish", SetOnfinish),
567 DECLARE_NAPI_SETTER("oncancel", SetOncancel),
568 DECLARE_NAPI_SETTER("onrepeat", SetOnrepeat),
569 };
570
571 NAPI_CALL(env, napi_define_properties(env, jsAnimator, sizeof(resultFuncs) / sizeof(resultFuncs[0]), resultFuncs));
572 return jsAnimator;
573 }
574
575 // since API 9 deprecated
JSCreateAnimator(napi_env env,napi_callback_info info)576 static napi_value JSCreateAnimator(napi_env env, napi_callback_info info)
577 {
578 LOGI("JsAnimator: JSCreateAnimator");
579 return JSCreate(env, info);
580 }
581
AnimatorExport(napi_env env,napi_value exports)582 static napi_value AnimatorExport(napi_env env, napi_value exports)
583 {
584 LOGI("JsAnimator: AnimatorExport");
585 napi_property_descriptor animatorDesc[] = {
586 DECLARE_NAPI_FUNCTION("create", JSCreate),
587 DECLARE_NAPI_FUNCTION("createAnimator", JSCreateAnimator),
588 };
589 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(animatorDesc) / sizeof(animatorDesc[0]), animatorDesc));
590 return exports;
591 }
592
593 static napi_module animatorModule = {
594 .nm_version = 1,
595 .nm_flags = 0,
596 .nm_filename = nullptr,
597 .nm_register_func = AnimatorExport,
598 .nm_modname = "animator",
599 .nm_priv = ((void*)0),
600 .reserved = { 0 },
601 };
602
AnimatorRegister()603 extern "C" __attribute__((constructor)) void AnimatorRegister()
604 {
605 napi_module_register(&animatorModule);
606 }
607
ApplyOption()608 void AnimatorResult::ApplyOption()
609 {
610 CHECK_NULL_VOID_NOLOG(animator_);
611 CHECK_NULL_VOID_NOLOG(option_);
612 animator_->SetDuration(option_->duration);
613 animator_->SetIteration(option_->iterations);
614 animator_->SetStartDelay(option_->delay);
615 animator_->SetFillMode(StringToFillMode(option_->fill));
616 animator_->SetAnimationDirection(StringToAnimationDirection(option_->direction));
617 }
618
619 } // namespace OHOS::Ace::Napi
620