0

This is my animation experiment, it works mostly as I expect. However, I want to animation happen one by one. That means the div with id1 does the animation first, then div with id2...etc. I use a for loop to do the trick but the animation happens just too fast. Could anyone let me know how I can make the animation happen one by one instead of animating all the divs almost simultaneously. Thanks in advance for any kind helpers.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>jQuery Animation - jsFiddle demo by dennisboys</title>

  <script type='text/javascript' src='//code.jquery.com/jquery-1.9.1.js'></script>



  <link rel="stylesheet" type="text/css" href="/css/result-light.css">

  <style type='text/css'>
    .items {
    float: left;
    margin-right: 3px;
    height: 50px;
    width: 50px;
    background-color: lightblue;    
}
  </style>



<script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
/*
Javascript logics:
1. One click on each div can generate a full animation.
    - using a for loop to do the div animation
*/

$(document).ready(function(){

    // global variable for holding a fixed height increase
    var newHeight = 50;

    // global counter to keep track of which div is being clicked
    var counter = 1

    // count the number of divs on this page, a total of 9
    var divCount = $('.items').length; 

    $('.items').click(

        function(){         

            for(i=1; i<=divCount; i++){     

                // increase the global variable by 50
                newHeight += 50;

                // set random width and height
                var randomWidth = Math.floor( Math.random() * 201 + 50 );  // generate a number from 50 - 250
                var randomHeight = Math.floor( Math.random() * 201 + 50 );      

                $('#' + i).animate( {width:randomWidth, opacity:'0.3'}, 1000 );
                $('#' + i).animate( {height:randomHeight, opacity:'1' }, 1000 );
                $('#' + i).animate( {width:'50', opacity:'1'}, 1000 );
                $('#' + i).animate( {height:newHeight, opacity:'1' }, 1000 );

            }

        });

});
});//]]>  

</script>


</head>
<body>

        <div class="items" id="1" status="true"></div>
        <div class="items" id="2" status="true"></div>
        <div class="items" id="3" status="true"></div>
        <div class="items" id="4" status="true"></div>
        <div class="items" id="5" status="true"></div>      
        <div class="items" id="6" status="true"></div>
        <div class="items" id="7" status="true"></div>
        <div class="items" id="8" status="true"></div>
        <div class="items" id="9" status="true"></div>  

</body>


</html>

Here is the jsfiddle page.

http://jsfiddle.net/dennisboys/Qq247/

