Reputation: 1368
I'm trying to build a menu with a reveal animation somewhat like a card animation.
The whole stack of menu items starts at the same position, and then as the stack moves the individual menu items stop at their destination along the way until the last item arrives at its destination.
I almost have it working here: http://jsfiddle.net/XVuPQ/2/
for(var j = 0; j < topItems; j++) {
$col2.append(
$('<div>')
.addClass('absColItem')
.css({
'top': $(this).position().top + 22,
'left': '-100px'
})
.animate({
'left': 0
}, 100)
.animate({
'top': ($(this).position().top + 22) - (j * (itemHeight + 10))
}, (j + 1) * 500)
.data('parent', $(this))
);
}
but the timing of the items doesn't line up the way I would like.
Does anyone have any ideas as to how I could achieve the effect?
Edit - The answers so far are helpful, but here is a crude animation for what I'm trying to achieve.
Upvotes: 1
Views: 192
Reputation: 663
The default easing jQuery uses is called swing
, which makes the items animate at an uneven speed. For the effect you want, use linear
easing, the other option provided by jQuery:
.animate({ /* animation parameters */ },(j + 1) * 500, 'linear')
.animate({ /* animation parameters */ },(k + 1) * 500, 'linear')
jQueryUI provides a variety of other easing options if you need more to choose from or just want to see what they look like.
I modified your code to run the entire animation in a single loop. Not sure if this helps you, but it is a lot cleaner and it was a lot of fun to do:
Here are the results: http://jsfiddle.net/corymcd/RsgQd/5/
Benefits:
Adjust the speed of the animation based on the object's relative position to the stack:
.animate({ /* animation parameters */ },(j/topItems + 1) * 500)
.animate({ /* animation parameters */ },(k/bottomItems + 1) * 500)
Here is a fiddle: http://jsfiddle.net/QY3zD/
You'll notice without the scaling based on max distance (the way you originally had it) that the animation will take longer if you have more items on one side than the other- especially on the top and bottom.
You can easily adjust the time for the animation by replacing the 500
with a single configurable variable. The full animation will take between one and two times the duration you specify.
If you want it take exactly as long as the duration (e.g. 500
), remove the + 1
, and the outermost elements will always take that long to reach their final positions. If you do this, you might want to include a baseline in addition to the multiplication so that the initial elements do not animate instantly: ((k/bottomItems) * 400)+100
Upvotes: 5
Reputation: 2374
In .animate({...})
have a value 500
this determines the speed of the animation. Change the value according to what you want.
UPDATE
In your example have 3 effects
$(this).animate({
'opacity': 0,
'top': $(this).data('parent').position().top + 22
}, 200, function(){
$(this).remove();
});
Set the speed to remove/change "cards"
animate({
'top': ($(this).position().top + 22) - (j * (itemHeight + 10))
}, (j + 1) * 500)
.data('parent', $(this))
Set the speed to up
.animate({
'top': ($(this).position().top + 22 + itemHeight + 10) + (k * (itemHeight + 10))
}, (k + 1) * 500)
.data('parent', $(this))
Set the speed to down
Upvotes: 1