Animations with AngularJS

HTML animations can either be done using css, or by using some JavaScript library such as jQuery. Given that CSS3 has inherited support for animation, using CSS is a preferred way of implementing animation in our apps. With the use of CSS3 transitions and animation constructs, we can achieve some impressive animation effects.

In AngularJS, a set of directives has been built in such a way that adding animation to these directives is easy. Directives such as ng-repeat, ng-include, ng-view, ng-if, ng-switch, ng-class, and ng-show/ng-hide have build-in support for animation.

What does it mean when we say the directive supports animation?

Well, from the CSS perspective, it implies that the previous directive dynamically adds and removes classes to the HTML element on which they are defined at specific times during directive execution. How this helps in CSS animation will be clear when we discuss CSS animation in our next section.

From a script-based animation perspective, we can use the module animate function to animate the previous directives using libraries such as jQuery.

Let's look at both CSS and script-based animation and then understand what Angular has to offer.

AngularJS CSS animation

CSS animation is all about animating from one style configuration to another using some animation effect. The animation effect can be achieved by using any of the following two mechanisms:

  • Transition: This is where we define a start CSS state, the end CSS state, and the transition effect (animation) to use. The effect is defined using the style property transition. The following CSS style is an example:
    .my-class {
      -webkit-transition:0.5s linear all;
      transition:0.5s linear all;
      background:black;
    }
    .my-class:hover {
       background:blue;
    }

    When the preceding styles are applied to an HTML element, it changes the background color of the element from black to blue on hover with a transition effect defined by the transition property.

    Such animations are not just limited to pseudo selector such as hover. Let's add this style:

    .my-class.animate {
       background:blue;
    }

    When this style is added, a similar effect as demonstrated previously can be achieved by dynamically adding the animate class to an HTML element which already has my-class applied.

  • Animation: This is where we define the start CSS state, the keyframe configuration that defines the time duration of the animation, and other details about how the animation should progress. For example, these CSS styles have the same effect as a CSS transition:
    .my-class {
      background:black;
    }
    .my-class:hover {
       background:blue;
       animation: color 1s linear;
      -webkit-animation: color 1s linear;
    }
    @keyframes color {
      from {
        background: black;
      }
      to {
        background: blue;
      }
    }

The basic difference between transition and animation is that we do not need two CSS states defined in the case of animation. In the first example, transition happens when the CSS on the element changes from .my-class to .my-class:hover, whereas in the second example, animation starts when the CSS state is .my-class:hover, so there is no end CSS concept with animation.

The animation property on .my-class:hover allows us to configure the timing and duration of the animation but not the actual appearance. The appearance is controlled by @keyframes. In the preceding code, color is the name of the animation and @keyframes color defines the appearance.

Note

We will not be covering CSS-based animation in detail here. There are many good articles and blog posts that cover these topics in depth. To start with, we can refer to MDN documentation for transition (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions) and for animation (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations).

To facilitate animations, AngularJS directives add some specific classes to the HTML element.

Directives that add, remove, and move DOM elements, including ng-repeat, ng-include, ng-view, ng-if, and ng-switch, add one of the three sets of classes during different times:

  • ng-enter and ng-enter-active: These are added when directive adds HTML elements to the DOM.
  • ng-leave and ng-leave-active: These are added before an HTML element is removed from the DOM.
  • ng-move and ng-move-active: These are added when an element is moved in the DOM. This is applicable to the ng-repeat directive only.

The ng-<event> directive signifies the start and ng-<event>-active signifies the end of CSS states. We can use this ng-<event> g-<event>-active pair for transition-based animation and ng-<event> only for keyframe-based animation.

Directives such as ng-class, ng-show, and ng-hide work a little differently. The starting and ending class names are a bit different. The following table details the different class names that get applied for these directives:

Event

Start CSS

End CSS

Directive

Hiding an element

.ng-hide-add

ng-hide-add-active

ng-show, ng-hide

Showing an element

.ng-hide-remove

ng-hide-add-remove-active

ng-show, ng-hide

Adding a class to an element

<class>-add

<class>-add-active

ng-class and class="{{expression}}"

Removing a class from an element

<class>-remove

<class>-remove-active

ng-class and class="{{expression}}"

Make note that even interpolation-based class changes (class="{{expression}}") are included for animation support.

Another important aspect of animation that we should be aware of is that the start and end classes added are not permanent. These classes are added for the duration of the animation and removed thereafter. AngularJS respects the transition duration and removes the classes only after the animation is over.

Let's now look at JavaScript-based animation before we begin implementing animation for our app.

AngularJS JavaScript animation

The idea here too remains the same but instead of using CSS-based animation, we use JavaScript to do animation. This is the CSS:

.my-class {
  background:black;
}
.my-class:hover {
   background:blue;
}

