Reputation: 105
I'm trying to use the page visibility api to pause a canvas animation when the user switches focus to another browser tab:
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 & Firefox 18 & later support
hidden = "hidden";
visibilityChange = "visibilitychange";
}
function drawStuff () {
//draws & rotates stuff on canvas
}
function handleVisibilityChange() {
if (document[hidden]) {
clearInterval(drawPic);
} else {
var drawPic = setInterval(drawStuff, 60);
}
}
handleVisibilityChange();
document.addEventListener("visibilitychange", handleVisibilityChange, false);
I'd like the animation to resume exactly where it left off, but for some reason every time I leave the tab and come back to my page, the setInterval doesn't clear and the drawing speeds up as if there were multiple setIntervals being called on it. If you leave and come back to the tab multiple times, the animation speeds up to absurd proportions.
What's going on here? Why isn't the interval being cleared in the handleVisibilityChange function?
Edit: Moving the var declaration fixed it, thanks.
Edit 2: Added in the code of document[hidden] for future reference (as mentioned by Suing & Tushar).
Upvotes: 0
Views: 478
Reputation: 54041
UPDATE In lew of comments.
I made a mistake and requestAnimationFrame
will not keep the computer awake by itself. It will though if you are playing video and you can use requestAnimationFrame
to view the video. Though it is the video that keeps the computer awake.
Also the term "focus" may not be correct, though it was suggested that it only updates when "visible" is not accurate as it keeps firing when you place another window over the window, event if that window is maximised, or scroll what you are animating out of view. Nor does requestAnimationFrame
have to display anything, and the call is unaware of what you do in the body of the callback, you may just be counting frames.
For now I will use the term "page focus", meaning that the page is the displayed tab of the browser window, it does not have to have system focus to fire, though if someone has a more accurate description do say.
Use window.requestAnimationFrame(functionName);
it stops calling when you lose page focus and then starts again when you regain page focus. Provides the max visible frame rate the browser supports (1/60th of a second interval) an syncs animations with the browser's layout and renderer.
See MDN requestAnimationFrame for details on how to use and compatibility.
Upvotes: 2
Reputation: 453
try this: move the "var drawPic;" declaration outside of the function. Other code included (for completeness sake) if someone else needs to test in the future.
// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.mozHidden !== "undefined") {
hidden = "mozHidden";
visibilityChange = "mozvisibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
function drawStuff () {
//draws & rotates stuff on canvas
}
var drawPic;
function handleVisibilityChange() {
if (document[hidden]) {
clearInterval(drawPic);
} else {
drawPic = setInterval(drawStuff, 60);
}
}
handleVisibilityChange();
// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" ||
typeof document[hidden] === "undefined") {
alert("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
// Handle page visibility change
document.addEventListener(visibilityChange, handleVisibilityChange, false);
}
Upvotes: 0