Edgar
Edgar

Reputation: 363

Queue multiple jquery animation

Did someone try to manage common animation queue?

I want to get something like producer/consumer in back-end programming, so that any event triggering some animation could add it's piece of needed animation to general queue, which is being constantly processed like a chain.

I cannot find what is wrong. When I log the execution, it is going right order, but JS completely mixes up my chain of animating tasks, when I quickly trigger several animations.

I compiled some example on jsFiddle. I have a simple structure of absolutely positioned ".anim" blocks, which are being animated by "left" position:

<div id="anims_wrap">
    <div class="anim even" id="anim0">0</div>
    <div class="anim odd" id="anim1">1</div>
    <div class="anim even" id="anim2">2</div>
    <div class="anim odd" id="anim3">3</div>
    <div class="anim even" id="anim4">4</div>
    <div class="anim odd" id="anim5">5</div>
    <div class="anim even" id="anim6">6</div>
    <div class="anim odd" id="anim7">7</div>
    <div class="anim even" id="anim8">8</div>
    <div class="anim odd" id="anim9">9</div>
</div>

And the following basic method, which is adding to queue a function exiting last animated blocks and running new animation piece for some 3 blocks. The chain is being called only when each animation is complete. Own animation queue is set to false.

function queueAnimation(animId) {//animId is between 1 & 5, sent by the button triggering the animation..

    var animWrap = $("#anims_wrap");
    var animId1 = animId - 1;
    var animId2 = animId + 2;
    var animId3 = animId === 5 ? 0 : animId + 5;


    animWrap.queue("anims_queue", function (next) {
        exitPositionedAnimation(function () {

            $("#anim" + animId1).addClass("positioned").animate({
                left: 50
            }, {
                duration: 4000,
                queue: false
            });
            $("#anim" + animId2).addClass("positioned").animate({
                left: 150
            }, {
                duration: 6000,
                queue: false,
                complete: next
            });
            $("#anim" + animId3).addClass("positioned").animate({
                left: 200
            }, {
                duration: 5000,
                queue: false
            });

            console.log(animId1 + "," + animId2 + "," + animId3)
        });
    });

    //the only way I found to check if animation is in process..
    if (!$._data(animWrap[0], "anims_queue.run")) {
        animWrap.dequeue("anims_queue");
    }
}

I simplified the code as much as I could keeping the principle implemented. Just try to quickly press several anim buttons and you will see the mix-up.

Maybe I really expect too much from JavaScript :)

Upvotes: 0

Views: 1082

Answers (1)

Edgar
Edgar

Reputation: 363

Seems I have found the issue... looks like normally working now!

My mistake was to rely on jquery internal data cached to check if queue is running:

if (!$._data(animWrap[0], "anims_queue.run")) {
    animWrap.dequeue("anims_queue");
}

This cache is being removed very fast and new animation events are duplicating "dequeue" call when animation is actually going.

Here you can see updated version. Now I maintain "isQueueRunning" variable, which is being set to false by "lastQueueFunction", which I always keep at the end of the chain.

Hope someone will find this helpful.. :)

Upvotes: 1

Related Questions