1# Using Animations
2
3
4## Using Property Animations
5
6The ArkUI framework primarily offers property animations through NDK APIs to implement component transition effects for appearance and disappearance. Additionally, frame animation capabilities from the ArkTS side can be bridged through the Node-API to achieve animation effects on the native side.
7
8> **NOTE**
9>
10> - Obtain [this.getUIContext()](../reference/apis-arkui/arkui-ts/ts-custom-component-api.md#getuicontext) from ArkTS and pass it to the native side.
11>
12> - On the native side, obtain the context using the [OH_ArkUI_GetContextFromNapiValue](../reference/apis-arkui/native__node__napi_8h.md) API.
13>
14> - Animation property changes must be encapsulated within the callback of [ArkUI_ContextCallback](../reference/apis-arkui/_ark_u_i___context_callback.md).
15>
16> - Ensure that the properties intended for animation have been set before the animation is executed.
17
18A global **animateTo** explicit animation API is provided to specify transition effects for state changes caused by closure code. Like property animations, layout changes such as width and height adjustments are animated directly to their final states.
19
201. Obtain [UIContext](../reference//apis-arkui/js-apis-arkui-UIContext.md#uicontext) in the .ets file and pass **this.getUIContext()** as a parameter to the native API.
21   ```ts
22   // createNativeNode is an API exposed on the native side.
23   nativeNode.createNativeNode("xcomponentId", this.getUIContext());
24   ```
25
262. Parse the UI context to convert the context object in C.
27   ```
28   // Obtain the context passed from the ArkTS side.
29   ArkUI_ContextHandle context = nullptr;
30   // Determine whether the acquisition is successful based on code.
31   auto code = OH_ArkUI_GetContextFromNapiValue(env, args[1], &context);
32   ```
33
343. Obtain the **ArkUI_NativeAnimateAPI_1** object.
35   ```
36   // Obtain the ArkUI_NativeAnimateAPI.
37   ArkUI_NativeAnimateAPI_1 *animateApi = nullptr;
38   OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_ANIMATE, ArkUI_NativeAnimateAPI_1, animateApi);
39   ```
40
414. Set the **ArkUI_AnimateOption** parameters using the provided C APIs.
42   ```
43   ArkUI_AnimateOption *option = OH_ArkUI_AnimateOption_Create();
44   OH_ArkUI_AnimateOption_SetDuration(option, 2000);
45   OH_ArkUI_AnimateOption_SetTempo(option, 1.1);
46   OH_ArkUI_AnimateOption_SetCurve(option, ARKUI_CURVE_EASE);
47   OH_ArkUI_AnimateOption_SetDelay(option, 20);
48   OH_ArkUI_AnimateOption_SetIterations(option, 1);
49   OH_ArkUI_AnimateOption_SetPlayMode(option, ARKUI_ANIMATION_PLAY_MODE_REVERSE);
50   ArkUI_ExpectedFrameRateRange *range = new ArkUI_ExpectedFrameRateRange;
51   range->min = 10;
52   range->max = 120;
53   range->expected = 60;
54   OH_ArkUI_AnimateOption_SetExpectedFrameRateRange(option, range);
55   ```
56
575. Set callback parameters.
58   ```
59   // Define a user data struct.
60   struct UserData{
61       int32_t data;
62   };
63   UserData *onFinishUser = new UserData;
64   onFinishUser->data= 101;
65   // Create and set user data for the completion callback.
66   ArkUI_AnimateCompleteCallback *completeCallback = new ArkUI_AnimateCompleteCallback;
67   completeCallback->userData = onFinishUser;
68   completeCallback->type = ARKUI_FINISH_CALLBACK_REMOVED;
69   completeCallback->callback = [](void *userData) {
70       OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  onFinishCallback %{public}d",
71                    reinterpret_cast<AA *>(userData)->a);
72   };
73   // User data
74   UserData *eventUser = new UserData ;
75   eventUser->data= 201;
76   static bool isback = true;
77   ArkUI_ContextCallback *update = new ArkUI_ContextCallback;
78   update->userData = eventUser;
79   update->callback = [](void *user) {
80       OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Manager", "CreateNativeNode  animateTo %{public}d",
81                    reinterpret_cast<UserData*>(user)->data);
82       // Example of changing width and height properties
83       if (isback) {
84           ArkUI_NumberValue custom_widthValue[] = {200};
85           ArkUI_AttributeItem custom_widthItem = {custom_widthValue, 1};
86           ArkUI_NumberValue custom_heightValue1[] = {80};
87           ArkUI_AttributeItem custom_heightItem1 = {custom_heightValue1, 1};
88           nodeAPI->setAttribute(textInput, NODE_WIDTH, &custom_widthItem);
89           nodeAPI->setAttribute(textInput, NODE_HEIGHT, &custom_heightItem1);
90       } else {
91           ArkUI_NumberValue custom_widthValue[] = {100};
92           ArkUI_AttributeItem custom_widthItem = {custom_widthValue, 1};
93           ArkUI_NumberValue custom_heightValue1[] = {40};
94           ArkUI_AttributeItem custom_heightItem1 = {custom_heightValue1, 1};
95           nodeAPI->setAttribute(textInput, NODE_WIDTH, &custom_widthItem);
96           nodeAPI->setAttribute(textInput, NODE_HEIGHT, &custom_heightItem1);
97       }
98   };
99   // Execute the animation with the set options and callbacks.
100   animateApi->animateTo(context, option, update, completeCallback);
101   ```
102
103   ![GIF](figures/animateTo.gif)
104
105
106
107
108
109## Using Component Appearance/Disappearance Transitions
110
111Use **NODE_*XX*_TRANSITION** properties (where *XX* can be **OPACITY**, **TRANSLATE**, **SCALE**, **ROTATE**, or **MOVE**) to configure transition effects for components, enhancing the user experience when components are added to or removed from containers. The **NODE_TRANSFORM_CENTER** property sets the center point for animations including **NODE_SCALE_TRANSITION** and **NODE_ROTATE_ROTATE**.
112
1131. Design an interactive UI with a button to manage the addition and removal of transition nodes. For details about how to obtain and use the ArkUI_NodeContentHandle node, see [Integrating with ArkTS Pages](ndk-access-the-arkts-page.md).
114   ```
115   constexpr int32_t BUTTON_CLICK_ID = 1;
116   bool flag = false;
117   ArkUI_NodeHandle parrentNode;
118   ArkUI_NodeHandle childNode;
119   ArkUI_NodeHandle buttonNode;
120
121   void mainViewMethod(ArkUI_NodeContentHandle handle)
122   {
123       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
124           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
125       ArkUI_NodeHandle column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
126       ArkUI_NumberValue widthValue[] = {{.f32 = 500}};
127       ArkUI_AttributeItem widthItem = {.value = widthValue, .size = sizeof(widthValue) / sizeof(ArkUI_NumberValue)};
128       nodeAPI->setAttribute(column, NODE_WIDTH, &widthItem);
129       ArkUI_NumberValue heightValue[] = {{.f32 = 500}};
130       ArkUI_AttributeItem heightItem = {.value = heightValue, .size = sizeof(heightValue) / sizeof(ArkUI_NumberValue)};
131       nodeAPI->setAttribute(column, NODE_HEIGHT, &heightItem);
132       ArkUI_NodeHandle buttonShow = nodeAPI->createNode(ARKUI_NODE_BUTTON);
133       ArkUI_NumberValue buttonWidthValue[] = {{.f32 = 200}};
134       ArkUI_AttributeItem buttonWidthItem = {.value = buttonWidthValue,
135                                              .size = sizeof(buttonWidthValue) / sizeof(ArkUI_NumberValue)};
136       nodeAPI->setAttribute(buttonShow, NODE_WIDTH, &buttonWidthItem);
137       ArkUI_NumberValue buttonHeightValue[] = {{.f32 = 50}};
138       ArkUI_AttributeItem buttonHeightItem = {.value = buttonHeightValue,
139                                               .size = sizeof(buttonHeightValue) / sizeof(ArkUI_NumberValue)};
140       nodeAPI->setAttribute(buttonShow, NODE_HEIGHT, &buttonHeightItem);
141       ArkUI_AttributeItem labelItem = {.string = "show"};
142       nodeAPI->setAttribute(buttonShow, NODE_BUTTON_LABEL, &labelItem);
143       ArkUI_NumberValue buttonOpenTypeValue[] = {{.i32 = static_cast<int32_t>(ARKUI_BUTTON_TYPE_NORMAL)}};
144       ArkUI_AttributeItem buttonOpenTypeItem = {.value = buttonOpenTypeValue,
145                                                 .size = sizeof(buttonOpenTypeValue) / sizeof(ArkUI_NumberValue)};
146       nodeAPI->setAttribute(buttonShow, NODE_BUTTON_TYPE, &buttonOpenTypeItem);
147       ArkUI_NumberValue buttonShowMarginValue[] = {{.f32 = 20}};
148       ArkUI_AttributeItem buttonShowMarginItem = {.value = buttonShowMarginValue,
149                                                    .size = sizeof(buttonShowMarginValue) / sizeof(ArkUI_NumberValue)};
150       nodeAPI->setAttribute(buttonShow, NODE_MARGIN, &buttonShowMarginItem);
151       nodeAPI->registerNodeEvent(buttonShow, NODE_ON_CLICK, BUTTON_CLICK_ID, nullptr);
152       nodeAPI->addNodeEventReceiver(buttonShow, OnButtonShowClicked);
153       parrentNode = column;
154       buttonNode = buttonShow;
155       nodeAPI->addChild(column, buttonShow);
156       OH_ArkUI_NodeContent_AddNode(handle, column);
157   }
158   ```
159
1602. Create a node with **Transition** properties that play a transition animation when the target node is mounted or unmounted.
161   ```
162   ArkUI_NodeHandle CreateChildNode() {
163       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
164           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
165       ArkUI_NodeHandle image = nodeAPI->createNode(ARKUI_NODE_IMAGE);
166       ArkUI_AttributeItem imageSrcItem = {.string = "/pages/common/scenery.jpg"};
167       nodeAPI->setAttribute(image, NODE_IMAGE_SRC, &imageSrcItem);
168       ArkUI_NumberValue textWidthValue[] = {{.f32 = 300}};
169       ArkUI_AttributeItem textWidthItem = {.value = textWidthValue,
170                                            .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
171       nodeAPI->setAttribute(image, NODE_WIDTH, &textWidthItem);
172       ArkUI_NumberValue textHeightValue[] = {{.f32 = 300}};
173       ArkUI_AttributeItem textHeightItem = {.value = textHeightValue,
174                                             .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
175       nodeAPI->setAttribute(image, NODE_HEIGHT, &textHeightItem);
176       ArkUI_NumberValue transformCenterValue[] = {0.0f, 0.0f, 0.0f, 0.5f, 0.5f};
177       ArkUI_AttributeItem transformCenterItem = {.value = transformCenterValue,
178                                             .size = sizeof(transformCenterValue) / sizeof(ArkUI_NumberValue)};
179       nodeAPI->setAttribute(image, NODE_TRANSFORM_CENTER, &transformCenterItem);
180       ArkUI_NumberValue rotateAnimationValue[] = {0.0f, 0.0f, 1.0f, 360.0f, 0.0f, {.i32 = 500}, {.i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
181       ArkUI_AttributeItem rotateAnimationItem = {.value = rotateAnimationValue,
182                                                  .size = sizeof(rotateAnimationValue) / sizeof(ArkUI_NumberValue)};
183       nodeAPI->setAttribute(image, NODE_ROTATE_TRANSITION, &rotateAnimationItem);
184       ArkUI_NumberValue scaleAnimationValue[] = {
185           0.0f, 0.0f, 0.0f, {.i32 = 500}, {.i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
186       ArkUI_AttributeItem scaleAnimationItem = {.value = scaleAnimationValue,
187                                                  .size = sizeof(scaleAnimationValue) / sizeof(ArkUI_NumberValue)};
188       nodeAPI->setAttribute(image, NODE_SCALE_TRANSITION, &scaleAnimationItem);
189       ArkUI_NumberValue translateAnimationValue[] = {
190           200, 200, 0.0f, {.i32 = 500}, {.i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
191       ArkUI_AttributeItem translateAnimationItem = {.value = translateAnimationValue,
192                                                 .size = sizeof(translateAnimationValue) / sizeof(ArkUI_NumberValue)};
193       nodeAPI->setAttribute(image, NODE_TRANSLATE_TRANSITION, &translateAnimationItem);
194       return image;
195   }
196   ```
197
1983. Add logic for mounting and unmounting the transition node within the **Button** component event callback to control the appearance and disappearance of the transition node.
199   ```
200   void OnButtonShowClicked(ArkUI_NodeEvent* event)
201   {
202       if (!event) {
203           return;
204       }
205       if (!childNode) {
206           childNode = CreateChildNode();
207       }
208       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
209           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
210       if (flag) {
211           flag = false;
212           ArkUI_AttributeItem labelItem = {.string = "show"};
213           nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
214           nodeAPI->removeChild(parrentNode, childNode);
215       } else {
216           flag = true;
217           ArkUI_AttributeItem labelItem = {.string = "hide"};
218           nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
219           nodeAPI->addChild(parrentNode, childNode);
220       }
221   }
222   ```
223
224   ![en-us_image_0000001903284256](figures/en-us_image_0000001903284256.gif)
225