Search code examples
javascriptcanvaskineticjs

KineticJS: How can I keep a tween running while it's browser tab is not active?


Here's my tween function:

var secondsNotchTween = function() {

    var tween = new Kinetic.Tween({
        node: secondsNotchShape,
        rotationDeg: currentRotationDegree + 6,
        duration: 0.5,
        easing: Kinetic.Easings.ElasticEaseOut
    });

    return {
        tween: tween
    };

};

I am calling it each second with setTimeout like that:

var secondsNotchAnimation = function() {
    secondsNotchTween().tween.play();
};

var playSecondsNotchAnimation = function() {

    minuteNotchTimeout = setTimeout(function() {

        secondsNotchAnimation();
        playSecondsNotchAnimation();

    }, displayTime().intervalToSecond);

};

It's working just as I want it to, however when the animation is in the 'background' (it's not in the current browser tab) the tween is not really executing. I presume it's some sort of requestAnimationFrame issue however I can't seem to find a way around it? Has anyone else encountered such issue?


Solution

  • You presumption is correct.

    KineticJS animations use requestAnimationFrame to drive its animations and RAF will automatically halt execution when its browser tab is not focused. Changing the internals of KineticJS animation processing is not recommended.

    The workaround would require you to create your own requestAnimationFrame loop that advances your animation based on elapsed time rather than framecount.

    Luckily, RAF has anticipated this need.

    When the tab regains focus RAF will send a timestamp to your animation loop. You can use that timestamp to calculate elapsed time. Then you can properly advance your animation to reflect the elapsed time rather than the framecount of a halted animation loop.

    You'll have to decide whether it's worth recreating the animation functions (and easings) outside of the KineticJS structure. It's certainly not difficult, but the quantity of functionality to recreate is large.

    Either way...good luck with your project!