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