Credit to devdocs.io

angularjs 1.4

angularjs

Improve this Doc ngAnimate

Installation

First include angular-animate.js in your HTML:

<script src="angular.js">
<script src="angular-animate.js">

You can download this file from the following places:

where X.Y.Z is the AngularJS version you are running.

Then load the module in your application by adding it as a dependent module:

angular.module('app', ['ngAnimate']);

With that you're ready to get started!

The ngAnimate module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via callback hooks. Animations are not enabled by default, however, by including ngAnimate the animation hooks are enabled for an Angular app.

Usage

Simply put, there are two ways to make use of animations when ngAnimate is used: by using CSS and JavaScript. The former works purely based using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via module.animation(). For both CSS and JS animations the sole requirement is to have a matching CSS class that exists both in the registered animation and within the HTML element that the animation will be triggered on.

Directive Support

The following directives are "animation aware":

Directive Supported Animations
ngRepeat enter, leave and move
ngView enter and leave
ngInclude enter and leave
ngSwitch enter and leave
ngIf enter and leave
ngClass add and remove (the CSS class(es) present)
ngShow & ngHide add and remove (the ng-hide class value)
form & ngModel add and remove (dirty, pristine, valid, invalid & all other validations)
ngMessages add and remove (ng-active & ng-inactive)
ngMessage enter and leave

(More information can be found by visiting each the documentation associated with each directive.)

CSS-based Animations

CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation.

The example below shows how an enter animation can be made possible on an element using ng-if:

<div ng-if="bool" class="fade">
   Fade me in out
</div>
<button ng-click="bool=true">Fade In!</button>
<button ng-click="bool=false">Fade Out!</button>

Notice the CSS class fade? We can now create the CSS transition code that references this class:

/* The starting CSS styles for the enter animation */
.fade.ng-enter {
  transition:0.5s linear all;
  opacity:0;
}

/* The finishing CSS styles for the enter animation */
.fade.ng-enter.ng-enter-active {
  opacity:1;
}

The key thing to remember here is that, depending on the animation event (which each of the directives above trigger depending on what's going on) two generated CSS classes will be applied to the element; in the example above we have .ng-enter and .ng-enter-active. For CSS transitions, the transition code must be defined within the starting CSS class (in this case .ng-enter). The destination class is what the transition will animate towards.

If for example we wanted to create animations for leave and move (ngRepeat triggers move) then we can do so using the same CSS naming conventions:

/* now the element will fade out before it is removed from the DOM */
.fade.ng-leave {
  transition:0.5s linear all;
  opacity:1;
}
.fade.ng-leave.ng-leave-active {
  opacity:0;
}

We can also make use of CSS Keyframes by referencing the keyframe animation within the starting CSS class:

/* there is no need to define anything inside of the destination
CSS class since the keyframe will take charge of the animation */
.fade.ng-leave {
  animation: my_fade_animation 0.5s linear;
  -webkit-animation: my_fade_animation 0.5s linear;
}

@keyframes my_fade_animation {
  from { opacity:1; }
  to { opacity:0; }
}

@-webkit-keyframes my_fade_animation {
  from { opacity:1; }
  to { opacity:0; }
}

Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element.

CSS Class-based Animations

Class-based animations (animations that are triggered via ngClass, ngShow, ngHide and some other directives) have a slightly different naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added and removed.

For example if we wanted to do a CSS animation for ngHide then we place an animation on the .ng-hide CSS class:

<div ng-show="bool" class="fade">
  Show and hide me
</div>
<button ng-click="bool=true">Toggle</button>

<style>
.fade.ng-hide {
  transition:0.5s linear all;
  opacity:0;
}
</style>

All that is going on here with ngShow/ngHide behind the scenes is the .ng-hide class is added/removed (when the hidden state is valid). Since ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest.

In addition the addition and removal of the CSS class, ngAnimate also provides two helper methods that we can use to further decorate the animation with CSS styles.

<div ng-class="{on:onOff}" class="highlight">
  Highlight this box
</div>
<button ng-click="onOff=!onOff">Toggle</button>

<style>
.highlight {
  transition:0.5s linear all;
}
.highlight.on-add {
  background:white;
}
.highlight.on {
  background:yellow;
}
.highlight.on-remove {
  background:black;
}
</style>

We can also make use of CSS keyframes by placing them within the CSS classes.

CSS Staggering Animations

A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be performed by creating a ng-EVENT-stagger CSS class and attaching that class to the base CSS class used for the animation. The style property expected within the stagger class can either be a transition-delay or an animation-delay property (or both if your animation contains both transitions and keyframe animations).

.my-animation.ng-enter {
  /* standard transition code */
  transition: 1s linear all;
  opacity:0;
}
.my-animation.ng-enter-stagger {
  /* this will have a 100ms delay between each successive leave animation */
  transition-delay: 0.1s;

  /* As of 1.4.4, this must always be set: it signals ngAnimate
    to not accidentally inherit a delay property from another CSS class */
  transition-duration: 0s;
}
.my-animation.ng-enter.ng-enter-active {
  /* standard transition styles */
  opacity:1;
}

Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation will also be reset if one or more animation frames have passed since the multiple calls to $animate were fired.

The following code will issue the ng-leave-stagger event on the element provided:

var kids = parent.children();

$animate.leave(kids[0]); //stagger index=0
$animate.leave(kids[1]); //stagger index=1
$animate.leave(kids[2]); //stagger index=2
$animate.leave(kids[3]); //stagger index=3
$animate.leave(kids[4]); //stagger index=4

window.requestAnimationFrame(function() {
  //stagger has reset itself
  $animate.leave(kids[5]); //stagger index=0
  $animate.leave(kids[6]); //stagger index=1

  $scope.$digest();
});

Stagger animations are currently only supported within CSS-defined animations.

The ng-animate CSS class

When ngAnimate is animating an element it will apply the ng-animate CSS class to the element for the duration of the animation. This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations).

