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 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 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 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 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 467