1

Is there a way to know when the browser is actively running requestAnimationFrame?

For example when I switch tabs from one that was running requestAnimationFrame, the function stops getting executed, when I switch back it continues, what is the best way to deal with this?

GriffLab
  • 2,076
  • 3
  • 20
  • 21
  • 1
    you can set a variable to the date in your RAF callback, and compare that timestamp to the current one to know how long it's been since a paint. Anything over a second and the tab is very likely blurred. – dandavis Jun 20 '13 at 16:39

4 Answers4

9

To detect if requestAnimationFrame is running 100% you can check:

window.addEventListener('blur', function() {
   //not running full
}, false);

and

window.addEventListener('focus', function() {
   //running optimal (if used)
}, false);

this can be used as we know requestAnimationFrame reduces trigger rate (in most browsers) when window (tab) is not the active one (IF being used - it depends on the code actually using the requestAnimationFrame).

If you want it to run constantly you can insert a mechanism such as this:

var isActiveTab = true; //update with the events above

function myLoop() {

    //my cool stuff here

    if (isActiveTab) {
         requestAnimationFrame(myLoop);
    } else {
         setTimeout(myLoop, 16); //force a rate (vblank sync not necessary
                                 //when display isn't updated
    }
}

Note that the reduction in rate for requestAnimationFrame is not part of the standard and is a browser specific implementation.

  • Thanks for this Ken, the other answer didn't fully understand my question but this works great. You think they would have something in the api for this as at the heart of all games that are variable timestep you use some sort of timing mechanism coming from the loop so having big pauses from switching tabs kinda wrecks it. The other idea I had was to record the FPS of RAF, and if the delta is insanely above the average timestep then use the recorded FPS timestep as the delta value, not sure how I would implement it though. – GriffLab Jun 21 '13 at 01:22
  • @GriffLab For FPS perhaps this might help: http://stackoverflow.com/questions/5078913/html5-canvas-performance-calculating-loops-frames-per-second –  Jun 21 '13 at 02:20
  • I'm not sure window focus/blur event will be enough to know what 'mode' the browser tab is in - if the OS receives no input for a while & goes into idle/energy-saving, I think this affects RAF stuff. I have noticed this when working on a clock app with a loop run via RAF. – MachineElf Sep 25 '14 at 10:09
  • 1
    You can use the `HTML5 Visibility API` to detect when a browser tab loses or gains focus.. example : http://codepen.io/anon/pen/PqrjVg .. and the link to the spec: https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API – Jonathan Marzullo Aug 20 '15 at 18:38
2

When you again come back to the tab with animation,It must be working fine(If thats the case--following is your answer!!!)

This is what RAF made for.To optimize performance. SetInterval and Settimeout can be used instead for creating animations, But they cannot interact with the browser and eventually end up hogging up the cpu and the performance is also quite slow.

But your question is really not a question.This is actually a trick used by RAF to better your overall animation experience.

There are several articles which explains RAF. http://creativejs.com/resources/requestanimationframe/

Just An Optimization TRICK--No need to worry about it

  • But if I am creating a loop with requestAnimationFrame, and am passing in delta time to update entities on screen, and someone browses away from the tab, then my delta time gets messed up causing entities to violate their boundaries, knowing whether request animation is running or not would solve this, how would you go about it? – GriffLab Jun 20 '13 at 16:49
  • common!!! You are coder.And I believe every coder is a hacker at heart. If not the complete code,atleast simplify it ,shorten it and put it up in a a way that no body recognises!!Its your decision finally,but I think people would come up with more solution if they understand your code.Right now your question is too short to elaborate the exact problem you are having. –  Jun 20 '13 at 17:04
  • 1
    @jayeshjain (+1) has given the right answer: To improve CPU performance, requestAnimationFrame will suspend itself when the user switches browser tabs. When the user switches back to the RAF tab the animation will continue where it left off. If you want the animation to continue in your absence use setTimeout or setInterval instead of RAF. – markE Jun 20 '13 at 18:40
  • @markE requestAnimationFrame running or not is not my problem it is knowing when it is and when it isn't in order to update delta timestamps for a physic step. Check the accepted answer to fully understand what I meant, thanks everyone for your input – GriffLab Jun 21 '13 at 01:19
2

A solution I used in a project for canvas repainting. It's not 100% accurate but it works for out of focus users

// This will run when user is inactive
let = handleVisibilityChange = () => {
    if (document.hidden) {
        setTimeout(() => {
            updateYourStuff();
            handleVisibilityChange();
        }, 1000);
    }
};

// Listen if user is active or inactive
document.addEventListener("visibilitychange", handleVisibilityChange, false);

// Your loop when user is active
function myLoop() {
    updateYourStuff();
    requestAnimationFrame(myLoop);
}
roYal
  • 197
  • 1
  • 2
  • 16
0

If you need to know at what time a frame was painted, you can call requestPostAnimationFrame (google canary) or use a polyfill for it.

Spankied
  • 1,626
  • 13
  • 21