使用requestAnimationFrame更好的实现javascript动画(kimhou 译)
2012-05-28 14:05 VVG 阅读(491) 评论(0) 编辑 收藏 举报一直以来,JavaScript的动画都是通过定时器和间隔来实现的。虽然使用CSS transitions 和 animations使Web开发实现动画更加方便,但多年来以JavaScript为基础来实现动画却很少有所改变。直到Firefox 4的发布,才带来了第一种对JavaScript动画的改善的方法。但要充分认识改善,这有利于帮助我们了解web动画是如何演变改进的。
定时器Timer
(function(){ var msg = "NFL Draft is live tonight from Radio City Music Hall in New York City!", len = 25, pos = 0, padding = msg.replace(/./g, " ").substr(0,len), finalMsg = padding + msg; function updateText(){ var curMsg = finalMsg.substr(pos++, len); window.status = curMsg; if (pos == finalMsg.length){ pos = 0; } setTimeout(updateText, 100); } setTimeout(updateText, 100); })();
如果你想在浏览器中测试这段代码,你可以新建一个<pre>标签用来模拟window.status,例如:newsticker example
这种让人烦恼的web模式,后来遭到对window.status禁用的抵抗,但随着Explorer 4和Netscape 4的发布,浏览器第一次给开发者更多对页面元素的控制权限,这种技术再次出现。这样就出现了使用javascript动态改变元素大小、位置、颜色等的一种全新动画模式。例如,下面就是一个将div宽度变化成100%的动画(类似于进度条):
(function(){ function updateProgress(){ var div = document.getElementById("status"); div.style.width = (parseInt(div.style.width, 10) + 5) + "%"; if (div.style.width != "100%"){ setTimeout(updateProgress, 100); } } setTimeout(updateProgress, 100); } )();
尽管动画在页面上的地方不同,但基本原理却是一样的:做出改变,用setTimeout()间隔使页面更新,然后setTimeout又执行下一次变化,这个过程反复执行,直到动画完成(见进度条动画),早期的状态栏动画是相同的技术,只是动画不一样而已。
间隔动画intervals
(function(){ function updateAnimations(){ updateText(); updateProgress(); } setInterval(updateAnimations, 100); })();
创建一个小动画库,updateAnimations()方法将每一个动画(同时看到一个新闻股票和进度条在一起运行)循环执行并进行适当的改变。如果没有动画需要更新,该方法可以退出而不做任何事情,甚至停止动画循环,直到有更多的动画更新做好准备。
问题
mozRequestAnimationFrame
function updateProgress(){ var div = document.getElementById("status"); div.style.width = (parseInt(div.style.width, 10) + 5) + "%"; if (div.style.left != "100%"){ mozRequestAnimationFrame(updateProgress); } }
mozRequestAnimationFrame(updateProgress);
function draw(timestamp){ //calculate difference since last repaint var diff = timestamp - startTime; //use diff to determine correct next step //reset startTime to this repaint startTime = timestamp; //draw again mozRequestAnimationFrame(draw); }
var startTime = mozAnimationStartTime;
webkitRequestAnimationFrame
function draw(timestamp){ //calculate difference since last repaint var drawStart = (timestamp || Date.now()), diff = drawStart - startTime; //use diff to determine correct next step //reset startTime to this repaint startTime = drawStart; //draw again requestAnimationFrame(draw); } var requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame, startTime = window.mozAnimationStartTime || Date.now(); requestAnimationFrame(draw);
这种模式使用可用的方法来创建以花费多少时间为理念的循环动画。Firefox使用时间代码信息是有用的,而Chrome默认为欠精准的时间对象。当用这种模式的时候,时间的差异给你一种多少时间过去了的想法,但不会告诉你Chrome的下一次重绘出现在何时。不过这比只有多少时间过去了的模糊概念要好些。
总结
中文原文:http://www.kimhou.com/?p=155
英文原文:http://www.nczonline.net/blog/2011/05/03/better-javascript-animations-with-requestanimationframe/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+nczonline+%28NCZOnline+-+The+Official+Web+Site+of+Nicholas+C.+Zakas%29
转载请注明出处:http://www.cnblogs.com/NNUF/