为什么每次在浏览器中切换标签时当前标签都会暂停?
why does current tab pause every time when I switch tabs in browser?
我使用 three.js 加载了导航网格和动物。动物在地图上移动。但是当我更改标签动物移动暂停时,如果再次打开该标签动物从暂停点再次移动。如何在选项卡更改或选项卡背景下播放继续动画。
function animate() {
var currTime = window.performance.now();
var delta = (currTime - lastFrameTime) / 1000;
var dTime = Math.min(delta, maxFrameTime);
elapsedTime += delta;
lastFrameTime = currTime;
tick(dTime);
requestAnimationFrame( animate );
render();
}
这是setAnimationFrame
工作中的一个特点。浏览器限制对非活动选项卡的处理以节省功耗和 CPU 周期。更多信息:
播放人们看不到的动画是没有意义的。但是,在给定目标点和速度的情况下,更新生物在后台的位置并在用户 returns 到选项卡时显示其当前位置可能是有意义的。
如果我没理解错的话,期望的结果是点击一个点,让怪物开始移动,然后当你离开和返回时,就好像怪物移动了与你正在观看的相同的量.
您可以使用页面可见性 API 来帮助做到这一点:https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
在 visibilityChange
上,您可以查看是否 window.hidden===true
。如果是这样,请暂停模拟并等待另一个 visibilityChange
事件 window.hidden===false
.
当焦点 returns 到选项卡时,计算当前时间与 window 隐藏时间之间的时间差。将渲染快进到这个时间点。然后继续显示动画。
这是一个示例。
我把它放在你的 init()
函数中。
function handleVisibilityChange() {
if (document.hidden) {
windowHidden=true;
hideTime=window.performance.now();
} else {
windowHidden=false;
var timeDiff=(window.performance.now()-hideTime)/1000;
console.log('Page invisible for ',timeDiff,' seconds, jump ahead.');
tick(timeDiff);
render();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
然后我在你的 tick
函数中检查了 windowHidden
标志:
if (!level||windowHidden) { return; }
(几乎完成)示例:https://jsfiddle.net/thmsdnnr/thk80hsh/2/
请注意,这并不完全符合您的预期:目前怪物只是在通往 下一个 节点的路径上前进,而 window 是隐藏的.这就是为什么当您向后移动时,怪物会偏离路径,返回到它前往的最后一个节点,然后继续。
由于怪物沿着一条有多个点和不同定向线段的路径行进,您需要重构您的 tick
函数,或者(我认为更好的选择)完全编写另一个函数,这需要window 隐藏的时间间隔,并计算怪物在给定速度和时间的情况下通过的路径上的节点数,移除这些节点,并在正确的位置渲染怪物。
requestAnimationFrame
将当前时间传递给它调用的函数,因此您可以声明 function animate(currTime) {...}
然后删除您自己的 currTime
。在此示例中,delta
将是帧之间的时间量,或者是离开和返回当前选项卡之间经过的时间量。
function animate(currTime) { // <-- currTime is populated by requestAnimationFrame
var delta = (currTime - lastFrameTime) / 1000;
// I don't think you need dTime anymore
elapsedTime += delta;
lastFrameTime = currTime;
tick(delta);
requestAnimationFrame( animate );
render();
}
我使用 three.js 加载了导航网格和动物。动物在地图上移动。但是当我更改标签动物移动暂停时,如果再次打开该标签动物从暂停点再次移动。如何在选项卡更改或选项卡背景下播放继续动画。
function animate() {
var currTime = window.performance.now();
var delta = (currTime - lastFrameTime) / 1000;
var dTime = Math.min(delta, maxFrameTime);
elapsedTime += delta;
lastFrameTime = currTime;
tick(dTime);
requestAnimationFrame( animate );
render();
}
这是setAnimationFrame
工作中的一个特点。浏览器限制对非活动选项卡的处理以节省功耗和 CPU 周期。更多信息:
播放人们看不到的动画是没有意义的。但是,在给定目标点和速度的情况下,更新生物在后台的位置并在用户 returns 到选项卡时显示其当前位置可能是有意义的。
如果我没理解错的话,期望的结果是点击一个点,让怪物开始移动,然后当你离开和返回时,就好像怪物移动了与你正在观看的相同的量.
您可以使用页面可见性 API 来帮助做到这一点:https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
在 visibilityChange
上,您可以查看是否 window.hidden===true
。如果是这样,请暂停模拟并等待另一个 visibilityChange
事件 window.hidden===false
.
当焦点 returns 到选项卡时,计算当前时间与 window 隐藏时间之间的时间差。将渲染快进到这个时间点。然后继续显示动画。
这是一个示例。
我把它放在你的 init()
函数中。
function handleVisibilityChange() {
if (document.hidden) {
windowHidden=true;
hideTime=window.performance.now();
} else {
windowHidden=false;
var timeDiff=(window.performance.now()-hideTime)/1000;
console.log('Page invisible for ',timeDiff,' seconds, jump ahead.');
tick(timeDiff);
render();
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
然后我在你的 tick
函数中检查了 windowHidden
标志:
if (!level||windowHidden) { return; }
(几乎完成)示例:https://jsfiddle.net/thmsdnnr/thk80hsh/2/
请注意,这并不完全符合您的预期:目前怪物只是在通往 下一个 节点的路径上前进,而 window 是隐藏的.这就是为什么当您向后移动时,怪物会偏离路径,返回到它前往的最后一个节点,然后继续。
由于怪物沿着一条有多个点和不同定向线段的路径行进,您需要重构您的 tick
函数,或者(我认为更好的选择)完全编写另一个函数,这需要window 隐藏的时间间隔,并计算怪物在给定速度和时间的情况下通过的路径上的节点数,移除这些节点,并在正确的位置渲染怪物。
requestAnimationFrame
将当前时间传递给它调用的函数,因此您可以声明 function animate(currTime) {...}
然后删除您自己的 currTime
。在此示例中,delta
将是帧之间的时间量,或者是离开和返回当前选项卡之间经过的时间量。
function animate(currTime) { // <-- currTime is populated by requestAnimationFrame
var delta = (currTime - lastFrameTime) / 1000;
// I don't think you need dTime anymore
elapsedTime += delta;
lastFrameTime = currTime;
tick(delta);
requestAnimationFrame( animate );
render();
}