refer : css
https://angular.io/guide/animationsgit
https://github.com/angular/angular/blob/master/packages/animations/src/animation_metadata.ts github
https://github.com/angular/angular/commit/f1a9e3c (router)數組
angular 的動畫創建在一堆的方法上: 併發
1. trigger
觸發器, 用來和 dom 交互 <div [@triggerName]="state" ></div>
trigger 負責定義各類 state 和它們之間變化來變化去 transitiondom
trigger('triggerA', [ state('A', style...), state('B', style...), transition('A => B', animate...), transition('B => A', animate...) ])
2. State
angular 的概念是經過改變狀態(state)來觸發(trigger)動畫(animate)
每一個狀態都定義了最終的樣式 ide
state('A', style...)
3. transition
負責定義各類 state 之間錯綜複雜的轉換關係動畫
transition('A => B', animate...) transition('A <=> B', animate...) transition('* => *', animate...) * is whatever transition(':enter', animate...) transition(':leave', animate...) transition('* => void', animate...) void表示無, whatever to null 也等於 :leave transition((fromState, toState) => boolean, animate...) 還能夠寫方法判斷哦 transition('A => B',[style,animate]) style 也能夠放進來哦. transition('A => B',[animate,animate]) 數組 animate 會按序執行和 transition('A => B', sequence([animate,animate])) 是同樣的 transition('A => B',group(animate,animate)) 不想按序執行可使用 group
到這裏能夠看出一個基本的流程
[@triggerName]="state" 監聽了 state 的變化
一但變化發生觸發器就查找匹配的 transition 而後執行 animate. 就這樣簡單ui
4. Style
就是定義 css 啦spa
style({ display : 'none' })
5. animate
具體的動畫定義
animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...))
duration= 5second
delay=10ms
easing= cubic-bezier (ease-out 等等 css 有的均可以放)
最後加上 style 就能夠動畫了咯
animate("5s", keyframes([ style({opacity: 0, offset: 0}), style({opacity: 1, offset: 0.3}) ]))
若是你想徹底掌握節奏可使用 keyframes + offset 作定義, offset 0.3 是百分比
6.group
就是把多個 animate 組合起來併發執行.
group(animate,animate)
7.keyframes
上面說了
8.sequence
按順序一個接一個執行, 和 group 恰好打對臺, 一個 step by step, 另外一個是併發
sequence(animate,animate)
9.useAnimation
animate是能夠封裝的. 使用 animation 方法
let fadeAnimation = animation([ style({ opacity: '{{ start }}' }), animate('{{ time }}', style({ opacity: '{{ end }}')) ], { params: { time: '1000ms', start: 0, end: 1 }});
而後在任何想使用 animate 的地方改用 useAnimation
useAnimation(fadeAnimation, { params: { time: '2s', start: 1, end: 0 } })
10.query
任何你想使用 animate 的地方均可以使用 query
animate 會施法在當前的 element 上, 而經過 query 你能夠施法在 element 的 child 上
query 支持 css 選擇器的語法,還有一些 angular 特別的定義語法.
query('css-selector',[animate...])
- Querying for newly inserted/removed elements using `query(":enter")`/`query(":leave")`
這裏有個神技
<div [@listAnimation]="items.length"> <div *ngFor="let item of items"> {{ item }} </div> </div>
經過 items.length 配上下面的 transition * => * + query child 就能夠實現 items 在插入和移除時的動畫了.
transition('* => *', [ query(':leave', [ stagger(100, [ animate.. ]) ]), query(':enter', [ stagger(100, [ animate.. ]) ]) ])
- Querying all currently animating elements using `query(":animating")`
- Querying elements that contain an animation trigger using `query("@triggerName")`
- Querying all elements that contain an animation triggers using `query("@*")`
- Including the current element into the animation sequence using `query(":self")`
11.stagger
stagger 是配合 query 來使用的, 它的做用是當 query select 出不少 element 時,你但願它們不要併發, 而是隔着一個間隔時間.
query('css-selector',[stagger(100,[animate])])
好比 select 出 2 個 element, 一個觸發動畫先,另外一個則會等間隔 100ms 後才觸發.
12.animateChild
animateChild 是一個 manual trigger 概念
<div [@parentAnimation]="exp"> <div [@childAnimation]="exp"> one </div> </div>
angular 說, 當 parent trigger 觸發後,child trigger by default 是不會被觸發的 (不過我試了會 /.\)
而咱們能夠在 parent trigger 中經過 query('@child',[animateChild()]) 來手動觸發 child trigger.
這個在作 router animate 時會用到哦.
router animation 實現 https://github.com/angular/angular/commit/f1a9e3c
其實也是依據上面這些方法來作的. 主要用了 parent, child, query, enter, leave, animateChild 這些概念.