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  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  225