1

While working with the requestAnimationFrame API, I encountered a problem. It might be because the structure I use is wrong, but it seems logical to me.

What I basically do is a very easy background-position manipulation for an infinite falling effect:

( This version is simplified, but demonstrative )

cache.mechanism.snowFall = function(){

    cache.snow.position.y ++;
    if( cache.snow.position.y > cache.viewport.height ){ 
        cache.snow.position.y -= cache.viewport.height; 
    }
    cache.snow.elem.style.backgroundPosition = "0px " + cache.snow.position.y + "px";

    requestAnimationFrame( cache.mechanism.snowFall );

};

Actually, it moves the background position 1px lower with every animation frame. ( Resets when neccessary, to avoid high paint times, and FPS loss )

I initialize it by calling:

cache.mechanism.snowFall();

So, it runs fine, with a very high FPS, but it is not possible to stop it.

cancelAnimationFrame( cache.mechanism.snowFall );

-does nothing, and returns undefined.

István Pálinkás
  • 2,217
  • 7
  • 25
  • 50

1 Answers1

18

You should send the id of the requestAnimationFrame you want to cancel into cancelAnimationFrame. That id is a return value of the original requestAnimationFrame.

So request one animation loop:

var id = requestAnimationFrame(cache.mechanism.snowFall);

And to cancel that request:

cancelAnimationFrame(id);

Alternatively, since requestAnimationFrame must be called to keep the loop running, you could use a flag to stop the animation:

// Set an external flag to allow animations to continue
var continueAnimating = true;

function animate()
{
    if(continueAnimating)
    {
        // when continueAnimating is false, this new
        // request will not occur and animation stops
        requestAnimationFrame(animate); 
    }
}

// To turn off animation
continueAnimating = false;
David Callanan
  • 5,601
  • 7
  • 63
  • 105
markE
  • 102,905
  • 11
  • 164
  • 176