ngAnimate2.0

download ngAnimate2.0

of 9

Transcript of ngAnimate2.0

  • 7/24/2019 ngAnimate2.0

    1/9

    ngAnimate in Angular [email protected]

    [email protected]

    Basic Idea of ngAnimateThe ngAnimate module makes CSS, JS and Timeline-based animations work with pre-existing

    and custom components/directies present in Angular.

    What this Document Proposes- !ow to link animations between elements and CSS, JS, timelines- Changes in detection and naming- "mproements to animation reusabilit#- Animation plugins and de$ault component animations- %re-detection and tooling support

    How Angular 1.x wored&irecties trigger eents 'like enter and leae( and ngAnimate will attempt to capture a CSS or

    JS animation based on what it detects. &etection $or CSS usuall# inoles using

    getComputedSt#le which causes a re$low. )epeated re$lows slow things down and

    getComputedSt#le in general is er# unreliable.

    The ma*or problems with ngAnimate in +.x are

    - ngClass is oerused b# ngAnimate and causes some bugg# behaiour with

    detection and multiple class computations- Too man# re$lows due to reuestAnimationarme, getComputedSt#le and

    document.bod#.clientidth results in per$ormance issues- Too little pre-calculated in$ormation 're$lows are used to direct ngAnimate to

    behae in a certain wa#( cause things to slow down- Too much &01 traersal within 2animate due to CSS class behaiour- 3o real wa# to extend seuencing behaiour and to include child animations- CSS transitions and ke#$rames are sub*ect to browser inconsistencies and

    reuire too much code to create a leelled-out plat$orm- Tooling is non-existent- 3o support $or metadata- 3o wa# to mix CSS, JS and timelines together

    - The code is di$$icult to maintain and is too big oerall

    !he Angular 2.0 wa"

    irst things $irst, Angular 4.5 will not use addClass/remoeClass 'ngClass( to trigger animations.

    So something like this won6t work

    mailto:[email protected]:[email protected]:[email protected]:[email protected]
  • 7/24/2019 ngAnimate2.0

    2/9

    .my-component.fade-add { }

    .my-component.fade { }

    .my-component.fade-add-active { }

    Fade n

    &ealing with CSS is complicated $or when classes are added and remoed. Should the $ollow-

    up animation cancel out the preious one7 hen do we merge things together7 These

    uestions are pointment and there is no reason for the framework to have to make these

    decisions. "nstead we should *ust treat standard transitions, ke#$rame and class-based

    interactions outside o$ the realm o$ ngAnimate 'let the browser handle it(.

    hen it actuall# comes down to ngAnimate-powered animations, instead o$ rel#ing on the global

    landscape o$ CSS 'where eer#thing is de$ined as $loating CSS classes and selectors(, Angular

    4.5 will $ollow a mechanism o$ attaching animations to components via an app-level

    manifest file.

    The $ile looks something like this

    // animations.!son

    {

    "#.ng-enter : ".fade

    ".some-page-page.ng-leave : "{fade$%&nimation}

    ".some-page-page : "

  • 7/24/2019 ngAnimate2.0

    3/9

    // animations.!son

    {

    "#.ng-enter : ".fade*s s+

    }

    The timing $or the animation is now de$ined within the JS03 $ile. The $ade animation will run $or8s and hae a starting dela# o$ +s. When ngAnimate starts the animation it will build out the

    custom durationdelay transition by itself with the functionality of !animate"ss. This

    means that a deeloper can create a st#lesheet with only "## classes containing styles and

    $ero animation code.This cleans up some o$ the mess o$ endor pre$ixing and browser

    nuances.

    Sequenced and Parallel CSS-based animationsSince eer#thing is de$ined in a central JS03 $ile, we can de$ine a language $or seuenced

    animations. 9et6s sa# $or example we wanted to run fade then slide then rotate then e%plode&

    // animations.!son

    {

    "my-component.ng-enter :

    ".fade-prepare01

    ".fade*s s+1

    ".slide*s+1

    ".rotate*2s+1

    ".e3plode*222ms+4

    }

    The arra# s#ntax does the trick. :ut what about i$ we wanted to run eer#thing in parallel on that

    element7

    // animations.!son

    {

    "my-component.ng-enter : ".fade*s s+ .slide*s+

    .rotate*2s+ .e3plode*222ms+

    }

    Then mixing both together is triial

    // animations.!son

    {

    "my-component.ng-enter :

    ".fade*s s+ .slide*s+1

    ".rotate*2s+ .e3plode*222ms+4

    }

  • 7/24/2019 ngAnimate2.0

    4/9

    ;ou can also *ust pass a bunch o$ CSS classes and hae 2animateCss do the detection like it

    did in +.x

    // animations.!son

    {

    "my-component.ng-enter : {"com5ine-properties*+: true1

    "animation:".flip .rotate .spin .e3plode .fade-out

    }

    }

    This makes using other CSS libraries like animate.css triial

    // animations.!son

    {

    "my-component.ng-enter : ".animated.rotaten6ut

    }

    e can also use ke#$rames directl#

    // animations.!son

    {

    "my-component.ng-enter : ")5ounce*7s+

    }

    (a)a$cript%*ased AnimationsThe JS03 mani$est $ile also be able to trigger JaaScript animations. That we wanted to run a

    special pageChangeAnimation then we can do using this code

    // animations.!son

    {

    "my-component.ng-enter1 my-component.ng-leave :

    "{pageAnimations.change(10s 2s)}

    }

    The JaaScript animation will then be executed as

    class 8age&nimations {static c(ange*elements1 meta9ata+: 8romise {

    return some8romiseFor'(e&nimation

    }

    }

    The $unction will be executed with the params

  • 7/24/2019 ngAnimate2.0

    5/9

    // for ;(en 5ot( enter and leave are detected

    c(ange* { enter: enterlm1 leave: leavelm }1 { duration : 21

    delay : 7 }+

    // for ;(en only enter is present

    c(ange* { enter: enterlm }1 { duration : 21 delay : 7 }+

    e can also collect children that are also animating

    // animations.!son

    {

    "my-container: {

    "collect: ".ng-enter1 .ng-leave1

    "animation: "8age&nimations.c(ange*2s 7s+

    }

    }

    Since %ageAnimations is a class associated with Angular6s &", we need to attach that class to

    the in*ector o$ the app

    )n!ecta5le*+

    class 8age&nimations { }

    !imeline Based Animations

    Timeline animations are important $or complex seuencing 'which 1aterial needs( and $orplat$orm speci$ic data. Timelines are defined in ' and are used to choreograph animations

    which occur on multiple elements and on multiple leels

    // animations.!son

    {

    "my-container: "

    }

    The timeline

  • 7/24/2019 ngAnimate2.0

    6/9

    Performance +nhancements=sing this JS03 mani$est approach, deelopers can $ine-tune animations to proide hard coded

    duration alues directl# into the animation

    // animations.!son

    {// there is no need to call getComputedStyle or any reflo

    code here since e !no the duration

    ".ng-enter : ".slide*2s+

    // this ill call getComputedStyle "ehind the scenes

    ".ng-enter : ".slide

    }

    3gAnimate in +.x per$orms arious steps to >prepare? the element so that it can be animated

    using -add and -remoe st#ling. This st#ling isn6t alwa#s necessar# and slows things down.

    !oweer i$ #ou want to hae st#les be applied be$orehand then that is possible ia changing

    classes

    // animations.!son

    {

    // still no need to run getComputedStyle

    ".ng-enter : ".ng-(ide-add01 ".ng-(ide*2s+4

    }

    Since we are using simple CSS classes, the Angular 4.5 building s#stem can do extra work to

    attempt to $ill in the duration alues $or us. So i$ we de$ine .fade like so then

    .ng-(ide-add { opacity: transition:.s }

    .ng-(ide { opacity:2 transition:.s }

    Then ngAnimate within the compilation step can go in and $ill that into our compiled mani$est $ile

    to speed things up. e can also per$orm more aggressie caching.

    CSS? Greensock? WebAnimations? Mobile?Since the JS03 mani$est communicates with CSS directl# without the need $or transitions or

    ke#$rame animations this means that changing the underl#ing rendering mechanism can bedone without an# conseuence to the user.

    9ibraries like reensock and the eb Animations A%" allow $or $rame b# $rame control o$ the

    animation. There$ore i$ this rendering mechanism is used then the librar# can leerage those

    $eatures and the user can dictate that those animations need those $eatures. or example

    // animations.!son

  • 7/24/2019 ngAnimate2.0

    7/9

    {

    ".page-c(ange: {

    "driver: ";e5-animations1

    "animate: { ".old-page : ".fade6ut }1

    { ".ne;-page : ".faden }4

    }}

    3ow the deeloper can expose a pla#er A%" which can hook into the page change animation

    which allows to change the $rame at an instantaneous point. e can also proide extra meta

    data to handle snap points

    // animations.!son

    {

    ".page-c(ange: {

    "driver: ";e5-animations1

    "snap'ond: "2

    }

    }

    0nce again, i$ the drier supports this stu$$ then we should allow the deelopers to use it.

    !oolingSince the JS03 $ile exists and all the Angular-specific animations are e%plicitly declared

    this means that "&s and tools can inspect the $ile and proide hints within CSS code to tell us

    that the animations belong to Angular.

    =pon compilation, we can also inspect all the CSS $iles against the JS03 mani$est $ile to see i$

    an# classes, JS animations and/or timelines are not de$ined or are con$igured incorrectl#.

    Plugins and ,i*raries1uch like the example o$ animate.css, animation st#ling can be de$ined within the realm o$ CSS

    code, but the animation and seuencing is de$ined within the JS03 mani$est. !oweer what

    about pre-existing plugins that hae their own animations7 !ow could something like 1aterial

    sa$el# de$ine their own animations and allow the user to change things around i$ the# want to

    e can allow a plugin librar# like 1aterial to create their own JS03 $ile and attach that to their

    own librar#.

    )&nimations*"md-progress.!son+

    class ?d8rogress@inear { }

  • 7/24/2019 ngAnimate2.0

    8/9

    Then the animations are parsed at normal and behae as normal within the application. "$ the

    user choses to disable all animations then the# can do so within their own AppCmp

    )&nimations*false+

    class &pp,mp {}

    :ut i$ the user choses to allow 1aterial animations and to extend their behaiour then the# can

    do so ia their own top-leel animations.*son $ile

    // c(ange t(e animation entirely

    { "md-progress.ng-enter : ".fade .flip .rotate }

    // c(ange t(e duration or delay

    { "md-progress.ng-enter : { duration: 2.1 delay: 2. } }

    // prepend or append t(e animation ;it( ot(er animations

    { "md-progress.ng-enter : ".flip1 "in(erit 4 }

    { "md-progress.ng-enter : "in(erit1 ".flip 4 }

    !estingSince animation de$initions and seuencing/registration are separated, we can hae protractor

    run through each defined animation within the #+ manifest and attempt to run the

    animation. =pon running each animation it can detect to see i$ the animation actuall# triggers a

    st#le change or not. Since we know exactl# what CSS classes, JS animations and timelines we

    are dealing with it makes things easier to detect when there are collisions and no animations

    that are triggered. Take this $or example

    .5lue { 5acAground: 5lue 0 important }

    .red { 5acAground: red transition:s }

    am 5lue

    //animations.!son

    { ".colourful-component.ng-enter: ".red }

    ithin this circumstance the color will neer change $rom blue to red since blue alwa#s wins.3ormall# this would be impossible to detect within ngAnimate +.x, but in 4.x we can hae a

    series o$ unit tests be build upon compile to $ind these bugs.

    >.page-change? B

    >animation? B

    >85? >B*snD?,

  • 7/24/2019 ngAnimate2.0

    9/9

    >E5? >.class?

    D

    D

    FanimationG

    Fanimation-step HG