1# @ohos.animator (动画) 2 3本模块提供组件动画效果,包括定义动画、启动动画和以相反的顺序播放动画等。 4 5> **说明:** 6> 7> 本模块首批接口从API version 6开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 8> 9> 本模块从API version 9开始支持在ArkTS中使用。 10> 11> 该模块不支持在[UIAbility](./js-apis-app-ability-uiAbility.md)的文件声明处使用,即不能在UIAbility的生命周期中调用,需要在创建组件实例后使用。 12> 13> 本模块功能依赖UI的执行上下文,不可在UI上下文不明确的地方使用,参见[UIContext](./js-apis-arkui-UIContext.md#uicontext)说明。 14> 15> 从API version 10开始,可以通过使用[UIContext](./js-apis-arkui-UIContext.md#uicontext)中的[createAnimator](./js-apis-arkui-UIContext.md#createanimator)来明确UI的执行上下文。 16 17## 导入模块 18 19```ts 20import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 21``` 22## create<sup>9+</sup> 23 24create(options: AnimatorOptions): AnimatorResult 25 26定义Animator类。 27 28**系统能力:** SystemCapability.ArkUI.ArkUI.Full 29 30**参数:** 31 32| 参数名 | 类型 | 必填 | 说明 | 33| ------- | ----------------------------------- | ---- | ------- | 34| options | [AnimatorOptions](#animatoroptions) | 是 | 定义动画选项。 | 35 36**返回值:** 37 38| 类型 | 说明 | 39| --------------------------------- | ------------- | 40| [AnimatorResult](#animatorresult) | Animator结果接口。 | 41 42**示例:** 43 44 ```ts 45import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 46let options: AnimatorOptions = { 47 duration: 1500, 48 easing: "friction", 49 delay: 0, 50 fill: "forwards", 51 direction: "normal", 52 iterations: 3, 53 begin: 200.0, 54 end: 400.0 55}; 56animator.create(options); 57 ``` 58 59## AnimatorResult 60 61定义Animator结果接口。 62 63### reset<sup>9+</sup> 64 65reset(options: AnimatorOptions): void 66 67更新当前动画器。 68 69**系统能力:** SystemCapability.ArkUI.ArkUI.Full 70 71**参数:** 72 73| 参数名 | 类型 | 必填 | 说明 | 74| ------- | ----------------------------------- | ---- | ------- | 75| options | [AnimatorOptions](#animatoroptions) | 是 | 定义动画选项。 | 76 77**错误码:** 78 79以下错误码的详细介绍请参见[ohos.animator(动画)](../errorcodes/errorcode-animator.md)错误码。 80 81| 错误码ID | 错误信息 | 82| --------- | ------- | 83| 100001 | if no page is found for pageId or fail to get object property list. | 84 85 86**示例:** 87 88```ts 89import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 90import { BusinessError } from '@ohos.base'; 91let options: AnimatorOptions = { 92 duration: 1500, 93 easing: "friction", 94 delay: 0, 95 fill: "forwards", 96 direction: "normal", 97 iterations: 3, 98 begin: 200.0, 99 end: 400.0 100}; 101let optionsNew: AnimatorOptions = { 102 duration: 1500, 103 easing: "friction", 104 delay: 0, 105 fill: "forwards", 106 direction: "normal", 107 iterations: 5, 108 begin: 200.0, 109 end: 400.0 110}; 111try { 112 let animatorResult:AnimatorResult|undefined = animator.create(options) 113 animatorResult.reset(optionsNew); 114} catch(error) { 115 let message = (error as BusinessError).message 116 let code = (error as BusinessError).code 117 console.error(`Animator reset failed, error code: ${code}, message: ${message}.`); 118} 119``` 120 121### play 122 123play(): void 124 125启动动画。动画会保留上一次的播放状态,比如播放状态设置reverse后,再次播放会保留reverse的播放状态。 126 127**系统能力:** SystemCapability.ArkUI.ArkUI.Full 128 129**示例:** 130 131```ts 132animator.play(); 133``` 134 135### finish 136 137finish(): void 138 139结束动画。 140 141**系统能力:** SystemCapability.ArkUI.ArkUI.Full 142 143**示例:** 144 145```ts 146animator.finish(); 147``` 148 149### pause 150 151pause(): void 152 153暂停动画。 154 155**系统能力:** SystemCapability.ArkUI.ArkUI.Full 156 157**示例:** 158 159```ts 160animator.pause(); 161``` 162 163### cancel 164 165cancel(): void 166 167删除动画。 168 169**系统能力:** SystemCapability.ArkUI.ArkUI.Full 170 171**示例:** 172 173```ts 174animator.cancel(); 175``` 176 177### reverse 178 179reverse(): void 180 181以相反的顺序播放动画。 182 183**系统能力:** SystemCapability.ArkUI.ArkUI.Full 184 185**示例:** 186 187```ts 188animator.reverse(); 189``` 190 191### onframe 192 193onframe: (progress: number) => void 194 195接收到帧时回调。 196 197**系统能力:** SystemCapability.ArkUI.ArkUI.Full 198 199**参数:** 200 201| 参数名 | 类型 | 必填 | 说明 | 202| -------- | ------ | ---- | -------- | 203| progress | number | 是 | 动画的当前进度。 | 204 205**示例:** 206 207```ts 208import animator, { AnimatorResult } from '@ohos.animator'; 209let animatorResult:AnimatorResult|undefined = animator.create(options) 210animatorResult.onframe = (value)=> { 211 console.info("onframe callback") 212} 213``` 214 215### onfinish 216 217onfinish: () => void 218 219动画完成时回调。 220 221**系统能力:** SystemCapability.ArkUI.ArkUI.Full 222 223**示例:** 224 225```ts 226import animator, { AnimatorResult } from '@ohos.animator'; 227let animatorResult:AnimatorResult|undefined = animator.create(options) 228animatorResult.onfinish = ()=> { 229 console.info("onfinish callback") 230} 231``` 232 233### oncancel 234 235oncancel: () => void 236 237动画被取消时回调。 238 239**系统能力:** SystemCapability.ArkUI.ArkUI.Full 240 241**示例:** 242 243```ts 244import animator, { AnimatorResult } from '@ohos.animator'; 245let animatorResult:AnimatorResult|undefined = animator.create(options) 246animatorResult.oncancel = ()=> { 247 console.info("oncancel callback") 248} 249``` 250 251### onrepeat 252 253onrepeat: () => void 254 255动画重复时回调。 256 257**系统能力:** SystemCapability.ArkUI.ArkUI.Full 258 259**示例:** 260 261```ts 262import animator, { AnimatorResult } from '@ohos.animator'; 263let animatorResult:AnimatorResult|undefined = animator.create(options) 264animatorResult.onrepeat = ()=> { 265 console.info("onrepeat callback") 266} 267``` 268 269 270 271## AnimatorOptions 272 273定义动画选项。 274 275**系统能力:** SystemCapability.ArkUI.ArkUI.Full 276 277| 名称 | 类型 | 必填 | 说明 | 278| ---------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ | 279| duration | number | 是 | 动画播放的时长,单位毫秒。<br/>默认值:0。 | 280| easing | string | 是 | 动画插值曲线,仅支持以下可选值:<br/>"linear":动画线性变化。<br/>"ease":动画开始和结束时的速度较慢,cubic-bezier(0.25、0.1、0.25、1.0)。<br/>"ease-in":动画播放速度先慢后快,cubic-bezier(0.42, 0.0, 1.0, 1.0)。<br/>"ease-out":动画播放速度先快后慢,cubic-bezier(0.0, 0.0, 0.58, 1.0)。<br/>"ease-in-out":动画播放速度先加速后减速,cubic-bezier(0.42, 0.0, 0.58, 1.0)。<br/>"fast-out-slow-in":标准曲线,cubic-bezier(0.4,0.0,0.2,1.0)。<br/>"linear-out-slow-in":减速曲线,cubic-bezier(0.0,0.0,0.2,1.0)。<br>"fast-out-linear-in":加速曲线,cubic-bezier(0.4, 0.0, 1.0, 1.0)。<br/>"friction":阻尼曲线,cubic-bezier(0.2, 0.0, 0.2, 1.0)。<br/>"extreme-deceleration":急缓曲线,cubic-bezier(0.0, 0.0, 0.0, 1.0)。<br/>"rhythm":节奏曲线,cubic-bezier(0.7, 0.0, 0.2, 1.0)。<br/>"sharp":锐利曲线,cubic-bezier(0.33, 0.0, 0.67, 1.0)。<br/>"smooth":平滑曲线,cubic-bezier(0.4, 0.0, 0.4, 1.0)。<br/>"cubic-bezier(x1,y1,x2,y2)":三次贝塞尔曲线,x1、x2的值必须处于0-1之间。例如"cubic-bezier(0.42,0.0,0.58,1.0)"。<br/>"steps(number,step-position)":阶梯曲线,number必须设置,为正整数,step-position参数可选,支持设置start或end,默认值为end。例如"steps(3,start)"。<br/>"interpolating-spring(velocity,mass,stiffness,damping)":插值弹簧曲线,从API version 11开始支持且仅在ArkTS中支持使用。velocity、mass、stiffness、damping都是数值类型,且mass、stiffness、damping参数均应该大于0,具体参数含义参考[插值弹簧曲线](./js-apis-curve.md#curvesinterpolatingspring10)。使用interpolating-spring时,duration不生效,由弹簧参数决定;fill、direction、iterations设置无效,fill固定设置为"forwards",direction固定设置为"normal",iterations固定设置为1,且对animator的[reverse](#reverse)函数调用无效。即animator使用interpolating-spring时只能正向播放1次。 | 281| delay | number | 是 | 动画延时播放时长,单位毫秒,设置为0时,表示不延时。 | 282| fill | "none" \| "forwards" \| "backwards" \| "both" | 是 | 动画执行后是否恢复到初始状态,动画执行后,动画结束时的状态(在最后一个关键帧中定义)将保留。<br/>"none":在动画执行之前和之后都不会应用任何样式到目标上。<br/>"forwards":在动画结束后,目标将保留动画结束时的状态(在最后一个关键帧中定义)。<br/>"backwards":动画将在animation-delay期间应用第一个关键帧中定义的值。当animation-direction为"normal"或"alternate"时应用from关键帧中的值,当animation-direction为"reverse"或"alternate-reverse"时应用to关键帧中的值。<br/>"both":动画将遵循forwards和backwards的规则,从而在两个方向上扩展动画属性。 | 283| direction | "normal" \| "reverse" \| "alternate" \| "alternate-reverse" | 是 | 动画播放模式。<br/>"normal": 动画正向循环播放。<br/>"reverse": 动画反向循环播放。<br/>"alternate":动画交替循环播放,奇数次正向播放,偶数次反向播放。<br/>"alternate-reverse":动画反向交替循环播放,奇数次反向播放,偶数次正向播放。<br/>默认值:"normal"。 | 284| iterations | number | 是 | 动画播放次数。设置为0时不播放,设置为-1时无限次播放。<br/>**说明:** 设置为除-1外其他负数视为无效取值,无效取值动画默认播放1次。 | 285| begin | number | 是 | 动画插值起点。<br/>默认值:0。 | 286| end | number | 是 | 动画插值终点。<br/>默认值:1。 | 287 288 289## 完整示例 290### 基于JS扩展的类Web开发范式 291 292```html 293<!-- hml --> 294<div class="container"> 295 <div class="Animation" style="height: {{divHeight}}px; width: {{divWidth}}px; background-color: red;" onclick="Show"> 296 </div> 297</div> 298``` 299 300```ts 301import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 302import { BusinessError } from '@ohos.base'; 303let DataTmp:Record<string,animator> = { 304 'divWidth': 200, 305 'divHeight': 200, 306 'animator': animator 307} 308class Tmp{ 309 data:animator = DataTmp 310 onInit:Function = ()=>{} 311 Show:Function = ()=>{} 312} 313class DateT{ 314 divWidth:number = 0 315 divHeight:number = 0 316 animator:AnimatorResult | null = null 317} 318(Fn:(v:Tmp) => void) => {Fn({ 319 data: DataTmp, 320 onInit() { 321 let options:AnimatorOptions = { 322 duration: 1500, 323 easing: "friction", 324 delay: 0, 325 fill: "forwards", 326 direction: "normal", 327 iterations: 2, 328 begin: 200.0, 329 end: 400.0 330 }; 331 let DataTmp:DateT = { 332 divWidth: 200, 333 divHeight: 200, 334 animator: null 335 } 336 DataTmp.animator = animator.create(options); 337 }, 338 Show() { 339 let options1:AnimatorOptions = { 340 duration: 1500, 341 easing: "friction", 342 delay: 0, 343 fill: "forwards", 344 direction: "normal", 345 iterations: 2, 346 begin: 0, 347 end: 400.0, 348 }; 349 let DataTmp:DateT = { 350 divWidth: 200, 351 divHeight: 200, 352 animator: null 353 } 354 try { 355 DataTmp.animator = animator.create(options1); 356 DataTmp.animator.reset(options1); 357 } catch(error) { 358 let message = (error as BusinessError).message 359 let code = (error as BusinessError).code 360 console.error(`Animator reset failed, error code: ${code}, message: ${message}.`); 361 } 362 let _this = DataTmp; 363 if(DataTmp.animator){ 364 DataTmp.animator.onframe = (value:number)=> { 365 _this.divWidth = value; 366 _this.divHeight = value; 367 }; 368 DataTmp.animator.play(); 369 } 370 } 371})} 372``` 373 374 ![zh-cn_image_00007](figures/zh-cn_image_00007.gif) 375 376### 基于TS扩展的声明式开发范式 377 378```ts 379import animator, { AnimatorResult } from '@ohos.animator'; 380 381@Entry 382@Component 383struct AnimatorTest { 384 private TAG: string = '[AnimatorTest]' 385 private backAnimator: AnimatorResult | undefined = undefined 386 private flag: boolean = false 387 @State wid: number = 100 388 @State hei: number = 100 389 390 create() { 391 let _this = this 392 this.backAnimator = animator.create({ 393 duration: 2000, 394 easing: "ease", 395 delay: 0, 396 fill: "forwards", 397 direction: "normal", 398 iterations: 1, 399 begin: 100, 400 end: 200 401 }) 402 this.backAnimator.onfinish = ()=> { 403 _this.flag = true 404 console.info(_this.TAG, 'backAnimator onfinish') 405 } 406 this.backAnimator.onrepeat = ()=> { 407 console.info(_this.TAG, 'backAnimator repeat') 408 } 409 this.backAnimator.oncancel = ()=> { 410 console.info(_this.TAG, 'backAnimator cancel') 411 } 412 this.backAnimator.onframe = (value:number)=> { 413 _this.wid = value 414 _this.hei = value 415 } 416 } 417 418 aboutToDisappear() { 419 // 由于backAnimator在onframe中引用了this, this中保存了backAnimator, 420 // 在自定义组件消失时应该将保存在组件中的backAnimator置空,避免内存泄漏 421 this.backAnimator = undefined; 422 } 423 424 build() { 425 Column() { 426 Column() { 427 Column() 428 .width(this.wid) 429 .height(this.hei) 430 .backgroundColor(Color.Red) 431 } 432 .width('100%') 433 .height(300) 434 435 Column() { 436 Row() { 437 Button('create') 438 .fontSize(30) 439 .fontColor(Color.Black) 440 .onClick(() => { 441 this.create() 442 }) 443 } 444 .padding(10) 445 446 Row() { 447 Button('play') 448 .fontSize(30) 449 .fontColor(Color.Black) 450 .onClick(() => { 451 this.flag = false 452 if(this.backAnimator){ 453 this.backAnimator.play() 454 } 455 }) 456 } 457 .padding(10) 458 459 Row() { 460 Button('pause') 461 .fontSize(30) 462 .fontColor(Color.Black) 463 .onClick(() => { 464 if(this.backAnimator){ 465 this.backAnimator.pause() 466 } 467 }) 468 } 469 .padding(10) 470 471 Row() { 472 Button('finish') 473 .fontSize(30) 474 .fontColor(Color.Black) 475 .onClick(() => { 476 this.flag = true 477 if(this.backAnimator){ 478 this.backAnimator.finish() 479 } 480 }) 481 } 482 .padding(10) 483 484 Row() { 485 Button('reverse') 486 .fontSize(30) 487 .fontColor(Color.Black) 488 .onClick(() => { 489 this.flag = false 490 if(this.backAnimator){ 491 this.backAnimator.reverse() 492 } 493 }) 494 } 495 .padding(10) 496 497 Row() { 498 Button('cancel') 499 .fontSize(30) 500 .fontColor(Color.Black) 501 .onClick(() => { 502 if(this.backAnimator){ 503 this.backAnimator.cancel() 504 } 505 }) 506 } 507 .padding(10) 508 509 Row() { 510 Button('reset') 511 .fontSize(30) 512 .fontColor(Color.Black) 513 .onClick(() => { 514 if (this.flag) { 515 this.flag = false 516 if(this.backAnimator){ 517 this.backAnimator.reset({ 518 duration: 3000, 519 easing: "ease-in", 520 delay: 0, 521 fill: "forwards", 522 direction: "alternate", 523 iterations: 3, 524 begin: 100, 525 end: 300 526 }) 527 } 528 } else { 529 console.info(this.TAG, 'Animation not ended') 530 } 531 }) 532 } 533 .padding(10) 534 } 535 } 536 } 537} 538``` 539 540## update<sup>(deprecated)</sup> 541 542update(options: AnimatorOptions): void 543 544更新当前动画器。 545 546从API version9开始不再维护,建议使用[reset<sup>9+</sup>](#reset9) 547 548**系统能力:** SystemCapability.ArkUI.ArkUI.Full 549 550**参数:** 551 552| 参数名 | 类型 | 必填 | 说明 | 553| ------- | ----------------------------------- | ---- | ------- | 554| options | [AnimatorOptions](#animatoroptions) | 是 | 定义动画选项。 | 555 556**示例:** 557 558```ts 559animator.update(options); 560``` 561 562## createAnimator<sup>(deprecated)</sup> 563 564createAnimator(options: AnimatorOptions): AnimatorResult 565 566定义Animator类。 567 568从API version9开始不再维护,建议使用[create<sup>9+</sup>](#create9) 569 570**系统能力:** SystemCapability.ArkUI.ArkUI.Full 571 572**参数:** 573 574| 参数名 | 类型 | 必填 | 说明 | 575| ------- | ----------------------------------- | ---- | ------- | 576| options | [AnimatorOptions](#animatoroptions) | 是 | 定义动画选项。 | 577 578**返回值:** 579 580| 类型 | 说明 | 581| --------------------------------- | ------------- | 582| [AnimatorResult](#animatorresult) | Animator结果接口。 | 583 584**示例:** 585 586```ts 587import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 588let options: AnimatorOptions = { // xxx.js文件中不需要强调显式类型AnimatorOptions 589 duration: 1500, 590 easing: "friction", 591 delay: 0, 592 fill: "forwards", 593 direction: "normal", 594 iterations: 3, 595 begin: 200.0, 596 end: 400.0, 597}; 598this.animator = animator.createAnimator(options); 599```