• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 组件动画
2
3在组件上创建和运行动画的快捷方式。具体用法请参考[通用方法](../reference/arkui-js/js-components-common-methods.md)。
4
5
6## 获取动画对象
7
8通过调用animate方法获得animation对象,animation对象支持动画属性、动画方法和动画事件。
9
10```html
11<!-- xxx.hml -->
12<div class="container">
13  <div id="content" class="box" onclick="Show"></div>
14</div>
15```
16
17```css
18/* xxx.css */
19.container {
20  flex-direction: column;
21  justify-content: center;
22  align-items: center;
23  width: 100%;
24}
25.box{
26  width: 200px;
27  height: 200px;
28  background-color: #ff0000;
29  margin-top: 30px;
30}
31```
32
33```js
34/* xxx.js */
35export default {
36  data: {
37    animation: '',
38  },
39  onInit() {
40  },
41  onShow() {
42    var options = {
43      duration: 1500,
44    };
45    var frames = [
46      {
47        width:200,height:200,
48      },
49      {
50        width:300,height:300,
51      }
52    ];
53    this.animation = this.$element('content').animate(frames, options);  //获取动画对象
54  },
55  Show() {
56    this.animation.play();
57  }
58}
59```
60
61![zh-cn_image_0000001175235138](figures/zh-cn_image_0000001175235138.gif)
62
63> **说明:**
64> -   使用animate方法时必须传入Keyframes和Options参数。
65> -   多次调用animate方法时,采用replace策略,即最后一次调用时传入的参数生效。
66
67
68## 设置动画参数
69
70在获取动画对象后,通过设置参数Keyframes设置动画在组件上的样式。
71
72```html
73<!-- xxx.hml -->
74<div class="container">
75   <div id="content" class="box" onclick="Show"></div>
76</div>
77```
78
79```css
80/* xxx.css */
81.container {
82  flex-direction: column;
83  justify-content: center;
84  align-items: center;
85  width: 100%;
86  height: 100%;
87}
88.box{
89  width: 200px;
90  height: 200px;
91  background-color: #ff0000;
92  margin-top: 30px;
93}
94```
95
96```js
97/* xxx.js */
98export default {
99  data: {
100    animation: '',
101    keyframes:{},
102    options:{}
103  },
104  onInit() {
105    this.options = {
106      duration: 4000,
107    }
108    this.keyframes = [
109    {
110      transform: {
111        translate: '-120px -0px',
112        scale: 1,
113        rotate: 0
114        },
115        transformOrigin: '100px 100px',
116        offset: 0.0,
117        width: 200,
118        height: 200
119      },
120      {
121        transform: {
122          translate: '120px 0px',
123          scale: 1.5,
124          rotate: 90
125          },
126          transformOrigin: '100px 100px',
127          offset: 1.0,
128          width: 300,
129          height: 300
130      }
131    ]
132  },
133  Show() {
134    this.animation = this.$element('content').animate(this.keyframes, this.options)
135    this.animation.play()
136  }
137}
138```
139
140![zh-cn_image_0000001174916742](figures/zh-cn_image_0000001174916742.gif)
141
142> **说明:**
143> - translate、scale和rtotate的先后顺序会影响动画效果。
144>
145> - transformOrigin只对scale和rtotate起作用。
146
147在获取动画对象后,通过设置参数Options来设置动画的属性。
148
149```html
150<!-- xxx.hml -->
151<div class="container">
152   <div id="content" class="box" onclick="Show"></div>
153</div>
154```
155
156```css
157/* xxx.css */
158.container {
159  flex-direction: column;
160  justify-content: center;
161  align-items: center;
162  width: 100%;
163}
164.box{
165  width: 200px;
166  height: 200px;
167  background-color: #ff0000;
168  margin-top: 30px;
169}
170```
171
172```js
173/* xxx.js */
174export default {
175  data: {
176    animation: '',
177  },
178  onInit() {
179  },
180  onShow() {
181    var options = {
182        duration: 1500,
183        easing: 'ease-in',
184        delay: 5,
185        iterations: 2,
186        direction: 'normal',
187    };
188    var frames = [
189      {
190        transform: {
191          translate: '-150px -0px'
192        }
193      },
194      {
195        transform: {
196          translate: '150px 0px'
197        }
198      }
199    ];
200    this.animation = this.$element('content').animate(frames, options);
201  },
202  Show() {
203    this.animation.play();
204  }
205}
206```
207
208![zh-cn_image_0000001220396499](figures/zh-cn_image_0000001220396499.gif)
209
210> **说明:**
211> direction:指定动画的播放模式。
212>
213> normal: 动画正向循环播放。
214>
215> reverse: 动画反向循环播放。
216>
217> alternate:动画交替循环播放,奇数次正向播放,偶数次反向播放。
218>
219> alternate-reverse:动画反向交替循环播放,奇数次反向播放,偶数次正向播放。
220
221
222## 添加事件和调用方法
223
224animation对象支持动画事件和动画方法。可以通过添加开始和取消事件,调用播放、暂停、倒放和结束方法实现预期动画。
225
226```html
227<!-- xxx.hml -->
228<div class="container">
229    <div id="content" style="width: 350px;height: 350px;margin-top: 100px;background: linear-gradient(pink, purple);">
230    </div>
231    <div class="row">
232        <button type="capsule" value="play" onclick="playAnimation"></button>
233        <button type="capsule" value="pause" onclick="pauseAnimation"></button>
234    </div>
235    <div class="row1">
236        <button type="capsule" value="reverse" onclick="reverseAnimation"></button>
237        <button type="capsule" value="cancel" onclick="cancelAnimation"></button>
238    </div>
239</div>
240```
241
242```css
243/* xxx.css */
244.container {
245  flex-direction: column;
246  align-items: center;
247  justify-content: center;
248  width: 100%;
249  height: 100%;
250}
251button{
252  width: 200px;
253}
254.row{
255  width: 65%;
256  height: 100px;
257  align-items: center;
258  justify-content: space-between;
259  margin-top: 40px;
260  position: fixed;
261  top: 65%;
262  left: 120px;
263}
264.row1{
265  width: 65%;
266  height: 100px;
267  align-items: center;
268  justify-content: space-between;
269  margin-top: 30px;
270  position: fixed;
271  top: 75%;
272  left: 120px;
273}
274```
275
276```js
277// xxx.js
278export default {
279    data: {
280        animation: '',
281    },
282    onShow() {
283        var options = {
284            duration: 1500,
285            easing:'ease-in',
286            delay:5,
287            direction:'normal',
288            iterations:2
289        };
290        var frames = [
291            {
292                transform: {
293                    translate: '-150px -0px'
294                },
295                opacity: 0.1,
296                offset: 0.0,
297                width: 200,
298                height: 200,
299            },
300            {
301                transform: {
302                    translate: '150px 0px'
303                },
304                opacity: 1.0,
305                offset: 1.0,
306                width: 300,
307                height: 300,
308            }
309        ];
310        this.animation = this.$element('content').animate(frames, options);
311        this.animation.onstart = function() {
312            console.info('animation start')
313        }  // 添加开始事件
314        this.animation.onrepeat = function() {
315            console.info('animation repeated')
316        }  // 添加重播事件
317        this.animation.oncancel = function() {
318            console.info('animation canceled')
319        }   // 添加取消事件
320        this.animation.onfinish = function() {
321            console.info('animation finish')
322        }   // 添加完成事件
323    },
324    playAnimation() {
325        this.animation.play()  // 调用播放开始的方法
326    },
327    pauseAnimation() {
328        this.animation.pause()  // 调用播放暂停的方法
329    },
330    reverseAnimation() {
331        this.animation.reverse()  // 调用播放倒放的方法
332    },
333    cancelAnimation() {
334        this.animation.cancel()  // 调用播放取消的方法
335    }
336}
337```
338
339![zh-cn_image_0000001220635011](figures/zh-cn_image_0000001220635011.gif)
340
341通过改变playState的值实现动画状态的改变。
342
343```html
344<!-- xxx.hml -->
345<div class="container">
346  <div id="content" style="width: 350px;height: 350px;margin-top: 100px;background: linear-gradient(pink, purple);">
347  </div>
348  <div class="row">
349     <button type="capsule" value="{{state}}" onclick="playStateClick"></button>
350  </div>
351  <div class="row1">
352     <button type="capsule" value="{{state1}}" onclick="playStateClick1"></button>
353  </div>
354</div>
355```
356
357```css
358/* xxx.css */
359.container {
360  flex-direction: column;
361  align-items: center;
362  justify-content: center;
363}
364button{
365  width: 200px;
366}
367.row{
368  width: 65%;
369  height: 100px;
370  align-items: center;
371  justify-content: space-between;
372  margin-top: 50px;
373  margin-left: 260px;
374  position: fixed;
375  top: 65%;
376}
377.row1{
378  width: 65%;
379  height: 100px;
380  align-items: center;
381  justify-content: space-between;
382  margin-top: 50px;
383   margin-left: 260px;
384  position: fixed;
385  top: 75%;
386}
387```
388
389```js
390// xxx.js
391import promptAction from '@ohos.promptAction';
392export default {
393  data: {
394    animation: '',
395    state:'play',
396    state1:'play'
397  },
398  onInit() {
399  },
400  onShow() {
401    var options = {
402      duration: 1500,
403      easing:'ease-in',
404      elay:5,
405      direction:'normal',
406      iterations:2,
407    };
408    var frames = [
409      {
410        transform: {
411          translate: '-150px -0px'
412        },
413        opacity: 0.1,
414        offset: 0.0,
415        width: 200,
416        height: 200,
417      },
418      {
419        transform: {
420          translate: '150px 0px'
421        },
422          opacity: 1.0,
423          offset: 1.0,
424          width: 300,
425          height: 300,
426        }
427      ];
428      this.animation = this.$element('content').animate(frames, options);
429      this.animation.onstart = function(){
430        promptAction.showToast({
431          message: "start"
432        });
433      };
434      this.animation.onrepeat = function(){
435        promptAction.showToast({
436          message: " repeated"
437        });
438      };
439      this.animation.onfinish = function(){
440        promptAction.showToast({
441          message: " finished"
442      });
443    };
444  },
445  playStateClick(){
446    if(this.animation.playState != 'running'){
447      this.animation.playState = 'running';//设置playState为running,动画运行。
448      this.state = 'pause'
449    }else{
450      this.animation.playState = 'paused';//设置playState为paused,动画暂停。
451      this.state = 'play'
452    }
453  },
454  playStateClick1(){
455    if(this.animation.playState != 'running'){
456      this.animation.playState = 'running';
457      this.state1 = 'finish'
458    }else{
459      this.animation.playState = 'finished';//设置playState为finished,动画结束。
460      this.state1 = 'play'
461    }
462  }
463}
464```
465
466![zh-cn_image_0000001175075286](figures/zh-cn_image_0000001175075286.gif)
467