Etienne Noël
Etienne Noël

Reputation: 6166

Timeouts and javascript

I want to generate 4 circles when the page loads. However, even though the function is called 4 times, I'm only seeing one. I'm wondering what part I'm missing. Is it because when the function finishes, all the timeouts it had started are cleaned up ?

function getRandom(min, max) {
    return Math.floor((Math.random()*max)+min);
}

function generateCircle(leftPos, topPos, zIndex) {

    $circle = $('<div class="cercleAnime"></div>');
    $('body').append($circle);
    var self = this;

    self.leftPos = leftPos;
    self.topPos = topPos;

    $circle.css({
        'left' : self.leftPos+'px',
        'top' : self.topPos+'px',
        'z-index' : zIndex
    });

    $circle.animate({'width' : '300px', 'height' : '300px'}, {
        duration : 5000,
        progress: function() {
            newLeft = self.leftPos - $(this).width()/2;
            newTop = self.topPos - $(this).height()/2;

            $(this).css({
                'left' : newLeft+'px',
                'top' : newTop+'px'
            })
        },
        done: function() {
            $(this).remove()
        }
    } );

}


function generateCircles(numberOfCircles, intervalBetweenCircles) {
    leftPos = getRandom(1,1000);
    topPos = getRandom(100,400);
    zIndex = 1000;
    timeoutTime = intervalBetweenCircles;

    for(var i = 0; i < numberOfCircles; i++) {
        zIndex--;
        setTimeout(function(){generateCircle(leftPos, topPos, zIndex)}, timeoutTime);
        timeoutTime += intervalBetweenCircles;
    }

}



$(function() {
    generateCircles(3, 2000);

    generateCircles(3, 2000);

    generateCircles(3, 2000);

    generateCircles(3, 2000);




});

Here's is a jsfiddle: http://jsfiddle.net/etiennenoel/BwyH7/

Upvotes: 0

Views: 76

Answers (1)

user2864740
user2864740

Reputation: 61875

You are drawing circles with the same characteristics 4 times. (They nicely stack on top of each other and hide previous circles.)

This is because leftPos and topPos (etc) in generateCircles are global variables and are overwritten before the first circle even draws. Remember that the setTimeout callback will run "at some point in the future".

One solution is to use local variables such that they are bound in the closure:

var leftPos = getRandom(1,1000);
var topPos = getRandom(100,400);
// etc

(The closures in scope, i.e. the function passed to setTimeout still has access to these local variables .. that is what makes a closure a closure, after all.)

Upvotes: 3

Related Questions