Dennisboys
  • 583
  • 3
  • 9
  • 22
  • try to add delay() before animate, where you will multiply some number for miliseconds by i: `$('#' + i).delay(5000*i).animate( {width:randomWidth, opacity:'0.3'}, 1000 ); $('#' + i).delay(5000*i).animate( {height:randomHeight, opacity:'1' }, 1000 ); $('#' + i).delay(5000*i).animate( {width:'50', opacity:'1'}, 1000 ); $('#' + i).delay(5000*i).animate( {height:newHeight, opacity:'1' }, 1000 );` – Nikola Kirincic Jul 29 '13 at 10:32
  • Hi niklaz, actually I tried delay(), but I might have put the function into a wrong place because even I use delay() the animation happen simultaneously. Like this "$('#' + i).animate( {width:'50', opacity:'1'}, 1000 ).delay(1000).animate( {height:newHeight, opacity:'1' }, 1000 )" – Dennisboys Jul 29 '13 at 10:37
  • Hi niklaz, your codes works but it lags very much and is not a good user-friendly animation. Is there any other way to achieve that? – Dennisboys Jul 29 '13 at 10:40
  • I will suggest you one thing. If you have 4 to 5 animations on one page and your target device is iPad.Don't use jQuery Animation. I had to change my whole straergy.Instead Use CSS3 animations. Check this : http://stackoverflow.com/questions/10984771/whats-faster-css3-transitions-or-jquery-animations – Nagesh Salunke Jul 29 '13 at 10:41
  • @Dennisboys, I will reply on separate answer – Nikola Kirincic Jul 29 '13 at 10:49
  • @Dennisboys I have updated my code as it had an error on the scope/valuation of the `newHeight` variable. I have included a [JSFiddle](http://jsfiddle.net/gvee/Qq247/4/) with refactored code. – gvee Jul 29 '13 at 11:25

3 Answers3

1

Updated JSFiddle

Rather than trying to delay animations and work our timings etc you can simply set a function call to happen when your animation step is complete.

The animate() function optionally accepts extra parameters. From the manual:

.animate( properties [, duration ] [, easing ] [, complete ] )

...

complete

Type: Function()

A function to call once the animation is complete.

This means you can call a function when your animation is complete. Here's a simple example:

$('div').click(function() {
    $(this).animate({width: 200}, 5000, function() {
        alert('animation complete');
    });
});

In the above code we are popping up a message after the initial animation (width: 200px) is complete.

So how is this useful to you? Well, what if we call our second animation once the first has completed, and the 3rd after that had completed, and so on?

$('#' + i).animate({width:randomWidth, opacity:'0.3'} , 1000, function() {
    $(this).animate({height:randomHeight, opacity:'1' }, 1000, function() {
        $(this).animate({width:'50', opacity:'1'}, 1000, function() {
            $(this).animate( {height:newHeight, opacity:'1' }, 1000);
        });
    });
});

EDIT: Here's your code after refactoring:

function letsGo(i, newHeight) {
    var randomWidth = Math.floor(Math.random() * 201 + 50);
    var randomHeight = Math.floor(Math.random() * 201 + 50);
    $('#' + i).animate({width:randomWidth, opacity:'0.3'} , 1000, function() {
        $(this).animate({height:randomHeight, opacity:'1' }, 1000, function() {
            $(this).animate({width:'50', opacity:'1'}, 1000, function() {
                $(this).animate( {height:newHeight, opacity:'1' }, 1000);
            });
        });
    });
}

$('.items').click(function () {
    var newHeight = 50;
    var divCount = $('.items').length; 

    for(i=1; i<=divCount; i++) {
        letsGo(i, newHeight);
        newHeight += 50;
    };

});
gvee
  • 16,732
  • 35
  • 50
0

why not use delay....

here something like this

$(document).ready(function() {
    $('#1').delay(8000).fadeIn(400);
    $('#2').delay(7000).fadeIn(400);
});

but please make sure yr div is hidden at first

<div class="items" id="1" status="true" **style="display:none"**></div>
0

Ok, my suggestion in comment was just simple sample, delay duration is too long, as well as animation duration. This is your js code changed, so you have some smoother overlaps in delays, and faster animations ( I have put some comments as explanation):

$(document).ready(function(){

    // global variable for holding a fixed height increase
    var newHeight = 50;

    // global counter to keep track of which div is being clicked
    var counter = 1

    // count the number of divs on this page, a total of 9
    var divCount = $('.items').length; 

    $('.items').click(

        function(){         

            for(i=0; i<=divCount; i++){ //i=0, so first animation doesn't have delay. It can be done other ways, this is just one of them.      

                // increase the global variable by 50
                newHeight += 50;
                var delayInit  = 300-20*i; //this way we have overlap delays, so next animation of new element starts as previous is still doing
                var animationDuration = 300; //better to have out this param, so you can change it at one place
                // set random width and height
                var randomWidth = Math.floor( Math.random() * 201 + 50 );  // generate a number from 50 - 250
                var randomHeight = Math.floor( Math.random() * 201 + 50 );      

                $('#div' + (i+1)).delay(delayInit*i).animate( {width:randomWidth, opacity:'0.3'}, animationDuration,'linear' ); //if you want smoother animations, try to add after animationDuration some other easing option like easeOut, swing, linear, etc. instead of 'linear'. 
//For further and correct reference, consult with: http://api.jquery.com/animate/#animate-properties-duration-easing-complete
                $('#div'  + (i+1)).delay(delayInit*i).animate( {height:randomHeight, opacity:'1' }, animationDuration );
                $('#div'  + (i+1)).delay(delayInit*i).animate( {width:'50', opacity:'1'}, animationDuration);
                $('#div'  + (i+1)).delay(delayInit*i).animate( {height:newHeight, opacity:'1' }, animationDuration );

            }

        });

});

Also, you will notice that I changed selectors, so I suggest you to do that as well, so assign for id something as div1, div2, etc... try avoiding pure numbers. Also, you will see that I changed the loop count start from 0.

Nikola Kirincic
  • 3,651
  • 1
  • 24
  • 28
  • Thanks niklaz! Sorry I can only give one tick! I gave it to gvee, his solution inspired me to a own solution. Thanks again for your input! – Dennisboys Jul 30 '13 at 04:05