1e41f4b71Sopenharmony_ci# Implementing Property Animation
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciArkUI provides two types of APIs, namely, [animateTo](../reference/apis-arkui/arkui-ts/ts-explicit-animation.md) and [animation](../reference/apis-arkui/arkui-ts/ts-animatorproperty.md), to implement a property animation – an illusion of continuity created by driving component properties to change over time based on animation parameters such as the animation curve.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci| Property Animation API | Scope | Principle | Use Scenario |
8e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- |
9e41f4b71Sopenharmony_ci| animateTo | UI changes caused by property changes in closures.<br>Transition for appearance and disappearance. | This API is a common function. It animates the differences between the UIs before and after the state variable in the closure is changed.<br>This API can be called multiple times and can be nested. | A single set of animation parameters is used to animate multiple properties.<br>Animations need to be nested. |
10e41f4b71Sopenharmony_ci| animation | GUI changes caused by attribute changes bound to components through attribute APIs. | This API identifies the change of the animatable properties of a component and automatically adds an animation.<br>As the API call sequence of the component is from bottom to top, this API applies only to the properties above it.<br>In a component, you can set **animation** for individual properties based on the API call sequence. | Different sets of animation parameters are used to animate different properties. |
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci## animateTo
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci```
16e41f4b71Sopenharmony_cianimateTo(value: AnimateParam, event: () => void): void
17e41f4b71Sopenharmony_ci```
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciAmong the parameters of [animateTo](../reference/apis-arkui/arkui-ts/ts-explicit-animation.md), **value** indicates the [animation parameters](../reference/apis-arkui/arkui-ts/ts-explicit-animation.md#animateparam) (including duration and [curve](../reference/apis-arkui/js-apis-curve.md#curve)); **event** indicates the closure of the animation. Property animations generated by variable changes within a closure follow the same animation parameters.
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci```ts
23e41f4b71Sopenharmony_ciimport { curves } from '@kit.ArkUI';
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci@Entry
26e41f4b71Sopenharmony_ci@Component
27e41f4b71Sopenharmony_cistruct AnimateToDemo {
28e41f4b71Sopenharmony_ci  @State animate: boolean = false;
29e41f4b71Sopenharmony_ci  // Step 1: Declare related state variables.
30e41f4b71Sopenharmony_ci  @State rotateValue: number = 0; // Rotation angle of component 1.
31e41f4b71Sopenharmony_ci  @State translateX: number = 0; // Offset of component 2
32e41f4b71Sopenharmony_ci  @State opacityValue: number = 1; // Opacity of component 2.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci  // Step 2: Set the declared state variables to the related animatable property APIs.
35e41f4b71Sopenharmony_ci  build() {
36e41f4b71Sopenharmony_ci    Row() {
37e41f4b71Sopenharmony_ci      // Component 1
38e41f4b71Sopenharmony_ci      Column() {
39e41f4b71Sopenharmony_ci      }
40e41f4b71Sopenharmony_ci      .rotate({ angle: this.rotateValue })
41e41f4b71Sopenharmony_ci      .backgroundColor('#317AF7')
42e41f4b71Sopenharmony_ci      .justifyContent(FlexAlign.Center)
43e41f4b71Sopenharmony_ci      .width(100)
44e41f4b71Sopenharmony_ci      .height(100)
45e41f4b71Sopenharmony_ci      .borderRadius(30)
46e41f4b71Sopenharmony_ci      .onClick(() => {
47e41f4b71Sopenharmony_ci        animateTo({ curve: curves.springMotion() }, () => {
48e41f4b71Sopenharmony_ci          this.animate = !this.animate;
49e41f4b71Sopenharmony_ci          // Step 3: Change the state variables in the closure to update the UI.
50e41f4b71Sopenharmony_ci          // You can write any logic that can change the UI, such as array adding and visibility control. The system detects the differences between the new UI and the previous UI and adds animations for the differences.
51e41f4b71Sopenharmony_ci          // The rotate property of component 1 is changed. Therefore, a rotate animation is added to component 1.
52e41f4b71Sopenharmony_ci          this.rotateValue = this.animate ? 90 : 0;
53e41f4b71Sopenharmony_ci          // The opacity property of component 2 is changed. Therefore, an opacity animation is added to component 2.
54e41f4b71Sopenharmony_ci          this.opacityValue = this.animate ? 0.6 : 1;
55e41f4b71Sopenharmony_ci          // The offset property of component 2 is changed. Therefore, an offset animation is added to component 2.
56e41f4b71Sopenharmony_ci          this.translateX = this.animate ? 50 : 0;
57e41f4b71Sopenharmony_ci        })
58e41f4b71Sopenharmony_ci      })
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci      // Component 2
61e41f4b71Sopenharmony_ci      Column() {
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci      }
64e41f4b71Sopenharmony_ci      .justifyContent(FlexAlign.Center)
65e41f4b71Sopenharmony_ci      .width(100)
66e41f4b71Sopenharmony_ci      .height(100)
67e41f4b71Sopenharmony_ci      .backgroundColor('#D94838')
68e41f4b71Sopenharmony_ci      .borderRadius(30)
69e41f4b71Sopenharmony_ci      .opacity(this.opacityValue)
70e41f4b71Sopenharmony_ci      .translate({ x: this.translateX })
71e41f4b71Sopenharmony_ci    }
72e41f4b71Sopenharmony_ci    .width('100%')
73e41f4b71Sopenharmony_ci    .height('100%')
74e41f4b71Sopenharmony_ci    .justifyContent(FlexAlign.Center)
75e41f4b71Sopenharmony_ci  }
76e41f4b71Sopenharmony_ci}
77e41f4b71Sopenharmony_ci```
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci![en-us_image_0000001599958466](figures/en-us_image_0000001599958466.gif)
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci## animation
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ciUnlike the **animateTo** API, the [animation](../reference/apis-arkui/arkui-ts/ts-animatorproperty.md) API does not need to use a closure. Just add it to the end of the target animatable property, and the API will automatically add a property animation once it detects that the bound property is changed.
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ci```ts
88e41f4b71Sopenharmony_ciimport { curves } from '@kit.ArkUI';
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci@Entry
91e41f4b71Sopenharmony_ci@Component
92e41f4b71Sopenharmony_cistruct AnimationDemo {
93e41f4b71Sopenharmony_ci  @State animate: boolean = false;
94e41f4b71Sopenharmony_ci  // Step 1: Declare related state variables.
95e41f4b71Sopenharmony_ci  @State rotateValue: number = 0; // Rotation angle of component 1.
96e41f4b71Sopenharmony_ci  @State translateX: number = 0; // Offset of component 2
97e41f4b71Sopenharmony_ci  @State opacityValue: number = 1; // Opacity of component 2.
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci  // Step 2: Set the declared state variables to the related animatable property APIs.
100e41f4b71Sopenharmony_ci  build() {
101e41f4b71Sopenharmony_ci    Row() {
102e41f4b71Sopenharmony_ci      // Component 1
103e41f4b71Sopenharmony_ci      Column() {
104e41f4b71Sopenharmony_ci      }
105e41f4b71Sopenharmony_ci      .opacity(this.opacityValue)
106e41f4b71Sopenharmony_ci      .rotate({ angle: this.rotateValue })
107e41f4b71Sopenharmony_ci      // Step 3: Enable property animation.
108e41f4b71Sopenharmony_ci      .animation({ curve: curves.springMotion() })
109e41f4b71Sopenharmony_ci      .backgroundColor('#317AF7')
110e41f4b71Sopenharmony_ci      .justifyContent(FlexAlign.Center)
111e41f4b71Sopenharmony_ci      .width(100)
112e41f4b71Sopenharmony_ci      .height(100)
113e41f4b71Sopenharmony_ci      .borderRadius(30)
114e41f4b71Sopenharmony_ci      .onClick(() => {
115e41f4b71Sopenharmony_ci        this.animate = !this.animate;
116e41f4b71Sopenharmony_ci        // Step 4: Change the state variables in the closure to update the UI.
117e41f4b71Sopenharmony_ci        // You can write any logic that can change the UI, such as array adding and visibility control. The system detects the differences between the new UI and the previous UI and adds animations for the differences.
118e41f4b71Sopenharmony_ci        // The rotate property of component 1 is changed. Therefore, a rotate animation is added to component 1.
119e41f4b71Sopenharmony_ci        this.rotateValue = this.animate ? 90 : 0;
120e41f4b71Sopenharmony_ci        // The offset property of component 2 is changed. Therefore, an offset animation is added to component 2.
121e41f4b71Sopenharmony_ci        this.translateX = this.animate ? 50 : 0;
122e41f4b71Sopenharmony_ci        // The opacity property of the parent component <Column> is changed, which results in an opacity change of its child components. Therefore, opacity animations are added to <Column> and its child components.
123e41f4b71Sopenharmony_ci        this.opacityValue = this.animate ? 0.6 : 1;
124e41f4b71Sopenharmony_ci      })
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci      // Component 2
127e41f4b71Sopenharmony_ci      Column() {
128e41f4b71Sopenharmony_ci      }
129e41f4b71Sopenharmony_ci      .justifyContent(FlexAlign.Center)
130e41f4b71Sopenharmony_ci      .width(100)
131e41f4b71Sopenharmony_ci      .height(100)
132e41f4b71Sopenharmony_ci      .backgroundColor('#D94838')
133e41f4b71Sopenharmony_ci      .borderRadius(30)
134e41f4b71Sopenharmony_ci      .opacity(this.opacityValue)
135e41f4b71Sopenharmony_ci      .translate({ x: this.translateX })
136e41f4b71Sopenharmony_ci      .animation({ curve: curves.springMotion() })
137e41f4b71Sopenharmony_ci    }
138e41f4b71Sopenharmony_ci    .width('100%')
139e41f4b71Sopenharmony_ci    .height('100%')
140e41f4b71Sopenharmony_ci    .justifyContent(FlexAlign.Center)
141e41f4b71Sopenharmony_ci  }
142e41f4b71Sopenharmony_ci}
143e41f4b71Sopenharmony_ci```
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci![en-us_image_0000001649279705](figures/en-us_image_0000001649279705.gif)
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ci> **NOTE**
148e41f4b71Sopenharmony_ci> - When an animation is applied to the position or size change of a component, as layout measurement is involved, performance overheads are high. To reduce performance overheads, use the [scale](../reference/apis-arkui/arkui-ts/ts-universal-attributes-transformation.md#scale) attribute instead, whose value change does not involve layout re-measurement. This practice is applicable where the component location and size change continuously, for example, where the component size changes as a response to gestures.
149e41f4b71Sopenharmony_ci> 
150e41f4b71Sopenharmony_ci> - Property animations should be applied to the components that are always visible. For those components whose visibility may change, use the [transition animation](arkts-transition-overview.md).
151e41f4b71Sopenharmony_ci> 
152e41f4b71Sopenharmony_ci> - Avoid using end callbacks for property animations. Property animations are applied to states that have occurred. As such, you do not need to process the end logic. If end callbacks are needed, be sure to correctly handle the data management for continuous operations.
153