0

I have tried to make two squares move at the same time... I know the first animation is repeating to infinite but what should i do?

JsFiddle

1
  • You really should put your code in your question so someday in the future when the jsFiddle is gone, this question can still be used by others to learn. Commented Mar 15, 2013 at 0:21

3 Answers 3

2

Both of the other solutions are correct, but please, PLEASE don't make your code a list of if else conditions with a massive inside block. Consider, instead the following solution:

http://jsfiddle.net/NM78r/

$(document).ready(function(){ animateTheBox('block1',0); animateTheBox('block2',2); }); function animateTheBox(block,i) { var animation = {}; var duration = 3000; var easing = 'linear'; var done = function(){ animateTheBox(block, (i+1)%4); }; switch(i){ case 0: animation = {'left' : "-=100px"} break; case 1: animation = {'top' : "-=100px"} break; case 2: animation = {'left' : "+=100px"} break; case 3: animation = {'top' : "+=100px"} break; default: return; //This is so you can't call the function in weird ways, as before. } $('.' + block).animate(animation, duration, easing, done); } 

Use a switch statement to determine what kind of animation to do, then only write the actual animation call once. This kind of abstraction is easier to read, and has the added benefit of being way more maintainable. You can be sure that your animation will be done the same way every single time.

EDIT:

Though the above design pattern is probably better in the long run, you could easily do this with an array instead:

$(document).ready(function(){ animateTheBox('block1',0); animateTheBox('block2',2); }); function animateTheBox(block,i) { var animations = [ {'left' : "-=100px"} , {'top' : "-=100px"} , {'left' : "+=100px"} , {'top' : "+=100px"} ]; var duration = 3000; var easing = 'linear'; var done = function(){ animateTheBox(block, (i+1)%4); }; if ( i < 0 || i >= animations.length) return; //Don't deal with out of bound numbers. $('.' + block).animate(animations[i], duration, easing, done); } 

http://jsfiddle.net/4S6Mg/1/

And actually, this could make multi step animation abstraction really easy:

$(document).ready(function(){ var block1Steps = [ {'left' : "-=100px"} , {'top' : "-=100px"} , {'left' : "+=100px"} , {'top' : "+=100px"} ]; var block2Steps = [ {'left' : "+=100px"} , {'top' : "+=100px"} , {'left' : "-=100px"} , {'top' : "-=100px"} ]; multiAnimate($('.block1'), block1Steps, 3000, 'linear', true); multiAnimate($('.block2'), block2Steps, 3000, 'linear', true); }); function multiAnimate(item, animations, duration, easing, infinite){ var i = -1; var step = function(){ i++; if (infinite) i %= animations.length; if (i >= animations.length) return; item.animate(animations[i], duration, easing, step); }; step(); } 

http://jsfiddle.net/jp2K4/

Then, if you wanted to get REALLY Apeshit, you could give each animation its own duration and easing, and BAM! You've basically created for yourself a little arbitrary multistep animation library.

function multiAnimate(item, animations, duration, easing, infinite){ var defaultDuration = 1000; var defaultEasing = 'linear'; var i = -1; var step = function(){ i++; if (infinite) i %= animations.length; if (i >= animations.length) return; item.animate(animations[i].animation , (animations[i].duration)? animations[i].duration: defaultDuration , (animations[i].easing)? animations[i].easing: defaultEasing , step ); }; step(); } $(document).ready(function(){ var block1Steps = [ { animation: {'left' : "-=100px"} , duration: 3000 , easing: 'linear' } , { animation: {'top' : "-=100px"} , duration: 1000 , easing: 'swing' } , { animation: {'left' : "+=100px"} , duration: 5000 , easing: 'swing' } , { animation: {'top' : "+=100px"} , duration: 2000 , easing: 'linear' } ]; var block2Steps = [ { animation: {'left' : "+=100px"} , duration: 5000 , easing: 'swing' } , { animation: {'top' : "+=100px"} , duration: 2000 , easing: 'linear' } , { animation: {'left' : "-=100px"} , duration: 3000 , easing: 'linear' } , { animation: {'top' : "-=100px"} , duration: 1000 , easing: 'swing' } ]; multiAnimate($('.block1'), block1Steps, 3000, 'linear', true); multiAnimate($('.block2'), block2Steps, 3000, 'linear', true); }); 

http://jsfiddle.net/nnQU8/

Sign up to request clarification or add additional context in comments.

3 Comments

+1 The amount of times I've replaced other coders' if else if else if else jungles with switch...
@popnoodles - you're darn right. I added a couple iterations. Not all of them reduce the number of lines, but I like to think of each of them as an improvement.
Thank you for your sugestions :D
2

The reason is you need to wait for the first animation to complete before telling the box to begin the next set of animation. In your code, you're not giving the red box a chance to begin animating because the yellow one is constantly doing it (there is a closure created by the animateTheBox and both boxes are calling it) :)

So I added the complete function handler to your .animate() and moved the animateTheBox() call into there.

See: http://jsfiddle.net/DkmKA/

1 Comment

Thank you! trying to understand now :)
1

You need to use the completion function of each animation to start the next animation like this:

$(document).ready(function(){ animateTheBox('block1',0); animateTheBox('block2',2); }); function animateTheBox(block,i) { if (i==0) { $('.'+block).animate({'left' : "-=100px"}, 3000, 'linear', function() { animateTheBox(block,1); }); } else if (i==1) { $('.'+block).animate({'top' : "-=100px"}, 3000, 'linear', function() { animateTheBox(block,2); }); } else if (i==2) { $('.'+block).animate({'left' : "+=100px"}, 3000, 'linear', function() { animateTheBox(block,3); }); } else if (i==3) { $('.'+block).animate({'top' : "+=100px"}, 3000, 'linear', function() { animateTheBox(block,0); }); } } 

Working demo: http://jsfiddle.net/jfriend00/39SUN/

In the spirit of DRY, here's a much shorter way of doing it:

$(document).ready(function(){ animateTheBox('.block1',0); animateTheBox('.block2',2); }); function animateTheBox(block,i) { var anims = [ {left: "-=100px"}, {top: "-=100px"}, {left: "+=100px"}, {top: "+=100px"}, ]; $(block).animate(anims[i], 3000, 'linear', function() { animateTheBox(block,(i+1) % 4); }); } 

Working demo: http://jsfiddle.net/jfriend00/nKuGs/

1 Comment

@smotru - I added a much shorter way of doing this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.