By Holly Schinsky
AngularJS recently came out with support for CSS3 transitions and animations, as well as JavaScript Animations. The support is part of version 1.1.4 (unstable build), but was changed and refined a bit in version 1.1.5 so you should start with that version when you check it out. I definitely think it’s worth trying because it allows you to add some fun interactions to your application quickly.
In this article I’ll explain a bit about how it all works and include links to a demo application I created to try things our for yourself. The source to the demo application is located on my GitHub account here as well. I also included some great resources in the form of links at the end of the post. There’s currently not a lot of documentation on this subject since it is so new, so I encourage you to check those out as well.
How it Works…
ngAnimate
is the name of the new directive for AngularJS animation support. The way it’s applied is by adding the ng-animate
attribute to any element containing one of the following directives in the list below:
The only exception to the above is when you create your own custom directive with animation support using the $animator
service. This is discussed later in the article.
Each of these directives causes a change to the DOM, which is how the transition or animation is triggered. For instance, on an ngRepeat
they will occur when the items are repeating, for ngShow
/ngHide
, when the element is being shown or hidden. You simply specify ng-animate
on your element with the name of the classes you’ve defined in your CSS to perform the transitions or animations and they will be applied automatically. Of course, you need to ensure you specify the ng-animate
on the same element where you have one of the directives mentioned above (ngRepeat
, ngSwitch
etc.) defined or nothing will happen.
Here’s a quick example of applying a scale type of transition the shorthand way (read on for notation details):
<ng-include ng-animate="'scale'" src="'partials/quote.html'"></ng-include>
Then in your CSS, you define a corresponding set of classes prefixed with scale
that are used to trigger the transition or animation based on the type of event you want to animate for that directive. More info to come on this…
Supported Events
Certain events are supported for each of the directives you can animate. They vary per directive and it’s important to know which apply for a given directive when you’re defining your CSS classes to perform the animation.
Here’s the list:
Directive | Events |
ngIf | enter/leave |
ngInclude | enter/leave |
ngRepeat | enter/leave/move |
ngShow/ngHide | show/hide |
ngSwitch | enter/leave |
ngView | enter/leave |
The AngularJS docs describe exactly when those events occur for each of the directives supporting animations. So for instance the ngIf
docs provide this description for the supported enter and leave events:
enter – happens just after the ngIf
contents change and a new DOM element is created and injected into the ngIf
container
leave – happens just before the ngIf
contents are removed from the DOM
You can use this information to determine when your transitions and animations will actually be triggered.
CSS3 Transitions versus CSS3 Animations
ngAnimate
can be used for both CSS3 animations and transitions, as well as JavaScript animations but that is beyond the scope of this article. I wanted to take a moment to briefly discuss the difference between CSS3 transitions and animations.
CSS3 Transitions
apply an effect to a style property for a certain duration. You can do things like fade, scale, move, slide, rotate, 3D effects etc.
CSS3 Animations are more complex than transitions and use keyframes to define different points to do things within the animation. These can be looped and auto-started. In addition, they don’t have to depend on a DOM change to trigger them.
The difference in using CSS3 transitions versus CSS3 animations with ngAnimate
is all in the way the CSS classes are defined. A great example can be found in the AngularJS 1.1.5 docs for ngAnimate. I’m including it here too for easy reference:
CSS3 Transition Sample
.animate-enter {
-webkit-transition: 1s linear all; /* Safari/Chrome */
-moz-transition: 1s linear all; /* Firefox */
-o-transition: 1s linear all; /* Opera */
transition: 1s linear all; /* IE10+ and Future Browsers */
/* The animation preparation code */
opacity: 0;
}
/*
Keep in mind that you want to combine both CSS
classes together to avoid any CSS-specificity
conflicts
*/
.animate-enter.animate-enter-active {
/* The animation code itself */
opacity: 1;
}
CSS3 Animation Sample
.animate-enter {
-webkit-animation: enter_sequence 1s linear; /* Safari/Chrome */
-moz-animation: enter_sequence 1s linear; /* Firefox */
-o-animation: enter_sequence 1s linear; /* Opera */
animation: enter_sequence 1s linear; /* IE10+ and Future Browsers */
}
@-webkit-keyframes enter_sequence {
from { opacity:0; }
to { opacity:1; }
}
@-moz-keyframes enter_sequence {
from { opacity:0; }
to { opacity:1; }
}
@-o-keyframes enter_sequence {
from { opacity:0; }
to { opacity:1; }
}
@keyframes enter_sequence {
from { opacity:0; }
to { opacity:1; }
}
When using ngAnimate
for either of the above, the same syntax would be used to apply the directive, such as:
<div ng-view ng-animate="{enter: 'animate-enter'}"></div>
I highly recommend reading through the documentation for further details on how this is all handled.
Naming Conventions
When writing your CSS classes to apply your transitions or animations, you define two CSS classes for each supported event (enter, leave, show, hide, etc). One is used as a baseline class and the other is defined as an active class where the animation actually happens. There is a certain notation you need to use to define these classes. The base class is named as name-event
(ie: slide-enter
), whereas the active class is named the same with the keyword “active” appended to it (ie: slide-enter-active
).
For example, using a fade type of effect on an ngShow
or ngHide
would require these 4 classes to be defined (since “show” and “hide” are the supported events for that directive):
.fade-show {
-webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
white-space:nowrap;
position:relative;
overflow: hidden;
text-overflow: clip;
}
.fade-show-active {
opacity:1;
}
.fade-hide {
-webkit-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-moz-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-ms-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
-o-transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
transition: 400ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all;
white-space:nowrap;
position:relative;
overflow: hidden;
text-overflow: clip;
}
.fade-hide-active {
opacity:0;
}
Applying the CSS via ng-animate
Once you define all of your animations and transitions, you apply them via the ngAnimate
directive. There are two ways you can describe which CSS classes to use, explicitly or shorthand. Both are shown below:
Explicit:
Here you explicitly name the class to apply for each supported event (enter, leave etc).
<div ng-view ng-animate="{enter: 'rotate-enter', leave: 'rotate-leave'}"></div>
Shorthand:
The shorthand way of applying them is through a name only, and then that name with the event appended is implied as the class name. So for instance, in the following, the resulting class names implied will be name-event
or rotate-enter
and rotate-leave
, just as above:
<div ng-view ng-animate="'rotate'">
Check out the demo source or links provided for specific examples to understand the syntax further.
Customizing Animation
You can customize your AngularJS animation in different ways using the $animator
service. You could create your own custom animation events or use the built-in ones like “enter” and “leave” with ng-animate
in your own custom directive by accessing them off the $animator
service.
You can also define custom events using the $animator.animate(myEvent,element)
function, where myEvent
is your own String and element
is what to apply the transition or animation to.
I included an example of defining a custom directive and custom event in the demo application if you are interested in seeing how it works.
Related Resources
- Demo Application
- AngularJS 1.1.5 Docs for
ngAnimate
- nganimate.org – Great samples here
- Really nice detailed article about the new animations support in AngularJS
- AngularJS and Animation Slides with demos by Gias Kay Lee
- Animate your AngularJS apps with CSS3 and jQuery article
- Misko Hevery video talking about the new animation features
- Swipe Demo and code using
ngAnimate
- Video showing swipe demo and code
- All About CSS3 Transitions
- All About CSS3 Animations