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