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