javascriptrequestanimationframecancelanimationframe

storing requestAnimationFrame


Brief explanation:

I've made a requestAnimation which alternatively has 2 callbacks depending on counter;

one of the callbacks will increment counter and the other will decrease it (always looping inside a certain range 0 // arr.length).

Everything works as expected until stopping and restarting the animation,
this is the code that activates and should store the requestAnimationFrame ( click() ):

function start() {
        if (!spiral) {
            spiral = window.requestAnimationFrame(animation);
        }
    }

function click() {
        if (spiral) {
            var trackSpiral = spiral;
            spiral = undefined;
            window.cancelAnimationFrame(spiral);

         } else {

          spiral = trackSpiral;
    /* (count > precedingCount || count == 0 ) ?
                    spiral = requestAnimationFrame(animation) :
                    spiral = requestAnimationFrame(animationReverse);*/              
         }
   }
        window.addEventListener('load', start)

        window.addEventListener('click', click)

As a workaround I've used a precidingCount var and depending on whether if it's increasing or not it can decide which requestAnimationFrame callback to fire;

Questions:

Can somebody explain why just storing and recalling the var assigned to requestAnimation doesn't work as I'd expect?

Is there a better pattern to stop-restart requestAnimation?

here's a working pen (to see the issue comment lines from 180 to 182)_


Solution

  • After each tick, you must re-request the animation frame. requestAnimationFrame is not something like setInterval that you need to cancel.

    var animating = false;
    
    function tick() {
        if (!animating) return;
        animate();                          // do one step of animation
        window.requestAnimationFrame(tick); // request next frame
    }
    
    function click() { if (animating = !animating) tick(); }
    
    window.addEventListener('load',  click);
    window.addEventListener('click', click);