Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Gerard Sans] Reactive Animations Using Angular

[Gerard Sans] Reactive Animations Using Angular

Presentation from GDG DevFest Ukraine 2017 - the biggest community-driven Google tech conference in the CEE.

Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

October 14, 2017
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. HTML Page life-cycle HTML Page life-cycle Load HTML Parse HTML

    Load CSS Parse CSS Create DOM tree Display Attach style to DOM nodes source: blog
  2. Specificity and Order Specificity and Order Element style Element id

    class/attribute selectors element selectors last CSS rule wins
  3. Background Background Integrate CSS, JS and SVG CSS hardware acceleration

    CSS variables + JS requestAnimationFrame (rAF) setInterval , (GSAP) Velocity GreenSock
  4. Angular CLI 1.0 Angular CLI 1.0 npm install web-animations-js --save

    // src/polyfills.ts import 'web-animations-js';
  5. CSS Transitions CSS Transitions Define an initial and final state

    Intermediate states are calculated automatically We can choose which CSS properties we want to affect Not all CSS properties are animatable ( ) list
  6. Animatable CSS Animatable CSS all background* border* bottom box- shadow

    clip clip-path color filter font* height left margin* mask* offset* opacity outline* padding* perspective* right text-decoration text-shadow top transform vertical- align visibility width z-index
  7. CSS Animations CSS Animations Define any number of states between

    the initial and final state Changes from states are calculated automatically We can choose which CSS properties we want to affect
  8. CSS Animation CSS Animation NAME animation: fade 5s 1s infinite

    linear; DURATION DELAY ITERATIONS TIMING
  9. Move 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); } }
  10. Rotate Rotate <div class="square base linear"></div> .base { animation: spin

    2s infinite; } .linear { animation-timing-function: linear; } @keyframes spin { to { transform: rotate(1turn); } }
  11. Resize 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); } }
  12. Fade 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; } }
  13. void * Special Keywords Special Keywords void => * :enter

    * => void :leave void <=> * STATE STATE
  14. fadeIn fadeOut States & Transitions States & Transitions TRANSITIONS STATE

    STATE fadeIn => fadeOut fadeOut => fadeIn fadeIn <=> fadeOut
  15. Animations Setup Animations Setup // npm install --save @angular/animations //

    app.module.ts import {Component, NgModule} from '@angular/core'; import {BrowserAnimationsModule} from '@angular/platform-browser/animat @Component({ }) export class App { } @NgModule({ imports: [ BrowserModule, BrowserAnimationsModule ], declarations: [ App ], bootstrap: [ App ] }) export class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule)
  16. Animation Example 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'; } }
  17. Animation Example 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')) ]);
  18. Router transitions Router transitions import { routerTransition } from './router.animations';

    @Component({ template: ` <main [@routerTransition]="getState(o)"> <router-outlet #o="outlet"></router-outlet> </main> `, animations: [ routerTransition ] }) export class App { getState(outlet) { return outlet.activatedRouteData.state; } }
  19. Routes Setup Routes Setup const routes = [ { path:

    '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: Home, data: { state: 'home'} }, { path: 'about', component: About, data: { state: 'about'} }, { path: '**', component: NotFound } ];
  20. Router transitions Router transitions export const routerTransition = trigger('routerTransition', [

    transition('about <=> home', [ query(':enter, :leave', style({ position: 'fixed', width:'100%' })) group([ query(':enter', [ style({ transform: 'translateX(100%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' ]), query(':leave', [ style({ transform: 'translateX(0%)' }), animate('0.5s ease-in-out', style({ transform: 'translateX(100% ]), ]) ]) ])
  21. Considerations Considerations Avoid unnecessary layout/repaint Avoid unnecessary layout/repaint Use opacity,

    transform Use opacity, transform Hardware acceleration (avoid) Hardware acceleration (avoid) transform: translateZ(0) transform: translateZ(0)