This is a feature of setAnimationFrame
at work. Browsers limit the processing on inactive tabs to save power consumption and CPU cycles. For more information: https://stackoverflow.com/a/5927432/7316502
It doesn't make sense to play an animation that people can't see. However, it might make sense to update the position of the creature in the background and display its current position when the user returns to the tab, given its target point and velocity.
If I understand correctly, the desired outcome is to click a point, have the monster start moving, and then when you tab away and tab back, it's as though the monster has moved the same amount as if you were watching.
You could use the Page Visibility API to help do this: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
On a visibilityChange
, you can check to see if window.hidden===true
. If so, pause the simulation and await another visibilityChange
event for which window.hidden===false
.
When focus returns to the tab, calculate the time difference between the current time and the time the window became hidden. Fast-forward your rendering to this time point. Then continue displaying animation.
Here is an example of what this might look like.
I placed this in your init()
function.
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);
Then I placed a check in your tick
function to check the windowHidden
flag:
if (!level||windowHidden) { return; }
Note that this does not quite work the way you'd intend: currently the monster just proceeds on the path toward the next node while the window is hidden. This is why when you tab back, the monster is off the path, proceeds back to the last node it was headed toward, and then continues.
Since the monster is following a path with multiple points and different directed segments, you'd need to refactor your tick
function, or (better choice, I think) write another one entirely, that takes the time interval the window was hidden for and calculates the number of nodes on the path the monster would have passed given its velocity and time, removes those nodes, and renders the monster in the correct position.