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 11``` 12<!-- xxx.hml --> 13<div class="container"> 14 <tabs onchange="changecontent"> 15 <tab-content> 16 <div class="container"> 17 <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;"> 18 <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;"> 19 </canvas> 20 <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};"> 21 </div> 22 </stack> 23 <button type="capsule" value="play" onclick="runframe"></button> 24 </div> 25 </tab-content> 26 </tabs> 27</div> 28``` 29 30 31``` 32/* xxx.css */ 33.container { 34 flex-direction: column; 35 justify-content: center; 36 align-items: center; 37 width: 100%; 38 height: 100%; 39} 40button{ 41 width: 300px; 42} 43``` 44 45 46``` 47/* xxx.js */ 48export default { 49 data: { 50 timer: null, 51 left: 0, 52 top: 0, 53 flag: true, 54 animation: null, 55 startTime: 0, 56 }, 57 onShow() { 58 var test = this.$element("mycanvas"); 59 var ctx = test.getContext("2d"); 60 ctx.beginPath(); 61 ctx.moveTo(0, 0); 62 ctx.lineTo(300, 300); 63 ctx.lineWidth = 5; 64 ctx.strokeStyle = "red"; 65 ctx.stroke(); 66 }, 67 runframe() { 68 this.left = 0; 69 this.top = 0; 70 this.flag = true; 71 this.animation = requestAnimationFrame(this.step); 72 }, 73 step(timestamp) { 74 if (this.flag) { 75 this.left += 5; 76 this.top += 5; 77 if (this.startTime == 0) { 78 this.startTime = timestamp; 79 } 80 var elapsed = timestamp - this.startTime; 81 if (elapsed < 500) { 82 console.log('callback step timestamp: ' + timestamp); 83 this.animation = requestAnimationFrame(this.step); 84 } 85 } else { 86 this.left -= 5; 87 this.top -= 5; 88 this.animation = requestAnimationFrame(this.step); 89 } 90 if (this.left == 250 || this.left == 0) { 91 this.flag = !this.flag 92 } 93 }, 94 onDestroy() { 95 cancelAnimationFrame(this.animation); 96 } 97} 98``` 99 100 101 102>  **NOTE**: 103> 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. 104 105 106## Canceling an Animation Frame 107 108Use 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. 109 110 111``` 112<!-- xxx.hml --> 113<div class="container"> 114 <tabs onchange="changecontent"> 115 <tab-content> 116 <div class="container"> 117 <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;"> 118 <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;"> 119 </canvas> 120 <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};"> 121 </div> 122 </stack> 123 <button type="capsule" value="play" onclick="runframe"></button> 124 </div> 125 </tab-content> 126 </tabs> 127</div> 128``` 129 130 131``` 132/* xxx.css */ 133.container { 134 flex-direction: column; 135 justify-content: center; 136 align-items: center; 137 width: 100%; 138 height: 100%; 139} 140button{ 141 width: 300px; 142} 143``` 144 145 146``` 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 193 194>  **NOTE**: 195> When cancelAnimationFrame is called, a parameter that indicates an ID must be passed. 196