窗口重新聚焦的画布requestAnimationFrame bug

时间:2013-11-30 20:33:19

标签: javascript html5 canvas

我正在使用画布进行一些动画制作,并且刚刚实现了基于时间的动画。

我得到一个奇怪的错误,只是偶尔发生。当我切换标签时,窗口失去焦点,当切换回动画片时,动画片会出现几个帧的“滞后”。

复制这个被证明是相当困难的,因为它在离开窗口一段任意时间后发生,但这不一致,即我已经离开它5,10,30分钟并且在重新聚焦窗口时错误不会发生。

这是罪魁祸首:

lastTime = Date.now();

function gameLoop(){

    requestAnimationFrame(gameLoop);
    var thisTime = Date.now();
    var deltaTime = (thisTime - lastTime);


    if(deltaTime > 160){ //If deltaTime is above 160 (roughly 6fps) 
                            //it's assumed the user switched tab

        deltaTime = 0;
    }
    lastTime = thisTime; //Update lastTime
    draw();
    update(deltaTime * timeMultiplier);


}

我假设错误处于if状态,这是因为没有它,deltaTime变量会一直递增,直到窗口重新聚焦。我认为问题在于1000/60的分配,其性质是文字......由于requestAnimationFrame的性质,我不知道在那里放置什么值。

关于出了什么问题的任何想法?

非常感谢

1 个答案:

答案 0 :(得分:1)

正如您可能知道的那样,requestAnimationFrame(RAF)旨在当浏览器选项卡失去焦点时停止运行。

当其浏览器选项卡重新获得焦点时,动画将恢复。由于RAF需要一小段时间才能恢复,因此可能会出现小的延迟。在60fps时,延迟可能高达几帧。

当RAF暂停时,不会计算您的deltaTime

当RAF暂停时,您的gameLoop不会执行且deltaTime不会递增 - 因此您的“if”不会被触发。

当RAF恢复时,Date.now()比lastTime大得多,所以你的“if”很可能会立即触发。

如果想要操作在选项卡失焦时继续运行,请使用setTimeout或setInterval。