Firefox 中的 requestAnimationFrame 闪烁问题
Posted
技术标签:
【中文标题】Firefox 中的 requestAnimationFrame 闪烁问题【英文标题】:requestAnimationFrame flickering issue in Firefox 【发布时间】:2013-01-18 14:49:56 【问题描述】:我正在尝试在画布上沿对角线方向制作一个圆圈。我正在使用 requestanimationframe。它在所有浏览器中都能顺利运行,但在 Firefox 中却不行。动画进行时会不断闪烁。请有人告诉我我做错了什么。我需要在 Firefox 中以至少合理的速度平滑动画。
这是我的简单代码,也许有人可以指出我在这里缺少什么..:
<!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>
【问题讨论】:
我期待一个非常快速的回答这个问题,因为场景非常简单。在Firefox中不可能有流畅的html5画布动画吗?为什么在Firefox中完成它如此困难,我想知道! 我在 Mac 上的 Firefox 18 中没有看到这种闪烁。您使用的是哪个版本的 Firefox? 我刚刚在 windows pc 上的 Firefox 18 中尝试过。它不光滑。它在 chrome 中完美运行,但在 Firefox 中我可以看到它并不流畅。也许这是 Firefox 能做的最好的事情。我的客户使用 Firefox,所以我必须对这个问题做点什么!在这个例子中,我放置了一个简单的圆圈在画布上移动的场景。我的实际项目在每个循环迭代中都包含图像背景和非课程 javascript 逻辑。在 chrome、IE 和 safari 中都运行良好。任何想法! 【参考方案1】:您的代码中有两处需要修改:
首先尝试新的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
秒是你需要计算一个时间戳和下一个时间戳之间的增量。您正在使用一个固定值,每次渲染迭代都会增加一个。因为您的浏览器跟不上它可能会跳过一两帧的速度。这样你就可以顺利度过。
这是计算增量时间的方式:
end = Date.now();
delta = ( end - start ) / 1000.0 * 60;
end = start;
http://jsfiddle.net/p5c6c/1/
【讨论】:
感谢您的帖子。好吧,我已经尝试过这个 polyfill,但动画仍然不流畅。我不知道你提到的增量时间。我看到你在我的代码中添加了 delta 因子..但不幸的是它仍然在我的 firefox.damn firefox 上闪烁。 (您是否使用此代码获得流畅的动画?如果是,哪个 FF 版本!)我也读过这篇文章,但我无法了解在 Firefox 中拥有流畅(如在其他浏览器中)动画的秘密。我已经尝试了好几个星期了。我现在完全被火狐困住了。 FF 18.0.1。起初加载并不像它应该的那样平滑(可能是因为文档没有完全呈现),但在很长一段时间内,与我跳过帧的方法相比,它肯定会变得更平滑。window.onload = function()
i 厚应该可以解决问题。
好吧,我的问题仍然存在。我客户的 Firefox 也有同样的问题。它并不完全顺利。我对平滑度的定义是这个动画在 chrome 中的表现。
那跟代码没关系...反正尽量用增量时间代替定值...
是的,那段代码不会有任何问题。它只是FF处理动画的糟糕程度。我将尝试在其他地方找到解决我独特问题的方法。无论如何感谢您的帮助:)以上是关于Firefox 中的 requestAnimationFrame 闪烁问题的主要内容,如果未能解决你的问题,请参考以下文章
css [隐藏滚动条]隐藏Firefox #firefox #css中的滚动条