We can do something that resembles JavaScript-based animation when we use jQuery (it requires a plugin such as http://www.bitstorm.org/jquery/color-animation/):

$(".my-class").hover( function() {$(this).animate({backgroundColor:blue},1000,"linear");

To integrate script-based animation with Angular, the framework provides the Module API method animation:

animation(name, animationFactory);

The first argument is the name of the animation and the second parameter, animationFactory, is an object with the callback function that gets called when Angular adds or removes classes (such as ng-enter and ng-leave) as explained in the CSS section earlier in the chapter.

It works something like this. Given here is an AngularJS construct that supports animation such as ng-repeat:

<div ng-repeat="item in items" class='repeat-animation'>

We can enable animation by using the Module API animation method:

myApp.animation('.repeat-animation', function() {
  return {
    enter : function(element, done) { //ng-enter or element added
    //Called when ng-enter is applied
    jQuery(element).css({
            opacity:0
      });
      jQuery(element).animate({
  opacity:1
      }, done);
    }
  }
});

Here, we animate when ng-enter is applied from the opacity value from 0 to 1. This happens when an element is added to the ng-repeat directive. Also, Angular uses the class name of the HTML element to match and run the animation. In the preceding example, any HTML element with the .repeat-animation class will trigger the previous animation when it is created.

For the enter function, the element parameter contains the element on which the directive has been applied and done is a function that should be called to tell Angular that the animation is complete. Always remember to call this done function. The preceding jQuery animate function takes done as a parameter and calls it when the animation is complete.

Note

Other than the enter function, we can add callbacks for leave, move, beforeAddClass, addClass, beforeRemoveClass, and removeClass. Check the AngularJS documentation on the ngAnimate module at https://code.angularjs.org/1.2.15/docs/api/ngAnimate for more details. Also, a more comprehensive treatment for AngularJS animation is available on the blog post at http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html.

Armed with an understanding of animation now, let's get back to our app and add some animation to it.

Adding animation to 7 Minute Workout

Time to add some animation support for our app! The AngularJS ngAnimate module contains the support for Angular animation. Since it is not a core module, we need to inject this module and include its script.

Add this reference to the angular animate script in index.html:

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular-animate.js"></script>

Add module dependency for the ngAnimate module in app.js:

angular.module('app', ['ngRoute', 'ngSanitize', '7minWorkout', 'mediaPlayer', 'ui.bootstrap', 'ngAnimate']).

We are all set to go.

The first animation we are going to enable is the ng-view transition, sliding in from the right. Adding this animation is all about adding the appropriate CSS in our app.css file. Open it and add:

div[ng-view] {
    position: absolute;
    width: 100%;
    height: 100%;
}
div[ng-view].ng-enter,
div[ng-view].ng-leave {
    -webkit-transition: all 1s ease;
    -moz-transition: all 1s ease;
    -o-transition: all 1s ease;
    transition: all 1s ease;
}
div[ng-view].ng-enter {
    left: 100%;     /*initial css for view transition in*/
}
div[ng-view].ng-leave {
    left: 0;        /*initial css for view transition out*/
}
div[ng-view].ng-enter-active {
    left: 0;        /*final css for view transition in*/
}
div[ng-view].ng-leave-active {
    left: -100%;    /*final css for view transition out*/
}

This basically is transition-based animation. We first define the common styles and then specific styles for the initial and final CSS states. It is important to realize that the div[ng-view].ng-enter class is applied for the new view being loaded and div[ng-view].ng-leave for the view being destroyed.

For the loading view, we transition from 100% to 0% for the left parameter.

For the view that is being removed, we start from left 0% and transition to left -100%

Try out the new changes by loading the start page and navigate to the workout or finish page. We get a nice right-to-left animation effect!

Let's add a keyframe-based animation for videos as it is using ng-repeat, which supports animation. This time we are going to use an excellent third-party CSS library animate.css (http://daneden.github.io/animate.css/) that defines some common CSS keyframe animations. Execute the following steps:

  1. Add the reference to the library in index.html after the bootstrap.min.css declaration:
     <link href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.0/animate.min.css" rel="stylesheet" />
  2. Update the video-panel.html file and add a custom class video-image to the ng-repeat element:
    <div ng-repeat="video in currentExercise.details.related.videos" ng-click="playVideo(video)" class="row video-image">
  3. Update the app.css file to animate the ng-repeat directive:
    .video-image.ng-enter,
    .video-image.ng-move {
        -webkit-animation: bounceIn 1s;
        -moz-animation: bounceIn 1s;
        -ms-animation: bounceIn 1s;
        animation: bounceIn 1s;
    }
    .video-image.ng-leave {
        -webkit-animation: bounceOut 1s;
        -moz-animation: bounceOut 1s;
        -ms-animation: bounceOut 1s;
        animation: bounceOut 1s;
    }

The setup here is far simpler as compared to transition-based animation. Most of the code is around vendor-specific prefixes.

We define animation effect bounceIn for the ng-enter and ng-move states and bounceOut for the ng-leave state. Much cleaner and simpler!

To verify the implementation, open the workout and wait for the first exercise to complete to see the bounce-out effect and the next exercise to load for the bounce-in effect.

Note

The app implementation so far is available in companion code chapter3checkpoint5.

GitHub Branch: checkpoint3.5 (folder – trainer)

While using animation, we should not go overboard and add too much of it as it makes the app look amateurish. We have added enough animation to our app and now it's time to move to our next topic.

One area that we still have not explored is Angular services. We have used some Angular services, but we have little understanding of how services work and what it takes to create a service. The next section is dedicated to this very topic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.17.40