Tech & Lifestyle Blog

How to enable/disable Animations in Angular

Jul 10, 2017

Angular 4.3.0-rc.0 finally brings forth a new binding property that allows for animations to be disabled during runtime. The binding to disable all animations can be controlled using @.disabled with a boolean-like value.

The code below shows an example of this in action:

@Component({
  selector: 'my-component',
  template: `
    <div [@.disabled]="disabled">
      <!-- the inner parts of the component -->
    </div>
  `
})
class MyComponent {
  // disabled = true or false
  disabled = true;
}

When true, all inner child animations within the element will be disabled. The inner animations themselves will still be validated and constructed, but they will not be run because of the container being disabled. Any callback code that listens on any inner animations will also execute as well (but only for zero seconds). Note that any animation triggers that exist on the same element as the disable/enable binding will not be disabled (only the children). If you wish to disable animations for that element then place the binding on an upper parent element.

Disabling animations application wide

Given that all components are usually situated inside of a top-level ApplicationComponent, this means that if animations are set to be disabled then the entire application's animations will be blocked (since everything sits inside of the application component).

By placing a @HostBinding on the application component we can disable all animations within.

@Component({
  selector: 'application-component',
  templateUrl: 'app.component.html'
})
class ApplicationComponent {
  @HostBinding('@.disabled')
  disabled = true;
}

What about querying for inner elements?

If animations are disabled for an inner part of the application, any parent animations (that sit inside an area where animations are not disabled) can query for children anywhere in the application and animate as they see fit.

@Component({
  selector: 'my-component',
  animations: [
    trigger('queryAnimation', [
      transition('* => go', [
        query('header, footer', [
          style({ opacity: 0 }),
          animate('1s', style({ opacity: 1 }))
        ])
      ])
    ])
  ],
  template: `
    <button (click)="start()">Start Animation!</button>
    <hr>
    <div [@.disabled]="disabled" [@queryAnimation]="exp">
      <header>...</header>
      <footer>...</footer>
    </div>
  `
})
class MyComponent {
  disabled = true;
  exp = '';
  start() {
    this.exp = 'go';
  }
}

What about animateChild()?

When an inner area of a component is queried then animateChild() can be used to kick off a sub animation that is present on the element. This continues to work even if the inner animation is within a container where animations are disabled.

@Component({
  selector: 'my-component',
  animations: [
    trigger('bodyAnimation', [
      transition('* => go', [
        style({
          transform: 'translateY(-100px)',
          opacity: 0
        }),
        animate('1s', style('*'))
      ])
    ]),
    trigger('queryAnimation', [
      transition('* => go', [
        query('header, footer', [
          style({ opacity: 0 }),
          animate('1s', style({ opacity: 1 }))
        ]),
        query('.body', animateChild())
      ])
    ])
  ],
  template: `
    <button (click)="start()">Start Animation!</button>
    <hr>
    <div [@.disabled]="disabled" [@queryAnimation]="exp">
      <header>...</header>
      <div class="body" [@bodyAnimation]="exp">...</div>
      <footer>...</footer>
    </div>
  `
})
class MyComponent {
  disabled = true;
  exp = '';
  start() {
    this.exp = 'go';
  }
}

Once again, a parent animation can query into an inner part of a template and run an animation even if that inner part has its animations set to be disabled! is so cool :)

Angular 4.3

The @.disabled binding is now available in 4.3.0-rc.0 and it will be apart of the angular.io animation documentation once Angular 4.3 is out!

to top

Up Next

Comments