HJ05
HJ05

Reputation: 1368

Deck reveal animation

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.

Crude deck animation

Upvotes: 1

Views: 192

Answers (2)

Corion
Corion

Reputation: 663

The Answer

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.

Going Beyond ...

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:

  • Combined it with my original answer below so your animation will never take longer than the allotted time.
  • Items are added and animated in a single location regardless of top/bottom.
  • Items are animated/displayed in the order you originally added them.

Another Option

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

PiLHA
PiLHA

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

Related Questions