Opoe
Opoe

Reputation: 1387

How to loop an animation for multiple appended divs?

I made a div wich I animate with jquery.

The loop goes like this: to the right, then down, to the left, and down again.

When the start button is pressed, the first div starts the animation loop. The next div is appended at a random interval, same for the next one etc. BUT when a second div is appended, the whole animation loop goes nuts.

What I'm trying to accomplish: If a second div is appended, the first one should just complete it's animtion loop. And the second one and the ones after that also complete their loop.

Can you help me with this? Should I add counters for the classes or something?

(By the way I disabled the random appending code in this jsfiddle, so you can see the right animation loop first. Please enable to see the crazy effect)

Demo

HTML

<div id="arena">
    <div id="start">start</div>
</div>

jQuery

var counter = 0;

$("#start").on('click', function () {
    $("#arena").append('<div class="b"></div>');
    bbLoop();
    $("#start").hide();
});

function bbLoop() {
    bbRight();
}

function bbLeft() {
    $(".b").animate({
        left: "-=300"
    }, 1500, "swing", bbLeftDown);
}

function bbRight() {
    $(".b").animate({
        left: "+=300"
    }, 1500, "swing", bbRightDown);
}

function bbLeftDown() {
    $(".b").animate({
        bottom: "-=30"
    }, 300, "swing", bbRight);
}

function bbRightDown() {
    $(".b").animate({
        bottom: "-=30"
    }, 300, "swing", bbLeft);
}

/*

function doSomething() {}

(function loop() {
    var rand = Math.round(Math.random() * (3000 - 500)) + 500;
    setTimeout(function () {
        doSomething();
    $("#arena").append('<div class="b"></div>');
        loop();
    }, rand);
}());
*/

Upvotes: 0

Views: 182

Answers (1)

Zach Saucier
Zach Saucier

Reputation: 25954

Try this

It makes use of passing the same object through each function so that the appended elements can be animated separately from the first

$("#start").on('click', function () {
    $("#arena").append('<div class="b"></div>');
    bbLoop($('.b:eq(0)'));
    $("#start").hide();

    (function loop() {
        var rand = Math.round(Math.random() * (3000 - 500)) + 500;
        setTimeout(function () {
            var elem = $('<div class="b"></div>');
            $("#arena").append(elem);
            bbRight(elem);
            doSomething();
            loop();
        }, rand);
    }());
});

function bbLoop(obj) {
    bbRight(obj);
}

function bbLeft(obj) {
    obj.animate({
        left: "-=300"
    }, 1500, "swing", bbLeftDown(obj));
}

function bbRight(obj) {
    obj.animate({
        left: "+=300"
    }, 1500, "swing", function() { bbRightDown(obj) });
}

function bbLeftDown(obj) {
    obj.animate({
        top: "+=300"
    }, 300, "swing");
}

function bbRightDown(obj) {
    obj.animate({
        top: "+=300"
    }, 300, "swing", bbLeft(obj));
}



function doSomething() {}

Or if you want them removed at the end, check here. .animate works in quirky ways sometimes, thus the approximation of the end animation time in the setTimeout is necessary

Upvotes: 1

Related Questions