# 10.2:帧动画

帧动画也叫序列帧动画,其原理就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。ArkUI开发框架提供了 ImageAnimator 组件实现帧动画能力,本节笔者介绍一下 ImageAnimator 组件的简单使用。

# 10.2.1:ImageAnimator定义介绍

interface ImageAnimatorInterface {
  (): ImageAnimatorAttribute;
}
1
2
3

由源码可知,ImageAnimator 组件不需要设置额外的配置参数。

# 10.2.2:ImageAnimator属性介绍

declare class ImageAnimatorAttribute extends CommonMethod<ImageAnimatorAttribute> {
  images(
    value: Array<{
      src: string;
      width?: number | string;
      height?: number | string;
      top?: number | string;
      left?: number | string;
      duration?: number;
    }>,
  ): ImageAnimatorAttribute;
  state(value: AnimationStatus): ImageAnimatorAttribute;
  duration(value: number): ImageAnimatorAttribute;
  reverse(value: boolean): ImageAnimatorAttribute;
  fixedSize(value: boolean): ImageAnimatorAttribute;
  preDecode(value: number): ImageAnimatorAttribute;
  fillMode(value: FillMode): ImageAnimatorAttribute;
  iterations(value: number): ImageAnimatorAttribute;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • images:设置图片帧信息集合。每一帧的帧信息包含图片路径、图片大小、图片位置和图片播放时长信息。详细说明如下:
    • src:图片路径,图片格式为 svgpngjpgwebp
    • width:图片宽度。
    • height:图片高度。
    • top:图片相对于组件左上角的纵向坐标。
    • left:图片相对于组件左上角的横向坐标。
    • duration:每一帧图片的播放时长,单位毫秒。
  • state:设置播放状态, AnimationStatus 定义了以下 4 中状态:
    • Initial(默认值):动画初始状态。
    • Running:动画处于播放状态。
    • Paused:动画处于暂停状态。
    • Stopped:动画处于停止状态。
  • fixedSize:设置图片大小是否固定为组件大小。 true 表示图片大小与组件大小一致,此时设置图片的 widthheighttopleft 属性是无效的。 false 表示每一张图片的 widthheighttopleft 属性都要单独设置。
  • preDecode:是否启用预解码,默认值为 0 ,即不启用预解码,如该值设为 2 ,则播放当前页时会提前加载后面两张图片至缓存以提升性能。
  • fillMode:设置动画开始前和结束后的状态, FillMode 参数类型说明如下:
    • None:播放完成后恢复初始状态。
    • Forwards:播放完成后保持动画结束时的状态。
  • iterations:设置播放次数,设置为 -1 时表示无限次播放。

简单样例如下所示:

@Entry @Component struct ImageAnimatorTest {

  build() {
    Column({ space: 10 }) {
      ImageAnimator()
        .images([                         // 序列帧资源数组
          {
            src: "/pages/loading_01.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_02.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_03.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_04.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_05.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_06.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_07.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_08.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_09.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_10.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_11.png", // 图片帧资源
            duration: 150                 // 播放时长
          },
          {
            src: "/pages/loading_12.png", // 图片帧资源
            duration: 150                 // 播放时长
          }
        ])
        .state(AnimationStatus.Running)   // 设置正在播放状态
        .iterations(-1)                   // 设置无限循环播放
        .preDecode(2)                     // 预加载2张图片
        .width(60)
        .height(60)
    }
    .width('100%')
    .height("100%")
    .padding(10)
  }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

样例运行效果如下图所示:

10_2_2_1

# 10.2.3:ImageAnimator事件介绍

declare class ImageAnimatorAttribute extends CommonMethod<ImageAnimatorAttribute> {
  onStart(event: () => void): ImageAnimatorAttribute;
  onPause(event: () => void): ImageAnimatorAttribute;
  onRepeat(event: () => void): ImageAnimatorAttribute;
  onCancel(event: () => void): ImageAnimatorAttribute;
  onFinish(event: () => void): ImageAnimatorAttribute;
}
1
2
3
4
5
6
7
  • onStart:状态回调,动画开始播放时触发。
  • onPause:状态回调,动画暂停播放时触发。
  • onRepeat:状态回调,动画重新播放时触发。
  • onCancel:状态回调,动画取消播放时触发。
  • onFinish:状态回调,动画播放完成时触发。

# 10.2.4:ImageAnimator完整样例

@Entry @Component struct ImageAnimatorTest {

  @State state: AnimationStatus = AnimationStatus.Initial
  @State reverse: boolean = false
  @State iterations: number = 1

  build() {
    Column({ space: 10 }) {
      ImageAnimator()
        .images([
          {
            src: '/pages/test_01.webp',
            duration: 500,
            width: 325,
            height: 200,
            top: 0,
            left: 0
          },
          {
            src: '/pages/test_02.webp',
            duration: 500,
            width: 325,
            height: 200,
            top: 0,
            left: 0
          },
          {
            src: '/pages/test_03.webp',
            duration: 500,
            width: 325,
            height: 200,
            top: 0,
            left: 0
          },
          {
            src: '/pages/test_04.webp',
            duration: 500,
            width: 325,
            height: 200,
            top: 0,
            left: 0
          }
        ])
        .state(this.state)
        .reverse(this.reverse)
        .fixedSize(false)
        .preDecode(2)
        .fillMode(FillMode.None)
        .iterations(this.iterations)
        .width(325)
        .height(210)
        .onStart(() => {
          console.info('Start')
        })
        .onPause(() => {
          console.info('Pause')
        })
        .onRepeat(() => {
          console.info('Repeat')
        })
        .onCancel(() => {
          console.info('Cancel')
        })
        .onFinish(() => {
          console.info('Finish')
        })
      Row({space: 5}) {
        Button('start')
          .width(100)
          .padding(5)
          .onClick(() => {
            this.state = AnimationStatus.Running
          })
        Button('pause')
          .width(100)
          .padding(5)
          .onClick(() => {
            this.state = AnimationStatus.Paused
          })
        Button('stop')
          .width(100)
          .padding(5)
          .onClick(() => {
            this.state = AnimationStatus.Stopped
          })
      }

      Row({space: 5}) {
        Button('reverse')
          .width(100)
          .padding(5)
          .onClick(() => {
            this.reverse = !this.reverse
          })
        Button('once')
          .width(100)
          .padding(5)
          .onClick(() => {
            this.iterations = 1
          })
        Button('iteration')
          .width(100)
          .padding(5)
          .onClick(() => {
            this.iterations = -1
          })
      }
    }
    .width('100%')
    .height('100%')
    .padding(10)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

样例运行结果如下图所示:

10_2_4_1
(adsbygoogle = window.adsbygoogle || []).push({});
请作者喝杯咖啡

津公网安备 12011402001367号

津ICP备2020008934号-2

中央网信办互联网违法和不良信息举报中心

天津市互联网违法和不良信息举报中心