Animations

AngularJS provides animation hooks for common directives such as ngRepeat, ngSwitch, and ngView, as well as custom directives via the $animate service. These animation hooks are set in place to trigger animations during the life cycle of various directives and when triggered, will attempt to perform a CSS Transition, CSS Keyframe Animation or a JavaScript callback Animation (depending on whether an animation is placed on the given directive). Animations can be placed using vanilla CSS by following the naming conventions set in place by AngularJS or with JavaScript code, defined as a factory.

Animations are not available unless you include the ngAnimate module as a dependency of your application. Below is a quick example of animations being enabled for ngShow and ngHide:

index.html

<div ng-init=”checked = true”>

<label>

<input type=”checkbox” ng-model=”checked” />

Is visible

</label>

<div class=”content-area sample-show-hide” ng-show=”checked”>

Content…

</div>

</div>

animation.css

.content-area {

border: 1px solid black;

margin-top: 10px;

padding: 10px;

}

.sample-show-hide {

transition: all linear 0.5s;

}

.sample-show-hide.ng-hide {

opacity: 0;

}

How they work

Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to an HTML element within your application, you can apply animations to it. Let’s say for example that we have an HTML template with a repeater like so:

<div ng-repeat=”item in items” class=”repeated-item”>

{{ item.id }}

</div>

As you can see, the repeated-item class is present on the element that will be repeated and this class will be used as a reference within our application’s CSS and/or JavaScript animation code to tell AngularJS to perform an animation.

As ngRepeat does its thing, each time a new item is added into the list, ngRepeat will add an ng-enter class to the element that is being added. When removed it will apply an ng-leave class and when moved around it will apply an ng-move class.

Taking a look at the following CSS code, we can see some transition and keyframe animation code set up for each of those events that occur when ngRepeat triggers them:

/*

We are using CSS transitions for when the enter and move events

are triggered for the element that has the `repeated-item` class

*/

.repeated-item.ng-enter, .repeated-item.ng-move {

transition: all 0.5s linear;

opacity: 0;

}

/*

`.ng-enter-active` and `.ng-move-active` are where the transition destination

properties are set so that the animation knows what to animate

*/

.repeated-item.ng-enter.ng-enter-active,

.repeated-item.ng-move.ng-move-active {

opacity: 1;

}

/*

We are using CSS keyframe animations for when the `leave` event

is triggered for the element that has the `repeated-item` class

*/

.repeated-item.ng-leave {

animation: 0.5s my_animation;

}

@keyframes my_animation {

from { opacity: 1; }

to   { opacity: 0; }

}

The same approach to animation can be used using JavaScript code (for simplicity, we rely on jQuery to perform animations here):

myModule.animation(‘.repeated-item’, function() {

return {

enter: function(element, done) {

// Initialize the element’s opacity

element.css(‘opacity’, 0);

// Animate the element’s opacity

// (`element.animate()` is provided by jQuery)

element.animate({opacity: 1}, done);

// Optional `onDone`/`onCancel` callback function

// to handle any post-animation cleanup operations

return function(isCancelled) {

if (isCancelled) {

// Abort the animation if cancelled

// (`element.stop()` is provided by jQuery)

element.stop();

}

};

},

leave: function(element, done) {

// Initialize the element’s opacity

element.css(‘opacity’, 1);

// Animate the element’s opacity

// (`element.animate()` is provided by jQuery)

element.animate({opacity: 0}, done);

// Optional `onDone`/`onCancel` callback function

// to handle any post-animation cleanup operations

return function(isCancelled) {

if (isCancelled) {

// Abort the animation if cancelled

// (`element.stop()` is provided by jQuery)

element.stop();

}

};

},

// We can also capture the following animation events:

move: function(element, done) {},

addClass: function(element, className, done) {},

removeClass: function(element, className, done) {}

}

});

With these generated CSS class names present on the element at the time, AngularJS automatically figures out whether to perform a CSS and/or JavaScript animation. Note that you can’t have both CSS and JavaScript animations based on the same CSS class.

Class and ngClass animation hooks

AngularJS also pays attention to CSS class changes on elements by triggering the add and remove hooks. This means that if a CSS class is added to or removed from an element then an animation can be executed in between, before the CSS class addition or removal is finalized. (Keep in mind that AngularJS will only be able to capture class changes if an interpolated expression or the ng-class directive is used on the element.)

The example below shows how to perform animations during class changes:

index.html

<p>

<button ng-click=”myCssVar=’css-class'”>Set</button>

<button ng-click=”myCssVar=””>Clear</button>

<br>

<span ng-class=”myCssVar”>CSS-Animated Text</span>

</p>

style.css

.css-class-add, .css-class-remove {

transition: all 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940);

}

.css-class,

.css-class-add.css-class-add-active {

color: red;

font-size: 3em;

}

.css-class-remove.css-class-remove-active {

font-size: 1em;

color: black;

}

A handful of common AngularJS directives support and trigger animation hooks whenever any major event occurs during their life cycle. The table below explains in detail which animation events are triggered:

Directive Supported Animations
ngRepeat enter, leave, and move
ngIf enter and leave
ngSwitch enter and leave
ngInclude enter and leave
ngView enter and leave
ngMessage / ngMessageExp enter and leave
ngClass / {{class} } add and remove
ngClassEven add and remove
ngClassOdd add and remove
ngHide add and remove (the ng-hide class)
ngShow add and remove (the ng-hide class)
ngModel add and remove (various classes)
form / ngForm add and remove (various classes)
ngMessages add and remove (the ng-active/ng-inactive classes)

Using animations in directives

Animations within custom directives can also be established by injecting $animate directly into your directive and making calls to it when needed.

myModule.directive(‘my-directive’, [‘$animate’, function($animate) {

return function(scope, element) {

element.on(‘click’, function() {

if (element.hasClass(‘clicked’)) {

$animate.removeClass(element, ‘clicked’);

} else {

$animate.addClass(element, ‘clicked’);

}

});

};

}]);

Animations on app bootstrap / page load

By default, animations are disabled when the AngularJS app bootstraps. If you are using the ngApp directive, this happens in the DOMContentLoaded event, so immediately after the page has been loaded. Animations are disabled, so that UI and content are instantly visible. Otherwise, with many animations on the page, the loading process may become too visually overwhelming, and the performance may suffer.

Internally, ngAnimate waits until all template downloads that are started right after bootstrap have finished. Then, it waits for the currently running $digest and one more after that, to finish. This ensures that the whole app has been compiled fully before animations are attempted.

If you do want your animations to play when the app bootstraps, you can enable animations globally in your main module’s run function:

myModule.run(function($animate) {

$animate.enabled(true);

});

Get industry recognized certification – Contact us

Menu