1# ImageAnimator 2 3The **ImageAnimator** component enables images to be played a frame-by-frame basis. The list of images to be played as well as the duration of each image can be configured. 4 5> **NOTE** 6> 7> This component is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. 8 9 10 11## Child Components 12 13Not supported 14 15 16## APIs 17 18ImageAnimator() 19 20**Widget capability**: This API can be used in ArkTS widgets since API version 10. 21 22**Atomic service API**: This API can be used in atomic services since API version 11. 23 24**System capability**: SystemCapability.ArkUI.ArkUI.Full 25 26## Attributes 27 28In addition to the [universal attributes](ts-component-general-attributes.md), the following attributes are supported. 29 30### images 31 32images(value: Array<ImageFrameInfo>) 33 34Sets the image frame information. Dynamic update is not supported. 35 36**Widget capability**: This API can be used in ArkTS widgets since API version 10. 37 38**Atomic service API**: This API can be used in atomic services since API version 11. 39 40**System capability**: SystemCapability.ArkUI.ArkUI.Full 41 42**Parameters** 43 44| Name| Type | Mandatory| Description | 45| ------ | ------------------------------------------------------ | ---- | ------------------------------------------------------------ | 46| value | Array<[ImageFrameInfo](#imageframeinfo)> | Yes | Image frame information. The information of each frame includes the image path, image size, image position, and image playback duration. For details, see **ImageFrameInfo**.<br>Default value: **[]**<br> **NOTE**<br>If the input array is too large, memory usage may increase. Therefore, as the controller of memory usage, be sure to assess potential memory consumption before passing in the data to avoid issues such as insufficient memory.| 47 48### state 49 50state(value: AnimationStatus) 51 52Sets the playback state of the animation. 53 54**Widget capability**: This API can be used in ArkTS widgets since API version 10. 55 56**Atomic service API**: This API can be used in atomic services since API version 11. 57 58**System capability**: SystemCapability.ArkUI.ArkUI.Full 59 60**Parameters** 61 62| Name| Type | Mandatory| Description | 63| ------ | ------------------------------------------------------- | ---- | ------------------------------------------------------------ | 64| value | [AnimationStatus](ts-appendix-enums.md#animationstatus) | Yes | Playback state of the animation. The default state is **Initial**.<br>Default value: **AnimationStatus.Initial**| 65 66### duration 67 68duration(value: number) 69 70Sets the playback duration. This attribute does not take effect when a separate duration is set for any of the image frames. 71 72**Widget capability**: This API can be used in ArkTS widgets since API version 10. 73 74**Atomic service API**: This API can be used in atomic services since API version 11. 75 76**System capability**: SystemCapability.ArkUI.ArkUI.Full 77 78**Parameters** 79 80| Name| Type | Mandatory| Description | 81| ------ | ------ | ---- | ------------------------------------------------------------ | 82| value | number | Yes | Playback duration.<br>If the value is **0**, no image is played.<br>The value change takes effect only at the start of the next cycle.<br>Unit: ms<br>Default value: **1000**| 83 84### reverse 85 86reverse(value: boolean) 87 88Sets the playback direction. 89 90**Widget capability**: This API can be used in ArkTS widgets since API version 10. 91 92**Atomic service API**: This API can be used in atomic services since API version 11. 93 94**System capability**: SystemCapability.ArkUI.ArkUI.Full 95 96**Parameters** 97 98| Name| Type | Mandatory| Description | 99| ------ | ------- | ---- | ------------------------------------------------------------ | 100| value | boolean | Yes | Playback direction.<br>The value **false** indicates that images are played from the first one to the last one, and **true** indicates that images are played from the last one to the first one.<br>Default value: **false**| 101 102### fixedSize 103 104fixedSize(value: boolean) 105 106Sets whether the image size is fixed at the component size. 107 108**Widget capability**: This API can be used in ArkTS widgets since API version 10. 109 110**Atomic service API**: This API can be used in atomic services since API version 11. 111 112**System capability**: SystemCapability.ArkUI.ArkUI.Full 113 114**Parameters** 115 116| Name| Type | Mandatory| Description | 117| ------ | ------- | ---- | ------------------------------------------------------------ | 118| value | boolean | Yes | Whether the image size is fixed at the component size.<br> **true**: The image size is fixed at the component size. In this case, the width, height, top, and left attributes of the image are invalid.<br> **false**: The width, height, top, and left attributes of each image must be set separately.<br>Default value: **true**| 119 120### preDecode<sup>(deprecated)</sup> 121 122preDecode(value: number) 123 124Sets the number of images to be pre-decoded. 125 126This API is deprecated since API version 9. 127 128**System capability**: SystemCapability.ArkUI.ArkUI.Full 129 130**Parameters** 131 132| Name| Type | Mandatory| Description | 133| ------ | ------ | ---- | ------------------------------------------------------------ | 134| value | number | Yes | Number of images to be pre-decoded. For example, the value **2** indicates that two images following the currently playing one are pre-decoded.<br>Default value: **0**| 135 136### fillMode 137 138fillMode(value: FillMode) 139 140Sets the status before and after execution of the animation in the current playback direction. The status after execution of the animation is jointly determined by the **fillMode** and **reverse** attributes. For example, if **fillMode** is set to **Forwards**, the target will retain the state defined by the last keyframe encountered during execution. In this case, if **reverse** is set to **false**, the target will retain the state defined by the last keyframe encountered in the forward direction, that is, the last image; if **reverse** is set to **true**, the target will retain the state defined by the last keyframe encountered in the backward direction, that is, the first image. 141 142**Widget capability**: This API can be used in ArkTS widgets since API version 10. 143 144**Atomic service API**: This API can be used in atomic services since API version 11. 145 146**System capability**: SystemCapability.ArkUI.ArkUI.Full 147 148**Parameters** 149 150| Name| Type | Mandatory| Description | 151| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ | 152| value | [FillMode](ts-appendix-enums.md#fillmode) | Yes | Status before and after execution of the animation in the current playback direction.<br>Default value: **FillMode.Forwards**| 153 154### iterations 155 156iterations(value: number) 157 158Sets the number of times that the animation is played. 159 160**Atomic service API**: This API can be used in atomic services since API version 11. 161 162**System capability**: SystemCapability.ArkUI.ArkUI.Full 163 164**Parameters** 165 166| Name| Type | Mandatory| Description | 167| ------ | ------ | ---- | ------------------------------------------------------ | 168| value | number | Yes | Number of times that the animation is played. By default, the animation is played once. The value **-1** indicates that the animation is played for an unlimited number of times.<br>Default value: **1**| 169 170### monitorInvisibleArea<sup>18+</sup> 171 172monitorInvisibleArea(monitorInvisibleArea: boolean) 173 174Sets whether the component should automatically pause or resume based on its visibility, using the system's [onVisibleAreaChange](./ts-universal-component-visible-area-change-event.md#onvisibleareachange) event. 175 176**Atomic service API**: This API can be used in atomic services since API version 18. 177 178**System capability**: SystemCapability.ArkUI.ArkUI.Full 179 180**Parameters** 181 182| Name| Type | Mandatory| Description | 183| ------ | ------ | ---- | ------------------------------------------------------ | 184| monitorInvisibleArea | boolean | Yes| Whether the component should automatically pause or resume based on its visibility, using the system's [onVisibleAreaChange](./ts-universal-component-visible-area-change-event.md#onvisibleareachange) event.<br> With the value **true**, when the component's [AnimationStatus](ts-appendix-enums.md#animationstatus) is Running, the component automatically pauses once it becomes invisible and resumes playback if it becomes visible again, based on the **onVisibleAreaChange** event.<br>Default value: **false**<br> **NOTE**<br>When this parameter is dynamically changed from **true** to **false**,<br> the component will resume from its last paused state based on the current **AnimationStatus**.<br>Changes to this property do not affect the custom [state](./ts-basic-components-imageanimator.md#state) value.| 185 186## ImageFrameInfo 187 188**Atomic service API**: This API can be used in atomic services since API version 11. 189 190**System capability**: SystemCapability.ArkUI.ArkUI.Full 191 192| Name | Type | Mandatory| Description| 193| -------- | -------------- | -------- | -------- | 194| src | string \| [Resource](ts-types.md#resource)<sup>9+</sup> \| [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)<sup>12+</sup> | Yes | Image path. The image format can be .jpg, .jpeg, .svg, .png, .bmp, .webp, .ico, or .heif. The [Resource](ts-types.md#resource) type is supported since API version 9, and the [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7) type is supported since API version 12.<br>**Widget capability**: This API can be used in ArkTS widgets since API version 10.| 195| width | number \| string | No | Image width. For the string type, numeric string values with optional units, for example, **"2"** or **"2px"**, are supported.<br>Default value: **0**<br>Unit: vp<br>**Widget capability**: This API can be used in ArkTS widgets since API version 10. | 196| height | number \| string | No | Image height. For the string type, numeric string values with optional units, for example, **"2"** or **"2px"**, are supported.<br>Default value: **0**<br>Unit: vp<br>**Widget capability**: This API can be used in ArkTS widgets since API version 10. | 197| top | number \| string | No | Vertical coordinate of the image relative to the upper left corner of the widget For the string type, numeric string values with optional units, for example, **"2"** or **"2px"**, are supported.<br>Default value: **0**<br>Unit: vp<br>**Widget capability**: This API can be used in ArkTS widgets since API version 10. | 198| left | number \| string | No | Horizontal coordinate of the image relative to the upper left corner of the widget For the string type, numeric string values with optional units, for example, **"2"** or **"2px"**, are supported.<br>Default value: **0**<br>Unit: vp<br>**Widget capability**: This API can be used in ArkTS widgets since API version 10. | 199| duration | number | No | Playback duration of each image frame, in milliseconds.<br>Default value: **0** | 200 201## Events 202 203In addition to the [universal events](ts-component-general-events.md), the following events are supported. 204 205### onStart 206 207onStart(event: () => void) 208 209Triggered when the animation starts to play. 210 211**Widget capability**: This API can be used in ArkTS widgets since API version 10. 212 213**Atomic service API**: This API can be used in atomic services since API version 11. 214 215**System capability**: SystemCapability.ArkUI.ArkUI.Full 216 217### onPause 218 219onPause(event: () => void) 220 221Triggered when the animation playback is paused. 222 223**Widget capability**: This API can be used in ArkTS widgets since API version 10. 224 225**Atomic service API**: This API can be used in atomic services since API version 11. 226 227**System capability**: SystemCapability.ArkUI.ArkUI.Full 228 229### onRepeat 230 231onRepeat(event: () => void) 232 233Triggered when the animation playback is repeated. 234 235**Atomic service API**: This API can be used in atomic services since API version 11. 236 237**System capability**: SystemCapability.ArkUI.ArkUI.Full 238 239### onCancel 240 241onCancel(event: () => void) 242 243Triggered when the animation playback returns to the initial state. 244 245**Widget capability**: This API can be used in ArkTS widgets since API version 10. 246 247**Atomic service API**: This API can be used in atomic services since API version 11. 248 249**System capability**: SystemCapability.ArkUI.ArkUI.Full 250 251### onFinish 252 253onFinish(event: () => void) 254 255Triggered when the animation playback is complete or stopped. 256 257**Widget capability**: This API can be used in ArkTS widgets since API version 10. 258 259**Atomic service API**: This API can be used in atomic services since API version 11. 260 261**System capability**: SystemCapability.ArkUI.ArkUI.Full 262 263 264## Example 265 266### Example 1: Playing an Animation Using Images of the Resource Type 267 268This example demonstrates how to play an animation using the **ImageAnimator** component with images of the Resource type. 269 270```ts 271// xxx.ets 272@Entry 273@Component 274struct ImageAnimatorExample { 275 @State state: AnimationStatus = AnimationStatus.Initial 276 @State reverse: boolean = false 277 @State iterations: number = 1 278 279 build() { 280 Column({ space: 10 }) { 281 ImageAnimator() 282 .images([ 283 { 284 src: $r('app.media.img1') 285 }, 286 { 287 src: $r('app.media.img2') 288 }, 289 { 290 src: $r('app.media.img3') 291 }, 292 { 293 src: $r('app.media.img4') 294 } 295 ]) 296 .duration(2000) 297 .state(this.state).reverse(this.reverse) 298 .fillMode(FillMode.None).iterations(this.iterations).width(340).height(240) 299 .margin({ top: 100 }) 300 .onStart(() => { 301 console.info('Start') 302 }) 303 .onPause(() => { 304 console.info('Pause') 305 }) 306 .onRepeat(() => { 307 console.info('Repeat') 308 }) 309 .onCancel(() => { 310 console.info('Cancel') 311 }) 312 .onFinish(() => { 313 console.info('Finish') 314 this.state = AnimationStatus.Stopped 315 }) 316 Row() { 317 Button('start').width(100).padding(5).onClick(() => { 318 this.state = AnimationStatus.Running 319 }).margin(5) 320 Button('pause').width(100).padding(5).onClick(() => { 321 this.state = AnimationStatus.Paused // Display the image of the current frame. 322 }).margin(5) 323 Button('stop').width(100).padding(5).onClick(() => { 324 this.state = AnimationStatus.Stopped // Display the image of the initial frame. 325 }).margin(5) 326 } 327 328 Row() { 329 Button('reverse').width(100).padding(5).onClick(() => { 330 this.reverse = !this.reverse 331 }).margin(5) 332 Button('once').width(100).padding(5).onClick(() => { 333 this.iterations = 1 334 }).margin(5) 335 Button('infinite').width(100).padding(5).onClick(() => { 336 this.iterations = -1 // The animation is played for an unlimited number of times. 337 }).margin(5) 338 } 339 }.width('100%').height('100%') 340 } 341} 342``` 343 344### Example 2: Playing an Animation Using Images of the PixelMap Type 345 346This example demonstrates how to play an animation using the **ImageAnimator** component with images of the PixelMap type. 347 348```ts 349// xxx.ets 350import { image } from '@kit.ImageKit' 351 352@Entry 353@Component 354struct ImageAnimatorExample { 355 imagePixelMap: Array<PixelMap> = [] 356 @State state: AnimationStatus = AnimationStatus.Initial 357 @State reverse: boolean = false 358 @State iterations: number = 1 359 @State images:Array<ImageFrameInfo> = [] 360 async aboutToAppear() { 361 this.imagePixelMap.push(await this.getPixmapFromMedia($r('app.media.icon'))) 362 this.images.push({src:this.imagePixelMap[0]}) 363 } 364 build() { 365 Column({ space: 10 }) { 366 ImageAnimator() 367 .images(this.images) 368 .duration(2000) 369 .state(this.state).reverse(this.reverse) 370 .fillMode(FillMode.None).iterations(this.iterations).width(340).height(240) 371 .margin({ top: 100 }) 372 .onStart(() => { 373 console.info('Start') 374 }) 375 .onPause(() => { 376 console.info('Pause') 377 }) 378 .onRepeat(() => { 379 console.info('Repeat') 380 }) 381 .onCancel(() => { 382 console.info('Cancel') 383 }) 384 .onFinish(() => { 385 console.info('Finish') 386 this.state = AnimationStatus.Stopped 387 }) 388 Row() { 389 Button('start').width(100).padding(5).onClick(() => { 390 this.state = AnimationStatus.Running 391 }).margin(5) 392 Button('pause').width(100).padding(5).onClick(() => { 393 this.state = AnimationStatus.Paused // Display the image of the current frame. 394 }).margin(5) 395 Button('stop').width(100).padding(5).onClick(() => { 396 this.state = AnimationStatus.Stopped // Display the image of the initial frame. 397 }).margin(5) 398 } 399 Row() { 400 Button('reverse').width(100).padding(5).onClick(() => { 401 this.reverse = !this.reverse 402 }).margin(5) 403 Button('once').width(100).padding(5).onClick(() => { 404 this.iterations = 1 405 }).margin(5) 406 Button('infinite').width(100).padding(5).onClick(() => { 407 this.iterations = -1 // The animation is played for an unlimited number of times. 408 }).margin(5) 409 } 410 }.width('100%').height('100%') 411 } 412 413 private async getPixmapFromMedia(resource: Resource) { 414 let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({ 415 bundleName: resource.bundleName, 416 moduleName: resource.moduleName, 417 id: resource.id 418 }) 419 let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength)) 420 let createPixelMap: image.PixelMap = await imageSource.createPixelMap({ 421 desiredPixelFormat: image.PixelMapFormat.RGBA_8888 422 }) 423 await imageSource.release() 424 return createPixelMap 425 } 426} 427``` 428 429 430 431### Example 3: Enabling Automatic Pause on Invisibility 432 433This example demonstrates how to use [monitorInvisibleArea](#monitorinvisiblearea18) to automatically pause the **ImageAnimator** component when it becomes invisible and resume playback when it becomes visible again. This behavior is controlled based on the component's [state](#state) being set to **AnimationStatus.Running**. 434 435```ts 436@Entry 437@Component 438struct ImageAnimatorAutoPauseTest { 439 scroller: Scroller = new Scroller() 440 @State state: AnimationStatus = AnimationStatus.Running 441 @State reverse: boolean = false 442 @State iterations: number = 100 443 @State preCallBack: string = "Null" 444 private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 445 446 build() { 447 Stack({ alignContent: Alignment.TopStart }) { 448 Scroll(this.scroller) { 449 Column() { 450 ImageAnimator() 451 .images([ 452 { 453 src: $r('app.media.Clouds') 454 }, 455 { 456 src: $r('app.media.landscape') 457 }, 458 { 459 src: $r('app.media.sky') 460 }, 461 { 462 src: $r('app.media.mountain') 463 } 464 ]) 465 .borderRadius(10) 466 .monitorInvisibleArea(true) 467 .clip(true).duration(4000).state(this.state).reverse(this.reverse) 468 .fillMode(FillMode.Forwards).iterations(this.iterations).width(340).height(240) 469 .margin({ top: 100 }) 470 .onStart(() => { 471 this.preCallBack = "Start" 472 console.info('ImageAnimator Start') 473 }) 474 .onPause(() => { 475 this.preCallBack = "Pause" 476 console.info('ImageAnimator Pause') 477 }) 478 .onRepeat(() => { 479 console.info('ImageAnimator Repeat') 480 }) 481 .onCancel(() => { 482 console.info('ImageAnimator Cancel') 483 }) 484 .onFinish(() => { 485 console.info('ImageAnimator Finish') 486 }) 487 ForEach(this.arr, (item: number) => { 488 Text(item.toString()) 489 .width('90%') 490 .height(150) 491 .backgroundColor(0xFFFFFF) 492 .borderRadius(15) 493 .fontSize(16) 494 .textAlign(TextAlign.Center) 495 .margin({ top: 10 }) 496 }, (item: string) => item) 497 }.width('100%') 498 } 499 .scrollable(ScrollDirection.Vertical) // The scrollbar scrolls in the vertical direction. 500 .scrollBar(BarState.On) // The scrollbar is always displayed. 501 .scrollBarColor(Color.Gray) // The scrollbar color is gray. 502 .scrollBarWidth(10) // The scrollbar width is 10. 503 .friction(0.6) 504 .edgeEffect(EdgeEffect.None) 505 .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => { 506 console.info(xOffset + ' ' + yOffset) 507 }) 508 .onScrollEdge((side: Edge) => { 509 console.info('To the edge') 510 }) 511 .onScrollStop(() => { 512 console.info('Scroll Stop') 513 }) 514 Text("Last triggered callback (Pause/Start): " + this.preCallBack) 515 .margin({ top: 60, left: 20 }) 516 }.width('100%').height('100%').backgroundColor(0xDCDCDC) 517 } 518} 519``` 520 521 522