maioman
maioman

Reputation: 18734

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)_

Upvotes: 1

Views: 1047

Answers (3)

allenhwkim
allenhwkim

Reputation: 27738

I think your approach is different from common usage. I recommend to call it when needed instead of start/stop.

I learned this lesson when I have created a animation library , which is very simple and small

https://github.com/allenhwkim/jsanimation

Usage

import {slideInRight} from 'jsanimation';
slideInRight(el);

Upvotes: 0

TarranJones
TarranJones

Reputation: 4242

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

You need to declare var out side of the functions, if the var is only declared in a function then it is restricted to that scope.

Is there a better pattern to stop-restart requestAnimation?

You cont need to stop/start, just don't request the next frame. for instances where there is an infinite loop you might want to use cancelAnimationFrame;

(function rAF(){
    // animate .... call again
    rAF_id = window.requestAnimationFrame(rAF)
}();
// .. wait ... cancel
setTimeout( window.cancelAnimationFrame(rAF_id), 5000)

The following code should start forwardAnimation, stop forwardAnimation, start reverseAnimation, stop reverseAnimation and repeat.

(function(callback1, callback2, animating) {

  callback = callback1;

  function click() {
    if (animating = !animating) {
      callback = callback !== callback1 ? callback1 : callback2;
      (function loop() {
        rAF = window.requestAnimationFrame(loop);
        callback();
      })();
    } else {
      window.cancelAnimationFrame(rAF);
    }
  }

  window.addEventListener("load", function load() {
    click();
    window.removeEventListener("load", load);
    window.addEventListener('click', click);
  });
}(forwardAnimation, reverseAnimation));

Working Example

SVG Vertigo(unfinished)

Upvotes: 0

user663031
user663031

Reputation:

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);

Upvotes: 1

Related Questions