AngularJS Animations

By Matias Niemelä

bitly.com/yom-slides

@yearofmoo

http://www.yearofmoo.com

Six major AngularJS articles.

Great resource to learn about AngularJS and ngAnimate.

Animation & Webapps

Animation code tends almost always gets mixed in together with application code and website logic.

Not so simple way of disabling and changing animation properties during runtime

Difficult to test & reuse animations

What about AngularJS?

You'll fall into these same challenges when doing it yourself

No way to hook into core operations inside your application.

No way to isolate your code properly.

No fair!

ngAnimate solves this!

Non-Animated Demo

Here is an existing application that uses AngularJS, but without ngAnimate. http://bitly.com/yom-w1

ngAnimate

The magical directive that signals other directives to perform animations.

Supported in version 1.1.5 of AngularJS.

Full support for CSS3 Animations & Transitions

Also supports JavaScript animations

Lets get started!

How to define animations

Animations can be defined in CSS or in JavaScript (inside of your module code).

CSS-enabled animations use two classes to signal the setup and the active animation states.

JavaScript-enabled animations use a setup and a start callback.

CSS3 Transitions

Two CSS classes required.


/* preparation CSS (from) */
.some-animation {
  transition:0.5s linear all;
  background:red;
}
/* animation CSS (to) */
.some-animation-active {
  background:blue;
}

CSS3 Animations

Only CSS class required.


/* preparation CSS */
.some-animation {
  animation:0.5s my_animation;
}
/* animation CSS (from & to) */
@keyframes my_animation {
  from { background:blue; }
  to { background:red; }
}

JavaScript Animations

Define it like a service


ngModule.animation('some-animation', function(inject) {
  return {
    setup : function(element) { //preparation (from)
      element.css('background','blue');
    },
    start : function(element, done) { //animation (to)
      element.animate({
        'background':'#F00'
      }, done);
    },
    cancel : function(element, done) {
      cancelAnimation(element);
      done();
    }
  };
});

How to use animations


<div ng-directive ng-animate="..."><div>
Type Example
String ' "some-animation' '
Object ' {event:"some-animation-enter"} '
Function computeAnimation()

Shortform Syntax

When a string then it will expand to value-event

Event ng-animate="'something'"
enter something-enter
leave something-leave
move something-move
show something-show
hide something-hide
custom something-EVENT

Animation-aware Directives

The following directives support ngAnimate

Directive Events
ngRepeat enter, move, leave
ngSwitch, ngView, ngInclude enter, leave
ngIf enter, leave
ngShow, ngHide show, hide

ngShow / ngHide Example

Here is an example using ngShow to fading animation


<div ng-show="showMe"
     ng-animate="{show:'show',hide:'hide'}">
</div>

.show, .hide {
  transition:0.5s linear all;
}
.show { opacity:0; }
.show-active { opacity:1; }
.hide { opacity:1; }
.hide-active { opacity:0; }

ngView Example

Here is an example using ngView to perform a sliding animation


<div ng-view ng-animate="'view'"></div>

.view-enter, .view-leave {
  transition:0.5s linear all;
  position:relative;
}
.view-enter { opacity:0; left:20px; }
.view-enter-active { opacity:1; left:0; }
.view-leave { opacity:1; left:0; }
.view-leave-active { opacity:0; left:-20px; }

ngRepeat Example

Here is an example using ngRepeat to perform an expanding animation


<div ng-repeat="item in items" ng-animate="'scale'"></div>

ngModule.animate('scale-enter', function() {
  return {
    setup : function(element) {
      var to = {
        'line-height' : element.css('line-height'),
        'height' : element.css('height')
      };
      element.css({
        'height':0,
        'line-height':0,
      });
      return to;
    },
    start : function(element, done, to) {
      element.animate(to, done);
    }
  };
});
ngModule.animate('scale-leave', function() {
  return {
    start : function(element, done) {
      element.animate({
        'line-height':0,
        'height':0
      },done);
    }
  };
});

animate.css

Quick and dirty method of putting animations into your AngularJS code.


<link rel="stylesheet" href="animate.css" />
<div ng-show="showMe" ng-animate="{
  enter:'animated fadeIn',
  leave:'animated fadeOut'
}"></div>

bitly.com/yom-w3 | animate.css homepage

Animated Demo

Here is an AngularJS application built using ngAnimate: http://bitly.com/yom-w2

Using $animator in your own directives

$animator is a core service for running animations.


ngModule.directive('my-directive', function($animator) {
  return function($scope, element, attrs) {
    var animator = $animator($scope, attrs); 
    //...
  };
});

Now the created animator object can be used trigger animations

How to run animations

the animator object can trigger common events such as:

Event ng-animate="'something'"
enter animator.enter(element, parent, after)
leave animator.leave(element, parent)
move animator.move(element, parent, after)
show animator.show(element)
hide animator.hide(element)
custom animator.animate(event, element)

$animator example

This will show and hide the element when clicked


ngModule.directive('my-directive', function($animator) {
  return function($scope, element, attrs) {
    var animator = $animator($scope, attrs); 
    var toggle = element.children()[0];
    var container = element.children()[1];
    toggle.bind('click', function() {
      container.css('display') == 'none' ?
        animator.show(container) :
        animator.hide(container);
    });
  };
});

<div my-directive
     ng-animate="{show:'show',hide:'hide'}">
  <button>toggle</button>
  <div>...</div>
</div>

Disabling Animations

Remove the scope member or return null to ngAnimate.

Run $animator.enabled(false) in your controller.

Use ngAnimate & $animator

Try to always use ngAnimate with your code

Automatically cancels and starts animations without collision

Easy to disable and enable animations

Common, organized method of creating animation code

Soon to come...

animator.addClass, animator.removeClass support

ngClass animation hooks

"Spaced" animation support.

Thank you!

Thank you for making this possible

Please use and experiment with animations so that we can make this tool better

@yearofmoo

Feel free to contact me via matias@yearofmoo.com