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