slides.com/gerardsans | @gerardsans
Reactive
Animations
Google Developer Expert
Master of Ceremonies
Blogger
International Speaker
Spoken at 56 events in 18 countries
Angular Trainer
Community Leader
900
1K
Angular In Flip Flops
#dfua
Why use Animations?
Improved UX ✨
Perceived Performance
Immersive interactions
Better engagement
User happiness 😃
Animation Principles
Squash & Stretch + Anticipation
Follow through
Exaggeration
Composition
Animation Techniques
Move
transform: translateX(10px);
Resize
transform: scale(0.5);
Rotate
transform: rotate(1turn);
Fade
opacity: 0;
Move
<div class="circle base elastic"></div>
.base {
animation: move 2s infinite;
}
.elastic {
animation-timing-function:
cubic-bezier(.8,-0.6,0.2,1.5);
}
@keyframes move {
0% {
transform: translateX(-250px);
}
40%, 60% {
transform: translateX(50px);
}
100% {
transform: translateX(250px);
}
}
Rotate
<div class="square base linear"></div>
.base {
animation: spin 2s infinite;
}
.linear {
animation-timing-function: linear;
}
@keyframes spin {
to {
transform: rotate(1turn);
}
}
Resize
<div class="circle base"></div>
.base {
animation: size 2s infinite;
}
@keyframes size {
0%, 40%, 100% {
transform: scale(1);
}
25%, 60% {
transform: scale(1.1);
}
}
Fade
<div class="circle base elastic"></div>
.base {
animation: fade 2s infinite;
}
@keyframes fade {
0% {
transform: translateX(0px);
opacity: 0;
}
40%, 60% {
transform: translateX(80px);
opacity: 1;
}
100% {
transform: translateX(0px);
opacity: 0;
}
}
Advanced Techniques
Easing
Offset Delay
Parenting
Binding Values
Overlay
Example
Angular Animations
States & Transitions
void
*
Special Keywords
void => * :enter
* => void :leave
void <=> *
STATE
STATE
fadeIn
fadeOut
States & Transitions
TRANSITIONS
STATE
STATE
fadeIn => fadeOut
fadeOut => fadeIn
fadeIn <=> fadeOut
Animation Example
import {fade} from './animations';
@Component({
selector: 'my-app',
template: `<button [@fade]='fade' (click)="toggleFade()">Fade</button>`,
animations: [ fade ]
})
export class App {
fade = 'fadeIn';
toggleFade(){
this.fade = this.fade === 'fadeIn' ? 'fadeOut' : 'fadeIn';
}
}
Animation Example
import {
trigger, transition, state, style, animate
} from '@angular/animations';
export const fade = trigger('fade', [
state('fadeIn', style({ opacity: 1 })),
state('fadeOut', style({ opacity: 0.1 })),
transition('fadeIn <=> fadeOut', animate('2000ms linear'))
]);
Execution Order
sequence
group
time
Composition
animateChild
time
Stagger
time
Dynamic Selectors
class="container"
class="item"
class="item"
query(selector)
Dynamic Selectors
query('.item')
class="container"
class="item"
class="item"
Dynamic Selectors
query('.item:enter')
class="container"
class="item"
class="item"
class="item"
added
Reactive Animations
Introduction
- react to user interactions
- maps user input to CSS
- mouse position, keyboard, scroll, input field
- static or dynamic
Technologies
- Animations
- CSS, canvas, WebGL, SVG
- AnimationBuilder
- Player
- Events
- RxJS
AnimationBuilder
import {AnimationBuilder} from "@angular/animations";
export class MyComponent {
constructor(
private elem: ElementRef,
private builder: AnimationBuilder
) {
const player = this.playerMoveTo({ x: 100, y: 100 });
player.play();
}
playerMoveTo(to) {
const moveAnimation = this.builder.build([
animate('1s', style({ transform: `translate(${x}px, ${y}px)` }))
]);
return moveAnimation.create(this.elem.nativeElement
, {params: { x: to.x, y: to.y }});
}
}
Tracking mouse position
constructor(
private elem: ElementRef
) {
// find out center
this.mx = elem.nativeElement.offsetWidth/2;
this.my = elem.nativeElement.offsetHeight/2;
}
ngOnInit() {
const mouseMove$ = Observable.fromEvent(document, 'mousemove')
.map(e => ({ x: e.pageX, y: e.pageY }));
mouseMove$.subscribe({
next: e => {
this.lastPosition = { x: e.x-this.mx, y: e.y-this.my };
const player = this.playerMoveTo(this.lastPosition);
player.play();
}
})
}
Performance
Considerations
- Avoid unnecessary layout/repaint
- Use opacity, transform
- Hardware acceleration (avoid)
- transform: translateZ(0)
Saving Resources
.visible.advert {
will-change: transform;
}
.visible.advert:hover {
transform: scale(1.2);
}
More
Inspiration
David Khourshid
Issara Willenskomer
Sarah Drasner
Rachel Nabors
Reactive Animations using Angular
By Gerard Sans
Reactive Animations using Angular
How we can use Angular to achieve Reactive Animations. The overall idea is capturing multiple streams of events into one, and then emitting those values over to CSS creating animations. We will cover Web Animations API and how we can use Angular together with field-tested animation techniques providing examples for CSS transitions/animations and SVG. We will also study browser compatibility and performance to achieve reliable and smooth animations. Let's bring our Angular skills to the awesome world of animations!
- 2,980