Angular Animations

What Does ngAnimate Do?

The ngAnimate module adds and removes classes.

The ngAnimate module does not animate your HTML elements. However, when ngAnimate notices certain events, such as hiding or showing an HTML element, the element receives some pre-defined classes that can be used to create animations.

The directives in AngularJS that add/remove classes are:

  • ng-show
  • ng-hide
  • ng-class
  • ng-view
  • ng-include
  • ng-repeat
  • ng-if
  • ng-switch

The ng-show and ng-hide directives add or remove the ng-hide class value.

Other directives add an ng-enter class value when entering the DOM and an ng-leave attribute when removed from the DOM.

The ng-repeat directive also adds the ng-move class value when the HTML element changes position.

In addition, the HTML element will have a set of class values during animation, which will be removed when the animation ends.

For example, the ng-hide directive would concatenate these class values:

  • ng-animate
  • ng-hide-animate
  • ng-hide-add(if the element will be hidden)
  • ng-hide-remove (if the element will be shown)
  • ng-hide-add-active(if the element will be hidden)
  • ng-hide-remove-active (if the element will be shown

Animations Using CSS

We can use CSS transitions or CSS animations to animate HTML elements. This tutorial will show you both.

CSS Transitions

CSS transitions allow you to change CSS property values smoothly, from one value to another, over a given duration:

Example:

When the DIV element gets the .ng-hide class, the transition will take 0.5 seconds, and the height will smoothly change from 100px to 0:

<style>  

div {  

  transition: all linear 0.5s;  

  background-color: lightblue;  

  height: 100px;  

}  

  

.ng-hide {  

  height: 0;  

}  

</style>  

    CSS Animations

    CSS animations allow you to easily change CSS property values from one value to another over a given period of time:

    Example:

    When the DIV element receives the .ng-hide class, the myChange animation will run, which will simply change the height from 100px to 0:

    <style>  
    
    @keyframes myChange {  
    
      from {  
    
        height: 100px;  
    
      } to {  
    
        height: 0;  
    
      }  
    
    }  
    
      
    
    div {  
    
      height: 100px;  
    
      background-color: lightblue;  
    
    }  
    
      
    
    div.ng-hide {  
    
      animation: 0.5s myChange;  
    
    }  
    
    </style> 

      The main Angular modules for animations are @angular/animations and @angular/platform-browser. When you create a new project using the CLI, these dependencies are automatically added to your project.

      To get started with adding Angular animations to your project, import the animation-specific modules along with standard Angular functionality.

      Step 1: Enabling the animations module

      Import BrowserAnimationsModule, which introduces the animation capabilities into your Angular root application module.

      src/app/app.module.ts  
      
      content_copyimport { NgModule } from '@angular/core';  
      
      import { BrowserModule } from '@angular/platform-browser';  
      
      import { BrowserAnimationsModule } from '@angular/platform-browser/animations';  
      
        
      
      @NgModule({  
      
        imports: [  
      
          BrowserModule,  
      
          BrowserAnimationsModule  
      
        ],  
      
        declarations: [ ],  
      
        bootstrap: [ ]  
      
      })  
      
      export class AppModule { } 

        Note: When you use the CLI to create your app, the root application module app.module.ts is placed in the src/app folder.

        Step 2: Importing animation functions into component files

        If you plan to use specific animation functions in component files, import those functions from @angular/animations.

        src/app/app.component.ts

        content_copyimport { Component, HostBinding } from '@angular/core';  
        
        import {  
        
          trigger,  
        
          state,  
        
          style,  
        
          animate,  
        
          transition,  
        
          // ...  
        
        } from '@angular/animations'; 

          Step 3: Adding the animation metadata property

          In the component file, add a metadata property named animation: @Component() within the decorator. You place the trigger that defines an animation within the AnimationMetadata property.

          src/app/app.component.ts  
          
          content_copy@Component({  
          
            selector: 'app-root',  
          
            templateUrl: 'app.component.html',  
          
            styleUrls: ['app.component.css'],  
          
            animations: [  
          
              // animation triggers go here  
          
            ]  
          
          })  

            Animating a transition

            Let’s animate a transition that changes an HTML element from one state to another. For example, you can specify whether a button displays open or closed based on the user’s last action. When the button is in the open state, it is visible and is yellow. When it is in the closed state, it is translucent and blue.

            In HTML, these attributes are set using common CSS styles such as color and opacity. In Angular, use the style() function to specify a set of CSS styles for use with animations. Collect a set of styles in the animation state, and give the state a name, such as open or closed.

            Let’s create a new open-close component to animate with simple transitions.

            Run the following command in the terminal to generate the component:

            ng g component open-close  

            It will create the component at src/app/open-close.component.ts.

            Animation state and styles

            Use Angular’s position() function to define different states to be called at the end of each transition. This function takes two arguments: a unique name such as open or closed and a style() function.

            Use the style() function to define a set of styles to associate with a given state name. It would be best to use CamelCase for style attributes that contain dashes, such as background color, or wrap them in quotes, such as ‘background color’.

            Let’s see how Angular’s state() function works with the style?¬ (?) function to set CSS style attributes. In this code snippet, multiple style attributes are set at the same time for the state. In the open state, the button has a height of 200 pixels, an opacity of 1, and a yellow background.

            src/app/open-close.component.ts

            content_copy// ...  
            
            state('open', style({  
            
              height: '200px',  
            
              opacity: 1,  
            
              backgroundColor: 'yellow'  
            
            })), 

              In the following closed state, the button has a height of 100 pixels, an opacity of 0.8, and a background color of blue.

              src/app/open-close.component.ts  
              
              content_copystate('closed', style({  
              
                height: '100px',  
              
                opacity: 0.8,  
              
                backgroundColor: 'blue'  
              
              })),     

                Transitions and timing

                In Angular, you can set multiple styles without any animation. However, without further refinement, the button turns on immediately with no fade, no shrinkage, or any other visible indicator that a change is taking place.

                In order to make the change less abrupt, you need to define an animation transition to specify the changes that occur between one state and another at some point in time. The transition() function accepts two arguments: the first argument accepts an expression that defines the direction between two transition states, and the second argument accepts one or a series of animate() steps.

                Use the animate() function to define length, delay, and smoothness, and specify the style function to define styles when transitions occur. Use the animate() function to define keyframes() for multi-stage animations. These definitions are placed in the second argument of the animate() function.

                Animation metadata: duration, delay, and easing

                The animate () function (second argument of the transition function) accepts the timings and styles of input parameters.

                The timings parameter takes either a number or a string defined in three parts.

                animate (duration) or animate ('duration delay easing')  

                The first part, the period, is essential. Duration can be expressed as a number in milliseconds without quotes or in seconds with quotes and as a time specifier. For example, the duration of a tenth of a second can be expressed as follows:

                • As a plain number, in milliseconds: 100
                • In a string, as milliseconds: ‘100ms.’
                • In a string, as in seconds: ‘0.1s.’

                The second argument, delay, has the same syntax as duration. for example:

                • Wait 100ms and then run for 200ms: ‘0.2s 100ms’.

                The third argument, easing, controls how the animation accelerates and slows down during its runtime.

                For example, easing causes the animation to start slowly and pick up speed as it progresses.

                • Wait 100ms, Run for 200ms. Use a deceleration curve to start fast and gradually move to a resting point: ‘0.2s out of 100ms smoothly
                • Run up to 200ms without any delay. Use a standard curve to start slow, accelerate in the middle, and then gradually decrease towards the end: ‘0.2s eas-in-out
                • Quick start, run up to 200ms. Use the acceleration curve to start slow and end at full velocity: ‘0.2s Easy-in’.

                Note: See the Material Design website topic on Easing Curves for general information on natural easing curves.

                This example provides a state transition from open to closed with a 1-second transition between states.

                src/app/open-close.component.ts

                content_copytransition('open => closed', [  
                
                  animate('1s')  
                
                ]), 

                  In the previous code snippet, the => operator indicates unidirectional transition, and <=> is bidirectional. Within the transition, animate() specifies how long the transition takes. In this case, the state change from open to closed takes 1 second, which is expressed here as 1s.

                  This example adds a state transition from closed state to open state with a 0.5-second transition animation arc.

                  src/app/open-close.component.ts

                  content_copytransition('closed => open', [  
                  
                    animate('0.5s')  
                  
                  ]), 

                    Note: Some additional notes on using styles within the state and transition functions.

                    • Use state () to define styles applied at the end of each transition; they persist after the animation completes.
                    • Use transition () to define intermediate styles, which create the illusion of motion during the animation.
                    • When animations are disabled, transition ()styles can be skipped, but the state () styles can’t.

                    Include multiple state pairs within the same transition () argument:

                    transition( ‘on => off, off => void’ ).

                    Triggering the animation

                    Animation needs a trigger so that it knows when to start. The trigger() function collects states and transitions and gives the animation a name so that you can attach it to the triggering element in the HTML template.

                    The trigger() function describes the name of the property to watch for changes. When a change occurs, the trigger initiates the actions included in its definition. These actions can be transitions or other actions, as we will see later.

                    We’ll name the trigger open-close in this example and attach it to the button element. The trigger describes the open and closed states and the timing of the two transitions.

                    Note: Within each trigger() function call, an element can only be in one position at any time. However, multiple triggers can be activated simultaneously.

                    Defining animations and attaching them to the HTML template

                    Animations are defined in the component’s metadata that controls the HTML element to be animated. Put the code that defines your animations under the animation:property @Component() within the decorator.

                    src/app/open-close.component.ts

                    content_copy@Component({  
                    
                      selector: 'app-open-close',  
                    
                      animations: [  
                    
                        trigger('openClose', [  
                    
                          // ...  
                    
                          state('open', style({  
                    
                            height: '200px',  
                    
                            opacity: 1,  
                    
                            backgroundColor: 'yellow'  
                    
                          })),  
                    
                          state('closed', style({  
                    
                            height: '100px',  
                    
                            opacity: 0.8,  
                    
                            backgroundColor: 'blue'  
                    
                          })),  
                    
                          transition('open => closed', [  
                    
                            animate('1s')  
                    
                          ]),  
                    
                          transition('closed => open', [  
                    
                            animate('0.5s')  
                    
                          ]),  
                    
                        ]),  
                    
                      ],  
                    
                      templateUrl: 'open-close.component.html',  
                    
                      styleUrls: ['open-close.component.css']  
                    
                    })  
                    
                    export class OpenCloseComponent {  
                    
                      isOpen = true;  
                    
                      
                    
                      toggle() {  
                    
                        this.isOpen = !this.isOpen;  
                    
                      }  
                    
                      
                    
                    } 

                      When you have defined an animation trigger for a component, please attach it to an element in that component’s template by wrapping the trigger name in parentheses and the @ sign next to it. Then, you can bind the trigger to a template expression using the standard Angular property binding syntax, as shown below, where triggerName is the name of the trigger, and the expression evaluates to a defined animation state.

                      content_copy<div [@triggerName]="expression">...</div>;  

                      The animation is executed or triggered when the expression value changes to a new state.

                      The following code snippet binds the trigger to the value of the isOpen property.

                      src/app/open-close.component.html

                      content_copy<nav>  
                      
                        <button type="button" (click)="toggle()">Toggle Open/Close</button>  
                      
                      </nav>  
                      
                      <div [@openClose]="isOpen ? 'open' : 'closed'" class="open-close-container">  
                      
                        <p>The box is now {{ isOpen ? 'Open' : 'Closed' }}!</p>  
                      
                      </div> 

                        In this example, when the isOpen expression evaluates to a defined state of open or closed, it notifies the trigger of the state change to open-closed. Then it is up to the open-close code to handle the state change and initiate the state change animation.

                        You can conditional animations for elements entering or leaving a page (inserted or removed from the DOM). For example, use *ngIf with animation triggers in HTML templates.

                        Note: In the component file, set the trigger that defines the animation as the value of the animation:@Component() property in the decorator.

                        In an HTML template file, use a trigger name to attach animations defined to the HTML element to be animated.

                        Code review

                        Here is the code files discussed in the transition example.

                        • src/app/open-close.component.ts
                        • src/app/open-close.component.html
                        • src/app/open-close.component.css
                        content_copy@Component({  
                        
                          selector: 'app-open-close',  
                        
                          animations: [  
                        
                            trigger('openClose', [  
                        
                              // ...  
                        
                              state('open', style({  
                        
                                height: '200px',  
                        
                                opacity: 1,  
                        
                                backgroundColor: 'yellow'  
                        
                              })),  
                        
                              state('closed', style({  
                        
                                height: '100px',  
                        
                                opacity: 0.8,  
                        
                                backgroundColor: 'blue'  
                        
                              })),  
                        
                              transition('open => closed', [  
                        
                                animate('1s')  
                        
                              ]),  
                        
                              transition('closed => open', [  
                        
                                animate('0.5s')  
                        
                              ]),  
                        
                            ]),  
                        
                          ],  
                        
                          templateUrl: 'open-close.component.html',  
                        
                          styleUrls: ['open-close.component.css']  
                        
                        })  
                        
                        export class OpenCloseComponent {  
                        
                          isOpen = true;  
                        
                          
                        
                          toggle() {  
                        
                            this.isOpen = !this.isOpen;  
                        
                          }  
                        
                        } 

                          You learned to add animation to the transition between two states, using animate() as well as style() and state() for timing.

                          Learn about more advanced features in Angular Animation under the Animations section, starting with advanced techniques in transitions and triggers.

                          Animation API Summary

                          The functional API provided by the @angular/animations module provides a domain-specific language (DSL) for creating and controlling animations in Angular applications. See the API reference for a complete list of the main functions and associated data structures and syntax details.

                          function namewhat does it do
                          trigger()Closes the animation and serves as a container for all other animation function calls. Use the first argument to declare a unique trigger name. The HTML template binds to the trigger name. Uses array syntax.
                          genre()Defines one or more CSS styles to use in animations. Controls the visual appearance of HTML elements during animation. Uses object syntax.
                          state()Creates a named set of CSS styles that should be applied upon successful transition to a given state. Within other animation functions the state can be referred to by name.
                          animate ()Specifies timing information for a transition. Optional values for delay and easing. Style() call.
                          infection()Defines the animation sequence between two named states. Uses array syntax.
                          keyframe()Allows for gradual change between styles within a specified time interval. Use within animate(). Can contain multiple style() calls within each keyframe. Uses array syntax.
                          group()Specifies a group of animation steps (internal animations) to run in parallel. Animation continues only after all internal animation steps have been completed. Used within sequence() or transition().
                          query()Finds one or more innerHTML elements within the current element.
                          sequence()Specifies a list of animation steps that run sequentially, one by one.
                          stagger()Stabilizes the start time for animations of multiple elements.
                          animation()Produces a reusable animation that can be called from elsewhere. Used in conjunction with useAnimation().
                          useAnimation()Enables reusable animation. Animation() is used with .
                          animateChild()Allows animations on child components to run within the same time frame as the parent.

                          Comments

                          Leave a Reply

                          Your email address will not be published. Required fields are marked *