1# 如何控制循环动画的播放停止
2## 场景介绍
3由于循环动画无限播放的效果是通过配置animateTo接口中的iterations属性值为-1实现的。为了控制循环动画的播放,开发者通过添加定时器和通过递归函数方法实现播放停止。本文即为大家介绍该方法如何控制循环动画的播放停止。
4
5## 运行环境
6本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
7- IDE: DevEco Studio 4.0 Release
8- SDK: Ohos_sdk_public 4.0.10.13 (API Version 10 Release)
9## 实现方案
10方案一:将循环动画放到定时其中执行,通过清除定时器实现停止动画。
11创建一个播放一次的animateTo()并通过onFinish()回调,然后通过setInterval重复调用animateTo(),以达到循环动画的播放,最后通过clearInterval清除定时器完成循环播放的停止。具体代码如下:
12```ts
13class A {
14  x:number=0
15  y:number=0
16}
17@Entry
18@Component
19struct AnimateToStop{
20  private Timer: number=0
21  @State doScale: A = {x:1,y:1}
22  build(){
23    Column(){
24      Row().width(150).height(150).backgroundColor("#41A8A8").scale(this.doScale)
25      Button('播放动画',{type:ButtonType.Normal,stateEffect:true})
26        .borderRadius(8)
27        .margin(5)
28        .backgroundColor('#86C7CC').onClick(() => {
29        animateTo({ duration: 400, iterations: 1, onFinish: () => {
30          animateTo({ duration: 400, onFinish: () => {
31          } }, () => {
32            this.doScale = { x: 1, y: 1 }
33          })
34        } }, () => {
35          this.doScale = { x: 0.5, y: 0.5 }
36        })
37
38        this.Timer = setInterval(()=>{
39          animateTo({ duration: 400, iterations: 1, onFinish: () => {
40            animateTo({duration:400, onFinish:()=>{
41            } }, ()=>{
42              this.doScale ={x:1, y:1}
43            })
44          } }, ()=>{
45            this.doScale={x:0.5,y:0.5}
46          })
47        },900)
48      })
49      Button('停止播放',{type:ButtonType.Normal,stateEffect:true})
50        .borderRadius(8)
51        .margin(5)
52        .backgroundColor('#86C7CC')
53        .onClick(() => {
54          clearInterval(this.Timer)
55        })
56    }.width('100%')
57    .height('100%')
58    .justifyContent(FlexAlign.Center)
59  }
60}
61```
62效果图如下:
63
64![](figures/play-stop1.gif)
65
66方案二:通过递归函数使得循环动画无限播放,终止递归函数实现停止循环动画。
67doAnimate函数去一直调用animateTo函数,从而实现动画无限循环;
68```ts
69class A{
70  x:number=0
71  y:number=0
72}
73@Entry
74@Component
75struct AnimateToStop {
76  @State doStop: boolean = false
77  @State doScale: A = { x: 0.5, y: 0.5 }
78
79  doAnimate(x: number) {
80    if (this.doStop) {
81      return
82    }
83    animateTo({ duration: 400, iterations: 1, onFinish: () => {
84      if (x == 0.5) {
85        this.doAnimate(1)
86      } else {
87        this.doAnimate(0.5)
88      }
89    } }, () => {
90      this.doScale = { x: x, y: x }
91    })
92  }
93
94  build() {
95    Column() {
96      Row().width(150).height(150).backgroundColor("#41A8A8").scale(this.doScale)
97      Button('播放动画', { type: ButtonType.Normal, stateEffect: true })
98        .borderRadius(8)
99        .margin(5)
100        .backgroundColor('#5C9DBA')
101        .onClick(() => {
102          this.doStop = false
103          this.doAnimate(0.5)
104        })
105      Button('停止动画', { type: ButtonType.Normal, stateEffect: true })
106        .borderRadius(8)
107        .margin(5)
108        .backgroundColor('#5C9DBA')
109        .onClick(() => {
110          this.doStop = true
111        })
112    }.width('100%')
113    .height('100%')
114    .justifyContent(FlexAlign.Center)
115  }
116}
117```
118
119效果图如下:
120
121![](figures/play-stop2.gif)
122
123## 参考
124[显示动画](../application-dev/reference/apis-arkui/arkui-ts/ts-explicit-animation.md)
125
126[定时器](../application-dev/reference/common/js-apis-timer.md)
127
128