Angular Animations
@jurisicmarko
marko.jurisic@bearingpoint.com
Animations
- engage with users, call attention where it's needed
- make our applications more fun to use and program
- CSS3 - adding and removing classes, good for simple effects
- Angular Animations uses Web animations - allows for fine animation control
Angular Animations
- Web Animations (supported in all modern browsers, polyfill available for others)
- Animation DSL
- states, transitions, transformations
- from version 4.2: router animations, animation params, scrubbing...
Most Angular Docs/Tutorials
Animations docs
Minimal example
"dependencies": {
...
"@angular/animations": "4.4.3",
"@angular/platform-browser": "4.4.3"
...
}
imports: [
BrowserModule,
BrowserAnimationsModule,
...
]
<div [@animationTrigger]="animationState">Wow! Just wow!</div>
<button (click)="doToggle()">Magic!</button>
package.json
app.module.ts
app.component.html
Minimal example
import { Component } from '@angular/core';
import { trigger, style, animate, state, transition, } from '@angular/animations';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('animationTrigger', [
state('inactive', style({ opacity: 0 })),
state('active', style({ opacity: 1 })),
transition('inactive=>active', animate(1500))
])
]
})
export class AppComponent {
animationState = 'inactive'
doToggle() {
this.animationState = this.animationState == 'active' ? 'inactive' : 'active';
}
}
app.component.ts
Demo
States
- string values, tied to a class property
- special states void and *
Transitions
- Using predefined states:
- Inline transitions:
transition('void => *', [
style({transform: 'translateX(-100%)'}),
animate(100)
]),
state('inactive', style({ opacity: 0 })),
state('active', style({ opacity: 1 })),
transition('inactive <=> active', animate(1500))
transition(':enter', [ ... ]); // void => *
transition(':leave', [ ... ]); // * => void
Angular 4.2+ new features
- Animation options/ input params
- animation() / useAnimation()
- query() and stagger()
- sub animations using animateChild()
- routing animations
- programmatic animations with AnimationsBuilder
Animation options / input params
<div [@animation]="{value: expVal, /* option1: value, option2: value */ }">...</div>
// inside of @Component.animations...
transition('* => *', [
style({ opacity: 0 }),
animate("{{ time }}",
style({ opacity: "{{ opacity }}" }),
], {
time: "1s",
opacity: "1"
})
*shamelessly stolen from https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html#animation-options-input-params
animation() / useAnimation()
// animations.ts
import {animation, style, animate} from "@angular/animations";
export var fadeAnimation = animation([
style({ opacity: "{{ from }}" }),
animate("{{ time }}", style({ opacity: "{{ to }}" }))
], { time: "1s" })
// inside of @Component.animations...
import {useAnimation, transition} from "@angular/animations";
import {fadeAnimation} from "./animations";
transition('* => *', [
useAnimation(fadeAnimation, {
from: 0,
to: 1,
time: '1s'
})
])
*shamelessly stolen from https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html#animation-options-input-params
query() and stagger()
<p>Template</p>
<div [@listAnimation]="items.length">
<div *ngFor="let item of items" >
<p>{{item.title}}</p>
</div>
</div>
// inside of @Component.animations...
trigger('listAnimation', [
transition('*<=>*', [
query('p', style({transform: 'translateX(-100%)'})),
query('p',
stagger('200ms', [
animate('1000ms', style({transform:'translateX(0)'}))
]))
])
])
//...
items = [
{title:'first'},
{title:'second'},
{title:'third'},
]
sub animations using animateChild()
<!-- do these two guys animate at the same time? -->
<div [@parent]="parentVal">
<div [@child]="childVal">
...
</div>
</div>
trigger('parent', [
style({ transform: 'translate(-100px)' }),
animate('500ms',
style({ transform: 'translate(0px)' })),
query('@child', animateChild())
]),
trigger('child', [
style({ opacity:0 }),
animate('0.5s', style({ opacity:1 }))
])
*shamelessly stolen from https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html#animation-options-input-params
trigger('parent', [
style({ transform: 'translate(-100px)' }),
animate('500ms', style({ transform: 'translate(0px)' }))
]),
trigger('child', [
style({ opacity:0 }),
animate('0.5s', style({ opacity:1 }))
])
Parent always wins, unlike in real world
routing animations
<!-- app.html -->
<div [@routeAnimation]="prepRouteState(routerOutlet)">
<!-- make sure to keep the ="outlet" part -->
<router-outlet #routerOutlet="outlet"></div>
<div>
trigger('routeAnimation', [
//...
transition('homePage => supportPage', [
// make sure the new page is hidden first
query(':enter', style({ opacity: 1 })),
// animate the leave page away
query(':leave', [
animate('0.5s', style({ opacity: 0 })),
style({ display: 'none' })
]),
// and now reveal the enter
query(':enter', animate('0.5s',
style({ opacity: 1 }))),
]),
//...
])
*shamelessly stolen from https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html#animation-options-input-params
<!-- app.ts -->
const ROUTES = [
{ path: '',
component: HomePageComponent,
data: {
animation: 'homePage'
}
},
{ path: 'support',
component: SupportPageComponent,
data: {
animation: 'supportPage'
}
}
]
programmatic animations with AnimationsBuilder
constructor(private _builder: AnimationBuilder) {}
@Input('percentage')
set percentage(p: number) {
this._percentage = p;
if (this.player) {
this.player.destroy();
}
const factory = this._builder.build([
style({ width: '*' }),
animate('350ms cubic-bezier(.35, 0, .25, 1)', style({ width: (p * 100) + '%' }))
]);
this.player = factory.create(this.loadingBar.nativeElement, {});
this.player.play();
}
*shamelessly stolen from https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html#animation-options-input-params
Another demo
References
- Angular Animations Guide
https://angular.io/guide/animations - Web Animations
https://w3c.github.io/web-animations - CSS3 Transitions
https://www.w3.org/TR/css3-transitions - M. Niemelä: A New Wave of Animation Features in Angular
https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html
Angular Animations
By Marko Jurišić
Angular Animations
- 1,109