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}; 101try { 102 animator.reset(options); 103} catch(error) { 104 let message = (error as BusinessError).message 105 let code = (error as BusinessError).code 106 console.error(`Animator reset failed, error code: ${code}, message: ${message}.`); 107} 108``` 109 110### play 111 112play(): void 113 114启动动画。动画会保留上一次的播放状态,比如播放状态设置reverse后,再次播放会保留reverse的播放状态。 115 116**系统能力:** SystemCapability.ArkUI.ArkUI.Full 117 118**示例:** 119 120```ts 121animator.play(); 122``` 123 124### finish 125 126finish(): void 127 128结束动画。 129 130**系统能力:** SystemCapability.ArkUI.ArkUI.Full 131 132**示例:** 133 134```ts 135animator.finish(); 136``` 137 138### pause 139 140pause(): void 141 142暂停动画。 143 144**系统能力:** SystemCapability.ArkUI.ArkUI.Full 145 146**示例:** 147 148```ts 149animator.pause(); 150``` 151 152### cancel 153 154cancel(): void 155 156删除动画。 157 158**系统能力:** SystemCapability.ArkUI.ArkUI.Full 159 160**示例:** 161 162```ts 163animator.cancel(); 164``` 165 166### reverse 167 168reverse(): void 169 170以相反的顺序播放动画。 171 172**系统能力:** SystemCapability.ArkUI.ArkUI.Full 173 174**示例:** 175 176```ts 177animator.reverse(); 178``` 179 180### onframe 181 182onframe: (progress: number) => void 183 184接收到帧时回调。 185 186**系统能力:** SystemCapability.ArkUI.ArkUI.Full 187 188**参数:** 189 190| 参数名 | 类型 | 必填 | 说明 | 191| -------- | ------ | ---- | -------- | 192| progress | number | 是 | 动画的当前进度。 | 193 194**示例:** 195 196```ts 197import animator, { AnimatorResult } from '@ohos.animator'; 198let animatorResult:AnimatorResult|undefined = animator.create(options) 199animatorResult.onframe = (value)=> { 200 console.info("onframe callback") 201} 202``` 203 204### onfinish 205 206onfinish: () => void 207 208动画完成时回调。 209 210**系统能力:** SystemCapability.ArkUI.ArkUI.Full 211 212**示例:** 213 214```ts 215import animator, { AnimatorResult } from '@ohos.animator'; 216let animatorResult:AnimatorResult|undefined = animator.create(options) 217animatorResult.onfinish = ()=> { 218 console.info("onfinish callback") 219} 220``` 221 222### oncancel 223 224oncancel: () => void 225 226动画被取消时回调。 227 228**系统能力:** SystemCapability.ArkUI.ArkUI.Full 229 230**示例:** 231 232```ts 233import animator, { AnimatorResult } from '@ohos.animator'; 234let animatorResult:AnimatorResult|undefined = animator.create(options) 235animatorResult.oncancel = ()=> { 236 console.info("oncancel callback") 237} 238``` 239 240### onrepeat 241 242onrepeat: () => void 243 244动画重复时回调。 245 246**系统能力:** SystemCapability.ArkUI.ArkUI.Full 247 248**示例:** 249 250```ts 251import animator, { AnimatorResult } from '@ohos.animator'; 252let animatorResult:AnimatorResult|undefined = animator.create(options) 253animatorResult.onrepeat = ()=> { 254 console.info("onrepeat callback") 255} 256``` 257 258 259 260## AnimatorOptions 261 262定义动画选项。 263 264**系统能力:** SystemCapability.ArkUI.ArkUI.Full 265 266| 名称 | 类型 | 必填 | 说明 | 267| ---------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ | 268| duration | number | 是 | 动画播放的时长,单位毫秒。 | 269| 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/>"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)"。 | 270| delay | number | 是 | 动画延时播放时长,单位毫秒,设置为0时,表示不延时。 | 271| 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的规则,从而在两个方向上扩展动画属性。 | 272| direction | "normal" \| "reverse" \| "alternate" \| "alternate-reverse" | 是 | 动画播放模式。<br/>"normal": 动画正向循环播放。<br/>"reverse": 动画反向循环播放。<br/>"alternate":动画交替循环播放,奇数次正向播放,偶数次反向播放。<br/>"alternate-reverse":动画反向交替循环播放,奇数次反向播放,偶数次正向播放。 | 273| iterations | number | 是 | 动画播放次数。设置为0时不播放,设置为-1时无限次播放。<br/>**说明:** 设置为除-1外其他负数视为无效取值,无效取值动画默认播放1次。 | 274| begin | number | 是 | 动画插值起点。 | 275| end | number | 是 | 动画插值终点。 | 276 277 278## 完整示例 279### 基于JS扩展的类Web开发范式 280 281```html 282<!-- hml --> 283<div class="container"> 284 <div class="Animation" style="height: {{divHeight}}px; width: {{divWidth}}px; background-color: red;" onclick="Show"> 285 </div> 286</div> 287``` 288 289```ts 290import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 291import { BusinessError } from '@ohos.base'; 292let DataTmp:Record<string,animator> = { 293 'divWidth': 200, 294 'divHeight': 200, 295 'animator': animator 296} 297class Tmp{ 298 data:animator = DataTmp 299 onInit:Function = ()=>{} 300 Show:Function = ()=>{} 301} 302class DateT{ 303 divWidth:number = 0 304 divHeight:number = 0 305 animator:AnimatorResult | null = null 306} 307(Fn:(v:Tmp) => void) => {Fn({ 308 data: DataTmp, 309 onInit() { 310 let options:AnimatorOptions = { 311 duration: 1500, 312 easing: "friction", 313 delay: 0, 314 fill: "forwards", 315 direction: "normal", 316 iterations: 2, 317 begin: 200.0, 318 end: 400.0 319 }; 320 let DataTmp:DateT = { 321 divWidth: 200, 322 divHeight: 200, 323 animator: null 324 } 325 DataTmp.animator = animator.create(options); 326 }, 327 Show() { 328 let options1:AnimatorOptions = { 329 duration: 1500, 330 easing: "friction", 331 delay: 0, 332 fill: "forwards", 333 direction: "normal", 334 iterations: 2, 335 begin: 0, 336 end: 400.0, 337 }; 338 let DataTmp:DateT = { 339 divWidth: 200, 340 divHeight: 200, 341 animator: null 342 } 343 try { 344 DataTmp.animator = animator.create(options1); 345 DataTmp.animator.reset(options1); 346 } catch(error) { 347 let message = (error as BusinessError).message 348 let code = (error as BusinessError).code 349 console.error(`Animator reset failed, error code: ${code}, message: ${message}.`); 350 } 351 let _this = DataTmp; 352 if(DataTmp.animator){ 353 DataTmp.animator.onframe = (value:number)=> { 354 _this.divWidth = value; 355 _this.divHeight = value; 356 }; 357 DataTmp.animator.play(); 358 } 359 } 360})} 361``` 362 363  364 365### 基于TS扩展的声明式开发范式 366 367```ts 368import animator, { AnimatorResult } from '@ohos.animator'; 369 370@Entry 371@Component 372struct AnimatorTest { 373 private TAG: string = '[AnimatorTest]' 374 private backAnimator: AnimatorResult | undefined = undefined 375 private flag: boolean = false 376 @State wid: number = 100 377 @State hei: number = 100 378 379 create() { 380 let _this = this 381 this.backAnimator = animator.create({ 382 duration: 2000, 383 easing: "ease", 384 delay: 0, 385 fill: "forwards", 386 direction: "normal", 387 iterations: 1, 388 begin: 100, 389 end: 200 390 }) 391 this.backAnimator.onfinish = ()=> { 392 _this.flag = true 393 console.info(_this.TAG, 'backAnimator onfinish') 394 } 395 this.backAnimator.onrepeat = ()=> { 396 console.info(_this.TAG, 'backAnimator repeat') 397 } 398 this.backAnimator.oncancel = ()=> { 399 console.info(_this.TAG, 'backAnimator cancel') 400 } 401 this.backAnimator.onframe = (value:number)=> { 402 _this.wid = value 403 _this.hei = value 404 } 405 } 406 407 aboutToDisappear() { 408 // 由于backAnimator在onframe中引用了this, this中保存了backAnimator, 409 // 在自定义组件消失时应该将保存在组件中的backAnimator置空,避免内存泄漏 410 this.backAnimator = undefined; 411 } 412 413 build() { 414 Column() { 415 Column() { 416 Column() 417 .width(this.wid) 418 .height(this.hei) 419 .backgroundColor(Color.Red) 420 } 421 .width('100%') 422 .height(300) 423 424 Column() { 425 Row() { 426 Button('create') 427 .fontSize(30) 428 .fontColor(Color.Black) 429 .onClick(() => { 430 this.create() 431 }) 432 } 433 .padding(10) 434 435 Row() { 436 Button('play') 437 .fontSize(30) 438 .fontColor(Color.Black) 439 .onClick(() => { 440 this.flag = false 441 if(this.backAnimator){ 442 this.backAnimator.play() 443 } 444 }) 445 } 446 .padding(10) 447 448 Row() { 449 Button('pause') 450 .fontSize(30) 451 .fontColor(Color.Black) 452 .onClick(() => { 453 if(this.backAnimator){ 454 this.backAnimator.pause() 455 } 456 }) 457 } 458 .padding(10) 459 460 Row() { 461 Button('finish') 462 .fontSize(30) 463 .fontColor(Color.Black) 464 .onClick(() => { 465 this.flag = true 466 if(this.backAnimator){ 467 this.backAnimator.finish() 468 } 469 }) 470 } 471 .padding(10) 472 473 Row() { 474 Button('reverse') 475 .fontSize(30) 476 .fontColor(Color.Black) 477 .onClick(() => { 478 this.flag = false 479 if(this.backAnimator){ 480 this.backAnimator.reverse() 481 } 482 }) 483 } 484 .padding(10) 485 486 Row() { 487 Button('cancel') 488 .fontSize(30) 489 .fontColor(Color.Black) 490 .onClick(() => { 491 if(this.backAnimator){ 492 this.backAnimator.cancel() 493 } 494 }) 495 } 496 .padding(10) 497 498 Row() { 499 Button('reset') 500 .fontSize(30) 501 .fontColor(Color.Black) 502 .onClick(() => { 503 if (this.flag) { 504 this.flag = false 505 if(this.backAnimator){ 506 this.backAnimator.reset({ 507 duration: 3000, 508 easing: "ease-in", 509 delay: 0, 510 fill: "forwards", 511 direction: "alternate", 512 iterations: 3, 513 begin: 100, 514 end: 300 515 }) 516 } 517 } else { 518 console.info(this.TAG, 'Animation not ended') 519 } 520 }) 521 } 522 .padding(10) 523 } 524 } 525 } 526} 527``` 528 529## update<sup>(deprecated)</sup> 530 531update(options: AnimatorOptions): void 532 533更新当前动画器。 534 535从API version9开始不再维护,建议使用[reset<sup>9+</sup>](#reset9) 536 537**系统能力:** SystemCapability.ArkUI.ArkUI.Full 538 539**参数:** 540 541| 参数名 | 类型 | 必填 | 说明 | 542| ------- | ----------------------------------- | ---- | ------- | 543| options | [AnimatorOptions](#animatoroptions) | 是 | 定义动画选项。 | 544 545**示例:** 546 547```ts 548animator.update(options); 549``` 550 551## createAnimator<sup>(deprecated)</sup> 552 553createAnimator(options: AnimatorOptions): AnimatorResult 554 555定义Animator类。 556 557从API version9开始不再维护,建议使用[create<sup>9+</sup>](#create9) 558 559**系统能力:** SystemCapability.ArkUI.ArkUI.Full 560 561**参数:** 562 563| 参数名 | 类型 | 必填 | 说明 | 564| ------- | ----------------------------------- | ---- | ------- | 565| options | [AnimatorOptions](#animatoroptions) | 是 | 定义动画选项。 | 566 567**返回值:** 568 569| 类型 | 说明 | 570| --------------------------------- | ------------- | 571| [AnimatorResult](#animatorresult) | Animator结果接口。 | 572 573**示例:** 574 575```ts 576import animator, { AnimatorOptions,AnimatorResult } from '@ohos.animator'; 577let options: AnimatorOptions = { // xxx.js文件中不需要强调显式类型AnimatorOptions 578 duration: 1500, 579 easing: "friction", 580 delay: 0, 581 fill: "forwards", 582 direction: "normal", 583 iterations: 3, 584 begin: 200.0, 585 end: 400.0, 586}; 587this.animator = animator.createAnimator(options); 588```