• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  ![zh-cn_image_00007](figures/zh-cn_image_00007.gif)
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```