• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Animation Frame
2
3
4## Requesting an Animation Frame
5
6Use the **requestAnimationFrame** method to request frames on a one-by-one basis. This method accepts a callback as an argument.
7
8When **runframe** calls **requestAnimationFrame**, the **step** callback with the **timestamp** parameter is passed, and this timestamp iss assigned to **startTime**. When the difference between the **timestamp** and **startTime** is less than the specified value, **requestAnimationFrame** is called again, and the animation stops.
9
10```html
11<!-- xxx.hml -->
12<div class="container">
13  <tabs onchange="changecontent">
14    <tab-content>
15      <div class="container">
16        <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;">
17          <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;">
18          </canvas>
19          <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};">
20          </div>
21        </stack>
22        <button type="capsule" value="play" onclick="runframe"></button>
23      </div>
24    </tab-content>
25  </tabs>
26</div>
27```
28
29```css
30/* xxx.css */
31.container {
32  flex-direction: column;
33  justify-content: center;
34  align-items: center;
35  width: 100%;
36  height: 100%;
37}
38button{
39  width: 300px;
40}
41```
42
43```js
44// xxx.js
45export default {
46  data: {
47    timer: null,
48    left: 0,
49    top: 0,
50    flag: true,
51    animation: null,
52    startTime: 0,
53  },
54  onShow() {
55    var test = this.$element("mycanvas");
56    var ctx = test.getContext("2d");
57    ctx.beginPath();
58    ctx.moveTo(0, 0);
59    ctx.lineTo(300, 300);
60    ctx.lineWidth = 5;
61    ctx.strokeStyle = "red";
62    ctx.stroke();
63  },
64  runframe() {
65    this.left = 0;
66    this.top = 0;
67    this.flag = true;
68    this.animation = requestAnimationFrame(this.step);
69  },
70  step(timestamp) {
71    if (this.flag) {
72      this.left += 5;
73      this.top += 5;
74      if (this.startTime == 0) {
75        this.startTime = timestamp;
76      }
77      var elapsed = timestamp - this.startTime;
78        if (elapsed < 500) {
79          console.log('callback step timestamp: ' + timestamp);
80          this.animation = requestAnimationFrame(this.step);
81        }
82      } else {
83        this.left -= 5;
84        this.top -= 5;
85        this.animation = requestAnimationFrame(this.step);
86      }
87      if (this.left == 250 || this.left == 0) {
88        this.flag = !this.flag
89     }
90    },
91    onDestroy() {
92      cancelAnimationFrame(this.animation);
93    }
94}
95```
96
97![en-us_image_0000001267767877](figures/en-us_image_0000001267767877.gif)
98
99> **NOTE**
100>
101> When invoking the callback, the **requestAnimationFrame** method passes the **timestamp** as the first parameter, which indicates the time when **requestAnimationFrame** starts to execute the callback.
102
103
104## Canceling an Animation Frame
105
106Use the **cancelAnimationFrame** method to cancel frames on a one-by-one basis. When this method is called, the animation frame request sent through **requestAnimationFrame** will be canceled.
107
108```html
109<!-- xxx.hml -->
110<div class="container">
111  <tabs onchange="changecontent">
112    <tab-content>
113      <div class="container">
114        <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;">
115          <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;">
116          </canvas>
117          <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};">
118          </div>
119        </stack>
120        <button type="capsule" value="play" onclick="runframe"></button>
121      </div>
122    </tab-content>
123  </tabs>
124</div>
125```
126
127```css
128/* xxx.css */
129.container {
130  flex-direction: column;
131  justify-content: center;
132  align-items: center;
133  width: 100%;
134  height: 100%;
135}
136button{
137  width: 300px;
138}
139```
140
141```js
142// xxx.js
143export default {
144  data: {
145    timer: null,
146    left: 0,
147    top: 0,
148    flag: true,
149    animation: null
150  },
151  onShow() {
152    var test = this.$element("mycanvas");
153    var ctx = test.getContext("2d");
154    ctx.beginPath();
155    ctx.moveTo(0, 0);
156    ctx.lineTo(300, 300);
157    ctx.lineWidth = 5;
158    ctx.strokeStyle = "red";
159    ctx.stroke();
160  },
161  runframe() {
162    this.left = 0;
163    this.top = 0;
164    this.flag = true;
165    this.animation = requestAnimationFrame(this.step);
166  },
167  step(timestamp) {
168    if (this.flag) {
169      this.left += 5;
170      this.top += 5;
171      this.animation = requestAnimationFrame(this.step);
172    } else {
173      this.left -= 5;
174      this.top -= 5;
175      this.animation = requestAnimationFrame(this.step);
176    }
177    if (this.left == 250 || this.left == 0) {
178      this.flag = !this.flag
179    }
180  },
181  onDestroy() {
182    cancelAnimationFrame(this.animation);
183  }
184}
185```
186
187![en-us_image_0000001223127740](figures/en-us_image_0000001223127740.gif)
188
189> **NOTE**
190>
191> When **cancelAnimationFrame** is called, a parameter that indicates an ID must be passed.
192