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