在很久很久以前我们页面动画是这个样子的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>requestAnimationFrame</title> <style> #box { width: 50px; height: 50px; border: 1px solid #666; margin-left: 10px; } </style> </head> <body> <div id="box"></div> <button id="btn">点我 点我</button> <script> var box = document.getElementById('box'), btn = document.getElementById('btn'), left = 0, id; //用setTimeout 方法实现 btn.onclick = function() { go(); } function go() { if(left <= 300 ){ var timer = setTimeout(animation, 1000 / 60); // } else { clearTimeout(timer) } } function animation() { left += 10; box.style.marginLeft = left + 'px'; go(); } </script> </body> </html> |
但是这样做有几个问题,就是
- setTimeout效率并不是那么高
- 大多数浏览器的是已16ms为一帧,但是如果你设置不对,就会出现跳帧现象
于是乎作为现代人的我们,有了新的解决方法就是利用 requestAnimationFrame
直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>requestAnimationFrame</title> <style> #box { width: 50px; height: 50px; border: 1px solid #666; margin-left: 10px; } </style> </head> <body> <div id="box"></div> <button id="btn">点我 点我</button> <script> var box = document.getElementById('box'), btn = document.getElementById('btn'), left = 0, id; // requestAnimationFrame 实现 window.requestAnimationFrame = (function() { return window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(callback) { id = window.setTimeout(callback, 1000 / 60); // return id; }; })(); window.cancelAnimationFrame = (function() { return window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || function(id) { window.clearTimeout(id); } })(); btn.onclick = function() { requestAnimationFrame(step); } function step() { left += 10; box.style.marginLeft = left + 'px'; id = requestAnimationFrame(step); if(left > 300) { cancelAnimationFrame(id); } } </script> </body> </html> |
针对不同浏览器做了兼容,可以说从IE6开始支持,那么requestAnimationFrame有什么好处呢,
- 根据不同浏览器提供的帧去运动
- setTimeout本身机制并没有requestAnimationFrame效率高(具体原因待考察)
- 运行会更流畅,由其本身决定
- 相对css3来说,绘制更高级,css3有很多效果达不到
- 当当前页面不显示是,动画停止,节省cpu和电池热量
上面demo针对不同浏览器做了兼容,同时也写了取消事件。其实主要就这两个属性,很容易掌握。
ps: 其实开始研究的时候有个疑惑的地方,requestAnimationFrame 他没有时间这个参数,如果想要达到越来越快的效果怎么办。其实很简单,换个角度,以运动距离为参考,不断加大运动间距就ok啦。
参考:
CSS3动画那么强,requestAnimationFrame还有毛线用?
web动画–requestAnimationFrame
前端,学无止境!学长,“组长”。