requestAnimationFrame优化动画

本文由清尘发表于2018-05-05 17:25最后修改于2018-05-10属于HTML/CSS分类

在过去,为了使用JavaScript脚本代码实现动画,开发者需要使用一个定时器来指定每隔一段时间使页面显示效果产生一些变化。最近,浏览器厂商决定提供一些API来优化动画的实现方法。于是,在HTML 5新增window.requestAnimFrame方法,用于以一种更好的性能来实现动画。
通过window.requestAnimFrame方法,浏览器可以具有将各种并发性动画结合入一个单一的页面进行创建及渲染的能力,这种能力将使得动画的实现具有更好的性能。例如,可以同时执行使用JavaScript脚本代码实现的动画与使用CSS中的transition样式属性实现的动画。另外,通过window.requestAnimFrame方法,当用户将浏览器标签窗口切换到其他标签窗口时,当前页面中的动画将被暂停运行,以减少CPU、GPU与内存的消耗。


window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame       ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame    ||
                window.oRequestAnimationFrame      ||
                window.msRequestAnimationFrame     ||
                function(callback){
                   window.setTimeout(callback, 1000 / 60);// 定义每秒执行60次动画
                };
})();
// 相当于使用setInterval(render, 16)方法,但是具有更高的性能
(function animloop(){
        requestAnimFrame(animloop);
        render();
})();

通过window.requestAnimFrame方法在canvas画布中绘制一个小球运动动画

window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame       ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame    ||
            window.oRequestAnimationFrame      ||
            window.msRequestAnimationFrame     ||
            function(){
                window.setTimeout(callback, 1000 / 60); // 每秒60帧
            };
})();
var canvas, context;
init();
animate();
function init() {
    canvas = document.createElement('canvas');
    canvas.style.left=0;
    canvas.style.top=0;
    canvas.width = 210;
    canvas.height = 210;
    context = canvas.getContext('2d');
    document.body.appendChild( canvas );
}
function animate() {
    requestAnimFrame( animate );
    draw();
}
function draw() {
    var time = new Date().getTime() * 0.002;
    var x = Math.sin( time ) * 96 +105;
    var y = Math.cos( time * 0.9 ) * 96 + 105;
    context.fillStyle ='pink';
    context.fillRect( 0, 0, 255, 255 );
    context.fillStyle='rgb(255,0,0)';
    context.beginPath();
    context.arc(x,y,10,0,Math.PI * 2,true);
    context.closePath();
    context.fill();
}