Lately, I've been trying to learn more about the new animation features of the ngAnimate module available as of AngularJS 1.2. In my reading, I saw mention of the ability to "stagger" animations. As someone who has a love-hate relationship with user interface (UI) transitions, this struck me as something I wouldn't fall in love with; but, I wanted to take a look at it before I cast any (too much) judgement.
Staggering only makes sense (for ngRepeat) when you are animating multiple ngRepeat items at the same time. By default, all items will animate into place concurrently. However, if you stagger the animation, it will add a delay before each successive animation.
To stagger animations, you need to provide a "-stagger" CSS event class that defines the duration of the delay. Since I'm animating the "enter" event, I'm providing the "ng-enter-stagger" class. I don't know enough about CSS transitions vs. animation keyframes; but, apparently both approaches work. In this demo, I'm using transitions because it's what I'm used to; and, it's what AngularJS has in its documentation.
NOTE: I assume that you can stagger "leave" animations, although I haven't tested it personally.
One important thing to understand about staggering animations is that it doesn't delay the actual cloning and linking of the ngRepeat items. This is critical to understand because it means that your "staggered" DOM elements are sitting there on the page, waiting to be animated. As such, if your animation setup class (ex, "ng-enter") doesn't fully hide the pending elements, they will be visible to the end user.
To experiment with this, I created a demo in which you can add friends to a list. Remember, ngAnimate blocks animations during the initial page loading and bootstrapping. As such, the animations (including the staggering) will only show when subsequent friends are added to the already-rendered list.
The great thing about AngularJS animations is that they are all CSS-driven. The staggering of animations is no different. My Controller code knowns nothing about any of this - it's all defined in the various CSS classes for setup, staggering, and activation.
NOTE: There are non-CSS-based options for animations as well.
I love animations and user interface (UI) transitions when the serve a purpose and feel natural. My biggest concern with staggering animations is that they might make the user "overly aware" of the animations by adding additional time-to-complete. As such, I would suggest that you apply "staggering" with caution. I am sure there are good use-cases for it; but, I would defer it to a final "polishing" step in development. But, that's just my opinion.
Want to use code from this post? Check out the license.
Hi, i tried using stagger animations on ng-repeats on load of the page, but there seems a problem as when ever i filter the list or sort the list more elements add onto the ng-repeat.
I used $timeout to have the delay on load of the page, but now, i am not sure how to proceed.
one silly question: how did you pause the dom animantion in firebugs to actually view the class name ,like " ng-aninamte" ?
Great question. When I have to capture something like that, I usually one of two things (or both):
1. I'll use a really large animation duration - like 50-seconds. That way, I have plenty of time to inspect the element while the animation is still running. In reality, the code I commit has really small animations - but I'll tweak the timing specifically for screen shots.
It sounds like your might need to add a "track by" in the ngRepeat to ensure that the same items in the list are tracked by the same identifier. It could be that existing [filtered] items are being added to the list because they are being created with new object references? I'm not entirely sure.
not working in angular 1.4 :(