Therefore, animations can be applied to an element using this temporary class directly via CSS.

.zipper.ng-animate {
  transition:0.5s linear all;
}
.zipper.ng-enter {
  opacity:0;
}
.zipper.ng-enter.ng-enter-active {
  opacity:1;
}
.zipper.ng-leave {
  opacity:1;
}
.zipper.ng-leave.ng-leave-active {
  opacity:0;
}

(Note that the ng-animate CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove the CSS class once an animation has completed.)

The ng-[event]-prepare class

This is a special class that can be used to prevent unwanted flickering / flash of content before the actual animation starts. The class is added as soon as an animation is initialized, but removed before the actual animation starts (after waiting for a $digest). It is also only added for structural animations (enter, move, and leave).

In practice, flickering can appear when nesting elements with structural animations such as ngIf into elements that have class-based animations such as ngClass.

<div ng-class="{red: myProp}">
  <div ng-class="{blue: myProp}">
    <div class="message" ng-if="myProp"></div>
  </div>
</div>

It is possible that during the enter animation, the .message div will be briefly visible before it starts animating. In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts:

.message.ng-enter-prepare {
  opacity: 0;
}

JavaScript-based Animations

ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the module.animation() module function we can register the ainmation.

Let's see an example of a enter/leave animation using ngRepeat:

<div ng-repeat="item in items" class="slide">
  {{ item }}
</div>

See the slide CSS class? Let's use that class to define an animation that we'll structure in our module code by using module.animation:

myModule.animation('.slide', [function() {
  return {
    // make note that other events (like addClass/removeClass)
    // have different function input parameters
    enter: function(element, doneFn) {
      jQuery(element).fadeIn(1000, doneFn);

      // remember to call doneFn so that angular
      // knows that the animation has concluded
    },

    move: function(element, doneFn) {
      jQuery(element).fadeIn(1000, doneFn);
    },

    leave: function(element, doneFn) {
      jQuery(element).fadeOut(1000, doneFn);
    }
  }
}]);

The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as greensock.js and velocity.js.

If our animation code class-based (meaning that something like ngClass, ngHide and ngShow triggers it) then we can still define our animations inside of the same registered animation, however, the function input arguments are a bit different:

<div ng-class="color" class="colorful">
  this box is moody
</div>
<button ng-click="color='red'">Change to red</button>
<button ng-click="color='blue'">Change to blue</button>
<button ng-click="color='green'"&