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