• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 动画帧
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @CCFFWW-->
5<!--Designer: @yangfan229-->
6<!--Tester: @lxl007-->
7<!--Adviser: @HelloCrease-->
8
9## 请求动画帧
10
11请求动画帧时通过requestAnimationFrame函数逐帧回调,在调用该函数时传入一个回调函数。
12
13runframe在调用requestAnimationFrame时传入带有timestamp参数的回调函数step,将step中的timestamp赋予起始的startTime。当timestamp与startTime的差值小于规定的时间时将再次调用requestAnimationFrame,最终动画将会停止。
14
15```html
16<!-- xxx.hml -->
17<div class="container">
18  <tabs onchange="changecontent">
19    <tab-content>
20      <div class="container">
21        <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;">
22          <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;">
23          </canvas>
24          <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};">
25          </div>
26        </stack>
27        <button type="capsule" value="play" onclick="runframe"></button>
28      </div>
29    </tab-content>
30  </tabs>
31</div>
32```
33
34```css
35/* xxx.css */
36.container {
37  flex-direction: column;
38  justify-content: center;
39  align-items: center;
40  width: 100%;
41  height: 100%;
42}
43button{
44  width: 300px;
45}
46```
47
48```js
49// xxx.js
50export default {
51  data: {
52    timer: null,
53    left: 0,
54    top: 0,
55    flag: true,
56    animation: null,
57    startTime: 0,
58  },
59  onShow() {
60    var test = this.$element("mycanvas");
61    var ctx = test.getContext("2d");
62    ctx.beginPath();
63    ctx.moveTo(0, 0);
64    ctx.lineTo(300, 300);
65    ctx.lineWidth = 5;
66    ctx.strokeStyle = "red";
67    ctx.stroke();
68  },
69  runframe() {
70    this.left = 0;
71    this.top = 0;
72    this.flag = true;
73    this.animation = requestAnimationFrame(this.step);
74  },
75  step(timestamp) {
76    if (this.flag) {
77      this.left += 5;
78      this.top += 5;
79      if (this.startTime == 0) {
80        this.startTime = timestamp;
81      }
82      var elapsed = timestamp - this.startTime;
83        if (elapsed < 500) {
84          console.log('callback step timestamp: ' + timestamp);
85          this.animation = requestAnimationFrame(this.step);
86        }
87      } else {
88        this.left -= 5;
89        this.top -= 5;
90        this.animation = requestAnimationFrame(this.step);
91      }
92      if (this.left == 250 || this.left == 0) {
93        this.flag = !this.flag;
94     }
95    },
96    onDestroy() {
97      cancelAnimationFrame(this.animation);
98    }
99}
100```
101
102![zh-cn_image_0000001174756860](figures/zh-cn_image_0000001174756860.gif)
103
104> **说明:**
105>
106> requestAnimationFrame函数在调用回调函数时在第一个参数位置传入timestamp时间戳,表示requestAnimationFrame开始去执行回调函数的时刻。
107
108
109## 取消动画帧
110
111通过cancelAnimationFrame函数取消逐帧回调,在调用cancelAnimationFrame函数时取消requestAnimationFrame函数的请求。
112
113```html
114<!-- xxx.hml -->
115<div class="container">
116  <tabs onchange="changecontent">
117    <tab-content>
118      <div class="container">
119        <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;">
120          <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;">
121          </canvas>
122          <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};">
123          </div>
124        </stack>
125        <button type="capsule" value="play" onclick="runframe"></button>
126      </div>
127    </tab-content>
128  </tabs>
129</div>
130```
131
132```css
133/* xxx.css */
134.container {
135  flex-direction: column;
136  justify-content: center;
137  align-items: center;
138  width: 100%;
139  height: 100%;
140}
141button{
142  width: 300px;
143}
144```
145
146```js
147// xxx.js
148export default {
149  data: {
150    timer: null,
151    left: 0,
152    top: 0,
153    flag: true,
154    animation: null
155  },
156  onShow() {
157    var test = this.$element("mycanvas");
158    var ctx = test.getContext("2d");
159    ctx.beginPath();
160    ctx.moveTo(0, 0);
161    ctx.lineTo(300, 300);
162    ctx.lineWidth = 5;
163    ctx.strokeStyle = "red";
164    ctx.stroke();
165  },
166  runframe() {
167    this.left = 0;
168    this.top = 0;
169    this.flag = true;
170    this.animation = requestAnimationFrame(this.step);
171  },
172  step(timestamp) {
173    if (this.flag) {
174      this.left += 5;
175      this.top += 5;
176      this.animation = requestAnimationFrame(this.step);
177    } else {
178      this.left -= 5;
179      this.top -= 5;
180      this.animation = requestAnimationFrame(this.step);
181    }
182    if (this.left == 250 || this.left == 0) {
183      this.flag = !this.flag;
184    }
185  },
186  onDestroy() {
187    cancelAnimationFrame(this.animation);
188  }
189}
190```
191
192![zh-cn_image_0000001220316655](figures/zh-cn_image_0000001220316655.gif)
193
194> **说明:**
195>
196> 在调用该函数时需传入一个具有标识id的参数。
197