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