1# Using Animations
2
3
4## Using Property Animations
5
6The 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.
7
8> **NOTE**
9>
10> - Obtain **this.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 written within the callback of **ArkUI_ContextCallback**.
15> 
16> - The properties to be animated must 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 the UI context 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.
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(OH_NativeXComponent *component)
122   {
123       if (!component) {
124           return;
125       }
126       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
127           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
128       ArkUI_NodeHandle column = nodeAPI->createNode(ARKUI_NODE_COLUMN);
129       ArkUI_NumberValue widthValue[] = {{.f32 = 500}};
130       ArkUI_AttributeItem widthItem = {.value = widthValue, .size = sizeof(widthValue) / sizeof(ArkUI_NumberValue)};
131       nodeAPI->setAttribute(column, NODE_WIDTH, &widthItem);
132       ArkUI_NumberValue heightValue[] = {{.f32 = 500}};
133       ArkUI_AttributeItem heightItem = {.value = heightValue, .size = sizeof(heightValue) / sizeof(ArkUI_NumberValue)};
134       nodeAPI->setAttribute(column, NODE_HEIGHT, &heightItem);
135       ArkUI_NodeHandle buttonShow = nodeAPI->createNode(ARKUI_NODE_BUTTON);
136       ArkUI_NumberValue buttonWidthValue[] = {{.f32 = 200}};
137       ArkUI_AttributeItem buttonWidthItem = {.value = buttonWidthValue,
138                                              .size = sizeof(buttonWidthValue) / sizeof(ArkUI_NumberValue)};
139       nodeAPI->setAttribute(buttonShow, NODE_WIDTH, &buttonWidthItem);
140       ArkUI_NumberValue buttonHeightValue[] = {{.f32 = 50}};
141       ArkUI_AttributeItem buttonHeightItem = {.value = buttonHeightValue,
142                                               .size = sizeof(buttonHeightValue) / sizeof(ArkUI_NumberValue)};
143       nodeAPI->setAttribute(buttonShow, NODE_HEIGHT, &buttonHeightItem);
144       ArkUI_AttributeItem labelItem = {.string = "show"};
145       nodeAPI->setAttribute(buttonShow, NODE_BUTTON_LABEL, &labelItem);
146       ArkUI_NumberValue buttonOpenTypeValue[] = {{.i32 = static_cast<int32_t>(ARKUI_BUTTON_TYPE_NORMAL)}};
147       ArkUI_AttributeItem buttonOpenTypeItem = {.value = buttonOpenTypeValue,
148                                                 .size = sizeof(buttonOpenTypeValue) / sizeof(ArkUI_NumberValue)};
149       nodeAPI->setAttribute(buttonShow, NODE_BUTTON_TYPE, &buttonOpenTypeItem);
150       ArkUI_NumberValue buttonShowMarginValue[] = {{.f32 = 20}};
151       ArkUI_AttributeItem buttonShowMarginItem = {.value = buttonShowMarginValue,
152                                                    .size = sizeof(buttonShowMarginValue) / sizeof(ArkUI_NumberValue)};
153       nodeAPI->setAttribute(buttonShow, NODE_MARGIN, &buttonShowMarginItem);
154       nodeAPI->registerNodeEvent(buttonShow, NODE_ON_CLICK, BUTTON_CLICK_ID, nullptr);
155       nodeAPI->addNodeEventReceiver(buttonShow, OnButtonShowClicked);
156       parrentNode = column;
157       buttonNode = buttonShow;
158       nodeAPI->addChild(column, buttonShow);
159       OH_NativeXComponent_AttachNativeRootNode(component, column);
160   }
161   ```
162
1632. Create a node with **Transition** properties that play a transition animation when the target node is mounted or unmounted.
164   ```
165   ArkUI_NodeHandle CreateChildNode() {
166       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
167           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
168       ArkUI_NodeHandle image = nodeAPI->createNode(ARKUI_NODE_IMAGE);
169       ArkUI_AttributeItem imageSrcItem = {.string = "/pages/common/scenery.jpg"};
170       nodeAPI->setAttribute(image, NODE_IMAGE_SRC, &imageSrcItem);
171       ArkUI_NumberValue textWidthValue[] = {{.f32 = 300}};
172       ArkUI_AttributeItem textWidthItem = {.value = textWidthValue,
173                                            .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
174       nodeAPI->setAttribute(image, NODE_WIDTH, &textWidthItem);
175       ArkUI_NumberValue textHeightValue[] = {{.f32 = 300}};
176       ArkUI_AttributeItem textHeightItem = {.value = textHeightValue,
177                                             .size = sizeof(textWidthValue) / sizeof(ArkUI_NumberValue)};
178       nodeAPI->setAttribute(image, NODE_HEIGHT, &textHeightItem);
179       ArkUI_NumberValue transformCenterValue[] = {0.0f, 0.0f, 0.0f, 0.5f, 0.5f};
180       ArkUI_AttributeItem transformCenterItem = {.value = transformCenterValue,
181                                             .size = sizeof(transformCenterValue) / sizeof(ArkUI_NumberValue)};
182       nodeAPI->setAttribute(image, NODE_TRANSFORM_CENTER, &transformCenterItem);
183       ArkUI_NumberValue rotateAnimationValue[] = {0.0f, 0.0f, 1.0f, 360.0f, 0.0f, {.i32 = 500}, {.i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
184       ArkUI_AttributeItem rotateAnimationItem = {.value = rotateAnimationValue,
185                                                  .size = sizeof(rotateAnimationValue) / sizeof(ArkUI_NumberValue)};
186       nodeAPI->setAttribute(image, NODE_ROTATE_TRANSITION, &rotateAnimationItem);
187       ArkUI_NumberValue scaleAnimationValue[] = {
188           0.0f, 0.0f, 0.0f, {.i32 = 500}, {.i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
189       ArkUI_AttributeItem scaleAnimationItem = {.value = scaleAnimationValue,
190                                                  .size = sizeof(scaleAnimationValue) / sizeof(ArkUI_NumberValue)};
191       nodeAPI->setAttribute(image, NODE_SCALE_TRANSITION, &scaleAnimationItem);
192       ArkUI_NumberValue translateAnimationValue[] = {
193           200, 200, 0.0f, {.i32 = 500}, {.i32 = static_cast<int32_t>(ARKUI_CURVE_SHARP)}};
194       ArkUI_AttributeItem translateAnimationItem = {.value = translateAnimationValue,
195                                                 .size = sizeof(translateAnimationValue) / sizeof(ArkUI_NumberValue)};
196       nodeAPI->setAttribute(image, NODE_TRANSLATE_TRANSITION, &translateAnimationItem);
197       return image;
198   }
199   ```
200
2013. 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.
202   ```
203   void OnButtonShowClicked(ArkUI_NodeEvent* event)
204   {
205       if (!event) {
206           return;
207       }
208       if (!childNode) {
209           childNode = CreateChildNode();
210       }
211       ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
212           OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
213       if (flag) {
214           flag = false;
215           ArkUI_AttributeItem labelItem = {.string = "show"};
216           nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
217           nodeAPI->removeChild(parrentNode, childNode);
218       } else {
219           flag = true;
220           ArkUI_AttributeItem labelItem = {.string = "hide"};
221           nodeAPI->setAttribute(buttonNode, NODE_BUTTON_LABEL, &labelItem);
222           nodeAPI->addChild(parrentNode, childNode);
223       }
224   }
225   ```
226
227   ![en-us_image_0000001903284256](figures/en-us_image_0000001903284256.gif)
228