Reputation: 18734
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
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
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));
SVG Vertigo(unfinished)
Upvotes: 0
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