1# ImageAnimator
2
3提供帧动画组件来实现逐帧播放图片的能力,可以配置需要播放的图片列表,每张图片可以配置时长。
4
5>  **说明:**
6>
7> 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
8
9
10
11## 子组件
12
1314
15
16## 接口
17
18ImageAnimator()
19
20**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
21
22**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
23
24**系统能力:** SystemCapability.ArkUI.ArkUI.Full
25
26## 属性
27
28除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:
29
30### images
31
32images(value: Array<ImageFrameInfo>)
33
34设置图片帧信息集合。不支持动态更新。
35
36**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
37
38**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
39
40**系统能力:** SystemCapability.ArkUI.ArkUI.Full
41
42**参数:** 
43
44| 参数名 | 类型                                                   | 必填 | 说明                                                         |
45| ------ | ------------------------------------------------------ | ---- | ------------------------------------------------------------ |
46| value  | Array&lt;[ImageFrameInfo](#imageframeinfo对象说明)&gt; | 是   | 设置图片帧信息集合。每一帧的帧信息(ImageFrameInfo)包含图片路径、图片大小、图片位置和图片播放时长信息,详见ImageFrameInfo属性说明。<br/>默认值:[] |
47
48### state
49
50state(value: AnimationStatus)
51
52控制播放状态。
53
54**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
55
56**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
57
58**系统能力:** SystemCapability.ArkUI.ArkUI.Full
59
60**参数:** 
61
62| 参数名 | 类型                                                    | 必填 | 说明                                                         |
63| ------ | ------------------------------------------------------- | ---- | ------------------------------------------------------------ |
64| value  | [AnimationStatus](ts-appendix-enums.md#animationstatus) | 是   | 默认为初始状态,用于控制播放状态。<br/>默认值:AnimationStatus.Initial |
65
66### duration
67
68duration(value: number)
69
70设置播放时长。当Images中任意一帧图片设置了单独的duration后,该属性设置无效。
71
72**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
73
74**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
75
76**系统能力:** SystemCapability.ArkUI.ArkUI.Full
77
78**参数:** 
79
80| 参数名 | 类型   | 必填 | 说明                                                         |
81| ------ | ------ | ---- | ------------------------------------------------------------ |
82| value  | number | 是   | 播放时长。<br/>value为0时,不播放图片。<br/>value的改变只会在下一次循环开始时生效。<br/>单位:毫秒<br/>默认值:1000ms |
83
84### reverse
85
86reverse(value: boolean)
87
88设置播放方向。
89
90**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
91
92**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
93
94**系统能力:** SystemCapability.ArkUI.ArkUI.Full
95
96**参数:** 
97
98| 参数名 | 类型    | 必填 | 说明                                                         |
99| ------ | ------- | ---- | ------------------------------------------------------------ |
100| value  | boolean | 是   | 播放方向。<br/>false表示从第1张图片播放到最后1张图片,true表示从最后1张图片播放到第1张图片。<br/>默认值:false |
101
102### fixedSize
103
104fixedSize(value: boolean)
105
106设置图片大小是否固定为组件大小。
107
108**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
109
110**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
111
112**系统能力:** SystemCapability.ArkUI.ArkUI.Full
113
114**参数:** 
115
116| 参数名 | 类型    | 必填 | 说明                                                         |
117| ------ | ------- | ---- | ------------------------------------------------------------ |
118| value  | boolean | 是   | 设置图片大小是否固定为组件大小。&nbsp;true表示图片大小与组件大小一致,此时设置图片的width&nbsp;、height&nbsp;、top&nbsp;和left属性是无效的。false表示每一张图片的width&nbsp;、height&nbsp;、top和left属性都要单独设置。<br/>默认值:true |
119
120### preDecode<sup>(deprecated)</sup>
121
122preDecode(value: number)
123
124设置预解码的图片数量。
125
126从API version 9开始废弃。
127
128**系统能力:** SystemCapability.ArkUI.ArkUI.Full
129
130**参数:** 
131
132| 参数名 | 类型   | 必填 | 说明                                                         |
133| ------ | ------ | ---- | ------------------------------------------------------------ |
134| value  | number | 是   | 预解码的图片数量。例如该值设为2,则播放当前页时会提前加载后面两张图片至缓存以提升性能。<br/>默认值:0 |
135
136### fillMode
137
138fillMode(value: FillMode)
139
140设置当前播放方向下,动画开始前和结束后的状态。动画结束后的状态由fillMode和reverse属性共同决定。例如,fillMode为Forwards表示停止时维持动画最后一个关键帧的状态,若reverse为false则维持正播的最后一帧,即最后一张图,若reverse为true则维持逆播的最后一帧,即第一张图。
141
142**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
143
144**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
145
146**系统能力:** SystemCapability.ArkUI.ArkUI.Full
147
148**参数:** 
149
150| 参数名 | 类型                                      | 必填 | 说明                                                         |
151| ------ | ----------------------------------------- | ---- | ------------------------------------------------------------ |
152| value  | [FillMode](ts-appendix-enums.md#fillmode) | 是   | 当前播放方向下,动画开始前和结束后的状态。<br/>默认值:FillMode.Forwards |
153
154### iterations
155
156iterations(value: number)
157
158设置播放次数。
159
160**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
161
162**系统能力:** SystemCapability.ArkUI.ArkUI.Full
163
164**参数:** 
165
166| 参数名 | 类型   | 必填 | 说明                                                   |
167| ------ | ------ | ---- | ------------------------------------------------------ |
168| value  | number | 是   | 默认播放一次,设置为-1时表示无限次播放。<br/>默认值:1 |
169
170## ImageFrameInfo对象说明
171
172**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
173
174**系统能力:** SystemCapability.ArkUI.ArkUI.Full
175
176| 名称   | 类型   | 必填 | 说明 |
177| -------- | -------------- | -------- | -------- |
178| src      | string \| [Resource](ts-types.md#resource)<sup>9+</sup> \| [PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)<sup>12+</sup> | 是    | 图片路径,图片格式为jpg、jpeg、svg、png、bmp、webp、ico和heif,从API Version9开始支持[Resource](ts-types.md#resource)类型的路径,从API version 12开始支持[PixelMap](../../apis-image-kit/js-apis-image.md#pixelmap7)类型。 <br/>**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。|
179| width    | number&nbsp;\|&nbsp;string | 否  | 图片宽度。<br/>默认值:0   <br/>**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用       |
180| height   | number&nbsp;\|&nbsp;string | 否  | 图片高度。<br/>默认值:0     <br/>**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用        |
181| top      | number&nbsp;\|&nbsp;string | 否  | 图片相对于组件左上角的纵向坐标。<br/>默认值:0  <br/>**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用  |
182| left     | number&nbsp;\|&nbsp;string | 否  | 图片相对于组件左上角的横向坐标。<br/>默认值:0 <br/>**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用   |
183| duration | number          | 否     | 每一帧图片的播放时长,单位毫秒。<br/>默认值:0         |
184
185## 事件
186
187除支持[通用事件](ts-universal-events-click.md)外,还支持以下事件:
188
189### onStart
190
191onStart(event:&nbsp;()&nbsp;=&gt;&nbsp;void)
192
193状态回调,动画开始播放时触发。
194
195**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
196
197**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
198
199**系统能力:** SystemCapability.ArkUI.ArkUI.Full
200
201### onPause
202
203onPause(event:&nbsp;()&nbsp;=&gt;&nbsp;void)
204
205状态回调,动画暂停播放时触发。
206
207**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
208
209**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
210
211**系统能力:** SystemCapability.ArkUI.ArkUI.Full
212
213### onRepeat
214
215onRepeat(event:&nbsp;()&nbsp;=&gt;&nbsp;void)
216
217状态回调,动画重复播放时触发。
218
219**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
220
221**系统能力:** SystemCapability.ArkUI.ArkUI.Full
222
223### onCancel
224
225onCancel(event:&nbsp;()&nbsp;=&gt;&nbsp;void)
226
227状态回调,动画返回最初状态时触发。
228
229**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
230
231**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
232
233**系统能力:** SystemCapability.ArkUI.ArkUI.Full
234
235### onFinish
236
237onFinish(event:&nbsp;()&nbsp;=&gt;&nbsp;void)
238
239状态回调,动画播放完成时或者停止播放时触发。 
240
241**卡片能力:** 从API version 10开始,该接口支持在ArkTS卡片中使用。
242
243**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
244
245**系统能力:** SystemCapability.ArkUI.ArkUI.Full
246
247
248## 示例
249
250### 播放Resource动画
251
252```ts
253// xxx.ets
254@Entry
255@Component
256struct ImageAnimatorExample {
257  @State state: AnimationStatus = AnimationStatus.Initial
258  @State reverse: boolean = false
259  @State iterations: number = 1
260
261  build() {
262    Column({ space: 10 }) {
263      ImageAnimator()
264        .images([
265          {
266            src: $r('app.media.img1')
267          },
268          {
269            src: $r('app.media.img2')
270          },
271          {
272            src: $r('app.media.img3')
273          },
274          {
275            src: $r('app.media.img4')
276          }
277        ])
278        .duration(2000)
279        .state(this.state).reverse(this.reverse)
280        .fillMode(FillMode.None).iterations(this.iterations).width(340).height(240)
281        .margin({ top: 100 })
282        .onStart(() => {
283          console.info('Start')
284        })
285        .onPause(() => {
286          console.info('Pause')
287        })
288        .onRepeat(() => {
289          console.info('Repeat')
290        })
291        .onCancel(() => {
292          console.info('Cancel')
293        })
294        .onFinish(() => {
295          console.info('Finish')
296          this.state = AnimationStatus.Stopped
297        })
298      Row() {
299        Button('start').width(100).padding(5).onClick(() => {
300          this.state = AnimationStatus.Running
301        }).margin(5)
302        Button('pause').width(100).padding(5).onClick(() => {
303          this.state = AnimationStatus.Paused     // 显示当前帧图片
304        }).margin(5)
305        Button('stop').width(100).padding(5).onClick(() => {
306          this.state = AnimationStatus.Stopped    // 显示动画的起始帧图片
307        }).margin(5)
308      }
309
310      Row() {
311        Button('reverse').width(100).padding(5).onClick(() => {
312          this.reverse = !this.reverse
313        }).margin(5)
314        Button('once').width(100).padding(5).onClick(() => {
315          this.iterations = 1
316        }).margin(5)
317        Button('infinite').width(100).padding(5).onClick(() => {
318          this.iterations = -1 // 无限循环播放
319        }).margin(5)
320      }
321    }.width('100%').height('100%')
322  }
323}
324```
325
326### 播放PixelMap动画
327
328```ts
329import { image } from '@kit.ImageKit'
330
331@Entry
332@Component
333struct ImageAnimatorExample {
334  imagePixelMap: Array<PixelMap> = []
335  @State state: AnimationStatus = AnimationStatus.Initial
336  @State reverse: boolean = false
337  @State iterations: number = 1
338  @State images:Array<ImageFrameInfo> = []
339  async aboutToAppear() {
340    this.imagePixelMap.push(await this.getPixmapFromMedia($r('app.media.icon')))
341    this.images.push({src:this.imagePixelMap[0]})
342  }
343  build() {
344    Column({ space: 10 }) {
345      ImageAnimator()
346        .images(this.images)
347        .duration(2000)
348        .state(this.state).reverse(this.reverse)
349        .fillMode(FillMode.None).iterations(this.iterations).width(340).height(240)
350        .margin({ top: 100 })
351        .onStart(() => {
352          console.info('Start')
353        })
354        .onPause(() => {
355          console.info('Pause')
356        })
357        .onRepeat(() => {
358          console.info('Repeat')
359        })
360        .onCancel(() => {
361          console.info('Cancel')
362        })
363        .onFinish(() => {
364          console.info('Finish')
365          this.state = AnimationStatus.Stopped
366        })
367      Row() {
368        Button('start').width(100).padding(5).onClick(() => {
369          this.state = AnimationStatus.Running
370        }).margin(5)
371        Button('pause').width(100).padding(5).onClick(() => {
372          this.state = AnimationStatus.Paused     // 显示当前帧图片
373        }).margin(5)
374        Button('stop').width(100).padding(5).onClick(() => {
375          this.state = AnimationStatus.Stopped    // 显示动画的起始帧图片
376        }).margin(5)
377      }
378      Row() {
379        Button('reverse').width(100).padding(5).onClick(() => {
380          this.reverse = !this.reverse
381        }).margin(5)
382        Button('once').width(100).padding(5).onClick(() => {
383          this.iterations = 1
384        }).margin(5)
385        Button('infinite').width(100).padding(5).onClick(() => {
386          this.iterations = -1 // 无限循环播放
387        }).margin(5)
388      }
389    }.width('100%').height('100%')
390  }
391
392  private async getPixmapFromMedia(resource: Resource) {
393    let unit8Array = await getContext(this)?.resourceManager?.getMediaContent({
394      bundleName: resource.bundleName,
395      moduleName: resource.moduleName,
396      id: resource.id
397    })
398    let imageSource = image.createImageSource(unit8Array.buffer.slice(0, unit8Array.buffer.byteLength))
399    let createPixelMap: image.PixelMap = await imageSource.createPixelMap({
400      desiredPixelFormat: image.PixelMapFormat.RGBA_8888
401    })
402    await imageSource.release()
403    return createPixelMap
404  }
405}
406```
407
408![imageAnimator](figures/imageAnimator.gif)