Firefox中的requestAnimationFrame闪烁问题

时间:2013-02-03 21:48:44

标签: html5 firefox canvas requestanimationframe

我试图在对角线方向上画出画布上的圆圈。我正在使用requestanimationframe。它在所有浏览器中都能顺利运行,但在firefox中却没有。动画正在进行时会不断闪烁。请有人告诉我我在做什么错。我需要在firefox中以至少合理的速度使用平滑的animatin。

这是我的简单代码,也许有人可以指出我在这里缺少的东西..:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style>
/*html { background: #000; }*/
</style>

<title>Test</title>
</head>

<body>
<script type="text/javascript">

    window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame    || 
              window.oRequestAnimationFrame      || 
              window.msRequestAnimationFrame     || 
              function(/* function */ callback, /* DOMElement */ element){
                window.setTimeout(callback, 1000 / 60);
              };
    })();

window.cancelRequestAnimFrame = ( function() {
    return window.cancelAnimationFrame          ||
        window.webkitCancelRequestAnimationFrame    ||
        window.mozCancelRequestAnimationFrame       ||
        window.oCancelRequestAnimationFrame     ||
        window.msCancelRequestAnimationFrame        ||
        clearTimeout
} )();  

var canvas, context, toggle;
var ctr = 0;
var request;

var x = 10;
var y = 10;


init();
animate();

function init() {

    canvas = document.createElement( 'canvas' );
    canvas.width = 512;
    canvas.height = 512;

    context = canvas.getContext( '2d' );

    document.body.appendChild( canvas );

}

function animate() {


    request = requestAnimFrame( animate );
    draw();

}

function draw() {

  context.clearRect(0,0,canvas.width,canvas.height);
  y+=2;
  x+=2;

  context.beginPath();
  context.arc(x, y, 3, 0, 2 * Math.PI, false);
  context.fillStyle = 'green';
  context.fill();
  context.lineWidth = 5;
  context.strokeStyle = '#003300';
  context.stroke();

    //cancelRequestAnimFrame(request); 

}

</script>

</body>
</html>

1 个答案:

答案 0 :(得分:2)

您的代码中有两件事需要修改:

首先尝试新的requestAnimationFrame polyfill。

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelRequestAnimationFrame = window[vendors[x]+
          'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}())

如需深入解释,请阅读以下文章:http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

是您需要计算一个时间戳与下一个时间戳之间的差值。您正在使用固定值,该值在每次渲染迭代时增加1。因为您的浏览器无法跟上跳过一到两帧的速度。这样你就可以顺利度过。

这是计算增量时间的方式:

end = Date.now();
delta = ( end - start ) / 1000.0 * 60;
end = start;

http://jsfiddle.net/p5c6c/1/