Not sure if this is what you want.
I revive 20 snowflakes, wait for the animation to finish for all of them , and then restart again.
jsfiddle
function fallingSnow() { var $snowflakes = $(), qt = 20; for (var i = 0; i < qt; ++i) { var $snowflake = $('<div class="snowflakes"></div>'); $snowflake.css({ 'left': (Math.random() * $('#site').width()) + 'px', 'top': (- Math.random() * $('#site').height()) + 'px' }); // add this snowflake to the set of snowflakes $snowflakes = $snowflakes.add($snowflake); } $('#snowZone').prepend($snowflakes); $snowflakes.animate({ top: "500px", opacity : "0", }, Math.random() + 5000, function(){ $(this).remove(); // run again when all 20 snowflakes hit the floor if (--qt < 1) { fallingSnow(); } }); } fallingSnow();
Update
This version creates only 20 partitions only once and revitalizes them again and again.
jsFiddle
function fallingSnow() { var $snowflakes = $(), createSnowflakes = function () { var qt = 20; for (var i = 0; i < qt; ++i) { var $snowflake = $('<div class="snowflakes"></div>'); $snowflake.css({ 'left': (Math.random() * $('#site').width()) + 'px', 'top': (- Math.random() * $('#site').height()) + 'px' }); // add this snowflake to the set of snowflakes $snowflakes = $snowflakes.add($snowflake); } $('#snowZone').prepend($snowflakes); }, runSnowStorm = function() { $snowflakes.each(function() { var singleAnimation = function($flake) { $flake.animate({ top: "500px", opacity : "0", }, Math.random() + 5000, function(){ // this particular snow flake has finished, restart again $flake.css({ 'top': (- Math.random() * $('#site').height()) + 'px', 'opacity': 1 }); singleAnimation($flake); }); }; singleAnimation($(this)); }); }; createSnowflakes(); runSnowStorm(); } fallingSnow();
Update2
This one, which initializes left after the animation for each snowflake, looks more natural in my opinion. The delay also changed from
Math.random() + 5000
to
Math.random()*-2500 + 5000
demonstration
Jose Rui Santos
source share