1e41f4b71Sopenharmony_ci# Frame Animation 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciFrame animation involves the use of the **onFrame** callback in applications, which allows you to adjust property values with each frame that is rendered, thereby creating animation effects for the components associated with those property values. For details about the APIs, see [@ohos.animator (Animator)](../reference/apis-arkui/js-apis-animator.md). 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci## Implementing an Animation with animator 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ciTo create a simple animator and print the current interpolation value in each frame callback: 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci1. Import dependencies. 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ci ```ts 13e41f4b71Sopenharmony_ci import { AnimatorOptions, AnimatorResult } from '@kit.ArkUI'; 14e41f4b71Sopenharmony_ci ``` 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci2. Create an animator object. 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci ```ts 19e41f4b71Sopenharmony_ci // Initial options for creating an animator object 20e41f4b71Sopenharmony_ci let options: AnimatorOptions = { 21e41f4b71Sopenharmony_ci duration: 1500, 22e41f4b71Sopenharmony_ci easing: "friction", 23e41f4b71Sopenharmony_ci delay: 0, 24e41f4b71Sopenharmony_ci fill: "forwards", 25e41f4b71Sopenharmony_ci direction: "normal", 26e41f4b71Sopenharmony_ci iterations: 2, 27e41f4b71Sopenharmony_ci // Initial frame value used for interpolation in the onFrame callback 28e41f4b71Sopenharmony_ci begin: 200.0, 29e41f4b71Sopenharmony_ci // End frame value used for interpolation in the onFrame callback 30e41f4b71Sopenharmony_ci end: 400.0 31e41f4b71Sopenharmony_ci }; 32e41f4b71Sopenharmony_ci let result: AnimatorResult = this.getUIContext().createAnimator(options); 33e41f4b71Sopenharmony_ci // Set up a callback for when a frame is received, so that the onFrame callback is called for every frame throughout the animation playback process. 34e41f4b71Sopenharmony_ci result.onFrame = (value: number) => { 35e41f4b71Sopenharmony_ci console.log("current value is :" + value); 36e41f4b71Sopenharmony_ci } 37e41f4b71Sopenharmony_ci ``` 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ci3. Play the animation. 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci ```ts 42e41f4b71Sopenharmony_ci // Play the animation. 43e41f4b71Sopenharmony_ci result.play(); 44e41f4b71Sopenharmony_ci ``` 45e41f4b71Sopenharmony_ci 46e41f4b71Sopenharmony_ci4. After the animation has finished executing, manually release the **AnimatorResult** object. 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci ```ts 49e41f4b71Sopenharmony_ci // Play the animation. 50e41f4b71Sopenharmony_ci result = undefined; 51e41f4b71Sopenharmony_ci ``` 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci## Implementing a Ball's Parabolic Motion with Animator 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci1. Import dependencies. 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ci ```ts 58e41f4b71Sopenharmony_ci import { AnimatorOptions, AnimatorResult } from '@kit.ArkUI'; 59e41f4b71Sopenharmony_ci ``` 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci2. Define the component to be animated. 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci ```ts 64e41f4b71Sopenharmony_ci Button() 65e41f4b71Sopenharmony_ci .width(60) 66e41f4b71Sopenharmony_ci .height(60) 67e41f4b71Sopenharmony_ci .translate({ x: this.translateX, y: this.translateY }) 68e41f4b71Sopenharmony_ci ``` 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci3. Create an **AnimatorResult** Object in **onPageShow**. 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci ```ts 73e41f4b71Sopenharmony_ci onPageShow(): void { 74e41f4b71Sopenharmony_ci // Create an animatorResult object. 75e41f4b71Sopenharmony_ci this.animatorOptions = this.getUIContext().createAnimator(options); 76e41f4b71Sopenharmony_ci this.animatorOptions.onFrame = (progress: number) => { 77e41f4b71Sopenharmony_ci this.translateX = progress; 78e41f4b71Sopenharmony_ci if (progress > this.topWidth && this.translateY < this.bottomHeight) { 79e41f4b71Sopenharmony_ci this.translateY = Math.pow(progress - this.topWidth, 2) * this.g; 80e41f4b71Sopenharmony_ci } 81e41f4b71Sopenharmony_ci } 82e41f4b71Sopenharmony_ci // Invoked when the animation is canceled. 83e41f4b71Sopenharmony_ci this.animatorOptions.onCancel = () => { 84e41f4b71Sopenharmony_ci this.animatorStatus = 'Canceled' 85e41f4b71Sopenharmony_ci } 86e41f4b71Sopenharmony_ci // Invoked when the animation finishes playing. 87e41f4b71Sopenharmony_ci this.animatorOptions.onFinish = () => { 88e41f4b71Sopenharmony_ci this.animatorStatus = 'Finished' 89e41f4b71Sopenharmony_ci } 90e41f4b71Sopenharmony_ci // Invoked when the animation repeats. 91e41f4b71Sopenharmony_ci this.animatorOptions.onRepeat = () => { 92e41f4b71Sopenharmony_ci console.log("Animation repeating"); 93e41f4b71Sopenharmony_ci } 94e41f4b71Sopenharmony_ci } 95e41f4b71Sopenharmony_ci ``` 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci4. Define buttons for controlling the animation. 98e41f4b71Sopenharmony_ci 99e41f4b71Sopenharmony_ci ```ts 100e41f4b71Sopenharmony_ci Button('Play').onClick(() => { 101e41f4b71Sopenharmony_ci this.animatorOptions?.play(); 102e41f4b71Sopenharmony_ci this.animatorStatus = 'Playing' 103e41f4b71Sopenharmony_ci }).width(80).height(35) 104e41f4b71Sopenharmony_ci Button("Reset").onClick(() => { 105e41f4b71Sopenharmony_ci this.translateX = 0; 106e41f4b71Sopenharmony_ci this.translateY = 0; 107e41f4b71Sopenharmony_ci }).width(80).height(35) 108e41f4b71Sopenharmony_ci Button("Pause").onClick(() => { 109e41f4b71Sopenharmony_ci this.animatorOptions?.pause(); 110e41f4b71Sopenharmony_ci this.animatorStatus = 'Paused' 111e41f4b71Sopenharmony_ci }).width(80).height(35) 112e41f4b71Sopenharmony_ci ``` 113e41f4b71Sopenharmony_ci5. Destroy the animation in the page's **onPageHide** lifecycle callback. 114e41f4b71Sopenharmony_ci ```ts 115e41f4b71Sopenharmony_ci onPageHide(): void { 116e41f4b71Sopenharmony_ci this.animatorOptions = undefined; 117e41f4b71Sopenharmony_ci } 118e41f4b71Sopenharmony_ci ``` 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ciA complete example is as follows: 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_ci```ts 123e41f4b71Sopenharmony_ciimport { AnimatorOptions, AnimatorResult } from '@kit.ArkUI'; 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci@Entry 126e41f4b71Sopenharmony_ci@Component 127e41f4b71Sopenharmony_cistruct Index { 128e41f4b71Sopenharmony_ci @State animatorOptions: AnimatorResult | undefined = undefined; 129e41f4b71Sopenharmony_ci @State animatorStatus: string =' Created' 130e41f4b71Sopenharmony_ci begin: number = 0; 131e41f4b71Sopenharmony_ci end: number = 300 132e41f4b71Sopenharmony_ci topWidth: number = 150; 133e41f4b71Sopenharmony_ci bottomHeight: number = 100; 134e41f4b71Sopenharmony_ci g: number = 0.18 135e41f4b71Sopenharmony_ci animatorOption: AnimatorOptions = { 136e41f4b71Sopenharmony_ci duration: 4000, 137e41f4b71Sopenharmony_ci delay: 0, 138e41f4b71Sopenharmony_ci easing: 'linear', 139e41f4b71Sopenharmony_ci iterations: 1, 140e41f4b71Sopenharmony_ci fill: "forwards", 141e41f4b71Sopenharmony_ci direction: 'normal', 142e41f4b71Sopenharmony_ci begin: this.begin, 143e41f4b71Sopenharmony_ci end: this.end 144e41f4b71Sopenharmony_ci }; 145e41f4b71Sopenharmony_ci @State translateX: number = 0; 146e41f4b71Sopenharmony_ci @State translateY: number = 0; 147e41f4b71Sopenharmony_ci 148e41f4b71Sopenharmony_ci onPageShow(): void { 149e41f4b71Sopenharmony_ci this.animatorOptions = this.getUIContext().createAnimator(this.animatorOption) 150e41f4b71Sopenharmony_ci this.animatorOptions.onFrame = (progress: number) => { 151e41f4b71Sopenharmony_ci this.translateX = progress; 152e41f4b71Sopenharmony_ci if (progress > this.topWidth && this.translateY < this.bottomHeight) { 153e41f4b71Sopenharmony_ci this.translateY = Math.pow(progress - this.topWidth, 2) * this.g; 154e41f4b71Sopenharmony_ci } 155e41f4b71Sopenharmony_ci } 156e41f4b71Sopenharmony_ci this.animatorOptions.onCancel = () => { 157e41f4b71Sopenharmony_ci this.animatorStatus = 'Canceled' 158e41f4b71Sopenharmony_ci } 159e41f4b71Sopenharmony_ci this.animatorOptions.onFinish = () => { 160e41f4b71Sopenharmony_ci this.animatorStatus = 'Finished' 161e41f4b71Sopenharmony_ci } 162e41f4b71Sopenharmony_ci this.animatorOptions.onRepeat = () => { 163e41f4b71Sopenharmony_ci console.log("Animation repeating"); 164e41f4b71Sopenharmony_ci } 165e41f4b71Sopenharmony_ci } 166e41f4b71Sopenharmony_ci 167e41f4b71Sopenharmony_ci onPageHide(): void { 168e41f4b71Sopenharmony_ci this.animatorOptions = undefined; 169e41f4b71Sopenharmony_ci } 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_ci build() { 172e41f4b71Sopenharmony_ci Column() { 173e41f4b71Sopenharmony_ci Column({ space: 30 }) { 174e41f4b71Sopenharmony_ci Button('Play').onClick(() => { 175e41f4b71Sopenharmony_ci this.animatorOptions?.play(); 176e41f4b71Sopenharmony_ci this.animatorStatus = 'Playing'; 177e41f4b71Sopenharmony_ci }).width(80).height(35) 178e41f4b71Sopenharmony_ci Button("Reset").onClick(() => { 179e41f4b71Sopenharmony_ci this.translateX = 0; 180e41f4b71Sopenharmony_ci this.translateY = 0; 181e41f4b71Sopenharmony_ci }).width(80).height(35) 182e41f4b71Sopenharmony_ci Button("Pause").onClick(() => { 183e41f4b71Sopenharmony_ci this.animatorOptions?.pause(); 184e41f4b71Sopenharmony_ci this.animatorStatus = 'Paused'; 185e41f4b71Sopenharmony_ci }).width(80).height(35) 186e41f4b71Sopenharmony_ci }.width("100%").height('25%') 187e41f4b71Sopenharmony_ci 188e41f4b71Sopenharmony_ci Stack() { 189e41f4b71Sopenharmony_ci Button() 190e41f4b71Sopenharmony_ci .width(60) 191e41f4b71Sopenharmony_ci .height(60) 192e41f4b71Sopenharmony_ci .translate({ x: this.translateX, y: this.translateY }) 193e41f4b71Sopenharmony_ci } 194e41f4b71Sopenharmony_ci .width("100%") 195e41f4b71Sopenharmony_ci .height('45%') 196e41f4b71Sopenharmony_ci .align(Alignment.Start) 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_ci Text("Current animation state: "+ this.animatorStatus) 199e41f4b71Sopenharmony_ci }.width("100%").height('100%') 200e41f4b71Sopenharmony_ci } 201e41f4b71Sopenharmony_ci} 202e41f4b71Sopenharmony_ci``` 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci 205