views:

51

answers:

4

Okay, I'm trying to be clear on this one...

I have some insliding boxes, all with the same class .box When the page loads I want these slide in from the left. This works perfect according to this code:

$(document).ready(function(){
    $(".box").animate({left: "-=920px", opacity: "1"}, 1250)
    return false;
});

Now all the boxes are flying in at the same time. What I want is that the top box goes first, and the second box slides in a second later, en the third a second later than the second box, making a sort of chain reaction.

How can I achieve this, and still keep one class(to keep things dynamic)?

I'm also looking to create a blur to no-blur effect, if anyone has some ideas on that as well would be awesome, but it's not the priority

Edit: Complete code for testing:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"&gt;&lt;/script&gt;

<script type="text/javascript"> 
$(document).ready(function(){
    $(".box").animate({left: "-=920px", opacity: "1"}, 1250)
    return false;
});
</script> 

<style type="text/css"> 
.box {
    background: #6699FF;
    height: 100px;
    width: 100px;
    position: relative;
    margin-left: 920px;
    opacity: 0.0;
}
#main_box{
    overflow: hidden;
    padding: 5px;
    border: 3px solid;
}
</style> 

<div id="main_box">
    <div class="box">
    </div>
    <div class="box">
    </div>
    <div class="box">
    </div>
</div>
+1  A: 

Here's my implementation of something that's essentially what you're asking. I'll work on more general solution and post it when it's ready, but if you have any questions, let me know.

jQuery.fn.staggeredAnimate = function() {
  // initialize array of offsets
  var off = []

  // add each element's aggregate offset to the offsets array
  this.each(function(){
    off.push($(this).offset().left + $(this).offset().top)
  })

  // find the maximum and minimum offsets
  var omax = Math.max.apply(Math, off)
  var omin = Math.min.apply(Math, off)

  // fade in each element in a timing relative to the offsets
  return this.each(function(){
    var ratio = ($(this).offset().left + $(this).offset().top - omin) / omax
    var delay = 500 * (ratio)
    $(this).delay(delay).animate({opacity: 1})
  })
}

Here's a general solution based on your requirements. Just pass in the function you want staggered in as the first argument. Note that this takes advantage of the jQuery animation stack, so if you set jQuery.fx.off = true, the callbacks will all execute immediately.

jQuery.fn.staggeredAnimate = function(func, delay) {
  if(delay == undefined) delay = 500;
  return this.each(function(i){
    $(this).animate({dummy: 1}, delay * i, func);
  });
}

Here's the function in action: http://jsfiddle.net/V9NzR/

Steven Xu
Great answer as well! Gave you an upvote! Thanks!
Rick de Graaf
+3  A: 

It's easy if you're using jQuery 1.4 or later.

http://jsfiddle.net/9GjsC/

$(".box").each(function( index ) {
    $(this).delay( index * 1000 ).animate({left: "-=920px", opacity: "1"}, 1250);
});
patrick dw
If not, using `.animate({dummy: 1}, duration, callback)` will accomplish the same thing.
Steven Xu
This works perfectly. Adapting the 1000 in index * 1000 to for example 250 create the boxes to appear close during the previous one animation!Thanks!!
Rick de Graaf
@Rick - You're welcome. :o)
patrick dw
A: 

My contribution:

​$(function(){
   var move = function(){
       var self = this;
       move.delay = move.delay ? move.delay+=1000 : 1;

       setTimeout(function(){
           self.animate({
               left: '+=500'
           }, 1000);
       }, move.delay);
   };       

   $('.box').each(function(){
       move.apply($(this), []);        
   });
});​

Link: http://www.jsfiddle.net/zDSJ3/

Patricks solution might be the best, I just felt like doing something overcomplicated :p

jAndy
+2  A: 

Modify your jquery code like this:

var boxes = $('.box');
i = 0;

$(document).ready(function(){
    $(boxes[i++] || []).animate({left: "-=920px", opacity: "1"}, 1250, arguments.callee)
});

Here is the working demo.

Sarfraz