提示: angular2 時animation代碼在覈心模塊裏面(@angular/core裏面);到了angular4.0時animation從核心模塊中提取出來做爲一個單獨的模塊,css
這樣能夠在不用動效時能夠不引入進來.html
animation 模塊特性方法:css3
一、 trigger 觸發器數組
`trigger`是一個動畫特定的函數,觸發器,`trigger`將根據提供的`name`值建立一個動畫觸發器angular2
trigger("myAnimationTrigger", [ state(...), state(...), transition(...), transition(...) ])
二、state 狀態angular4
`state`是一個動畫特定的函數,狀態,每一個狀態都定義了最終的樣式(動效事後的最終樣子);經過改變狀態(state)來觸發(trigger)動畫(animate)ide
state('A', style...) //狀態除了能夠本身定義一個名字外,還有有不少特殊表示狀態 *(通配符)狀態 *(通配符)狀態匹配任何動畫狀態 如:1、當該元素的狀態從active變成任何其它狀態時,active => *轉場都會生效 2、當在任意兩個狀態之間切換時,* => *轉場都會生效,下圖狀況都會發行動效轉場
void
void
的特殊狀態,它表示元素沒有被附加到視圖。這種狀況多是因爲它還沒有被添加進來或者已經被移除了函數
如:如當一個元素離開視圖時,* => void
轉場就會生效,而無論它在離場之前是什麼狀態。下圖state的兩個狀態‘void’和‘in’,發生轉場狀況動畫
三、transition 轉換this
`transition`是一個動畫特定的函數,負責定義各類 state 之間錯綜複雜的轉換關係
transition('A => B', animate...) transition('A <=> B', animate...) transition('* => *', animate...) transition(':enter', animate...) transition(':leave', animate...) transition('* => void', animate...) 也等於 :leave
transition('void => *', animate...) 也等於 :enter
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,表示裏的動畫同時進行。
四、style 樣式
`style`是一個動畫特定的函數,就是定義 css
style({backgroundColor: "red"})
五、animate 動畫
`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}) ])) //offset 0.3 是百分比 這裏和css3的動畫是同樣意思,
六、group 組
`group`是一個動畫特定的函數,指定一個並行運行的動畫步驟列表。分組動畫是當一系列樣式必須在不一樣的開始/結束時間進行動畫/關閉時頗有用。
group([ animate("1s", { background: "black" })) animate("2s", { color: "white" })) ])
七、keyframes 關鍵幀
`keyframes`是一個動畫特定的函數,能夠描述每一個樣式條目是如何應用的,以及在什麼點動畫弧(很像CSS關鍵幀動畫)
animate("5s", keyframes([
style({ backgroundColor: "red", offset: 0 }),
style({ backgroundColor: "blue", offset: 0.2 }),
style({ backgroundColor: "orange", offset: 0.3 }),
style({ backgroundColor: "black", offset: 1 })
]))
// 表示百分比,時間百分比
//若是在樣式條目中沒有使用「offset」值,則offset的值會自動計算
animate("5s", keyframes([
style({ backgroundColor: "red" }) // offset = 0
style({ backgroundColor: "blue" }) // offset = 0.33
style({ backgroundColor: "orange" }) // offset = 0.66
style({ backgroundColor: "black" }) // offset = 1
]))
八、sequence 順序
`sequence`是一個動畫特定的函數,指定逐個運行的動畫步驟列表,這個也就是和group特性正好相反,一個同時進行,一個按前後順序一個一個的進行
sequence([ style({ opacity: 0 })), animate("1s", { opacity: 1 })) ]) //其實默認就是按sequence進行的,因此上面也能夠這樣寫 以下 [ style({ opacity: 0 })), animate("1s", { opacity: 1 })) ]
九、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 } })
//以下面我定一個動效用到上面的定義。
export const fadel = trigger("fadel",[
transition("void=>*",[
useAnimation(fadeAnimation, {
params: {
time: '2s',
start: 0,
end: 1
}
})
])
]);
十、query 查詢
`query`是一個動畫特定的函數,用於在當前元素中查找一個或多個內部元素在序列中進行動畫。提供的動畫步驟已應用查詢元素(默認狀況下,提供了一個數組,而後這將是做爲動畫序列處理)。query()被設計爲收集多個元素,並經過使用內部工做`element.querySelectorAll`。能夠提供一個額外的選項對象可用於限制要收集的物品總量。query('div', [
animate(...), animate(...) ], { limit: 1 }) //'limit'限制動畫個數 //query()默認狀況下會在找到零個項目時拋出一個錯誤。若是查詢將「optional」標誌設置爲true,則該錯誤將被忽略。 query('.some-element-that-may-not-be-there', [ animate(...), animate(...) ], { optional: true })
//特殊選擇器值,查詢中的選擇器值能夠收集包含角度特定的元素
//使用特殊的僞選擇器標記 以下幾個
- 使用query(「:enter」)`/`query(「:leave」)查詢新插入
- 使用query(「:animating」)查詢全部當前的動畫元素
- 使用query(「@ triggerName」)查詢包含動畫觸發器的元素
- 使用query(「@ *」)查詢包含動畫觸發器的全部元素
- 使用`query(「:self」)`將當前元素包含到動畫序列中
query(':self, .record:enter, .record:leave, @subTrigger', [...])
//demo
@Component({
selector: 'inner',
template: `
<div [@queryAnimation]="exp">
<h1>Title</h1>
<div class="content">
Blah blah blah
</div>
</div>
`,
animations: [
trigger('queryAnimation', [
transition('* => goAnimate', [
// 隱藏內部元素
query('h1', style({ opacity: 0 })),
query('.content', style({ opacity: 0 })),
// 一個接一個地動畫內部元素
query('h1', animate(1000, style({ opacity: 1 })),
query('.content', animate(1000, style({ opacity: 1 })),
])
])
]
})
class Cmp {
exp = '';
goAnimate() {
this.exp = 'goAnimate';
}
十一、stagger
`stagger`是一個動畫特定的函數,經過在每一個被查詢的項目被動畫以後發佈時間間隔來工做。
//在下面的例子中,有一個容器元素包裝了一系列被打印的項目 //由ngFor。容器元素包含稍後將設置的動畫觸發器 //查詢每一個內部項目。 <!-- list.component.html --> <button (click)="toggle()">Show / Hide Items</button> <hr /> <div [@listAnimation]="items.length"> <div *ngFor="let item of items"> {{ item }} </div> </div> <!--list.component.ts> @Component({ templateUrl: 'list.component.html', animations: [ trigger('listAnimation', [ transition('* => *', [ // each time the binding value changes query(':leave', [ stagger(100, [ animate('0.5s', style({ opacity: 0 })) ]) ]), query(':enter', [ style({ opacity: 0 }), stagger(100, [ animate('0.5s', style({ opacity: 1 })) ]) ]) ]) ] }) class ListComponent { items = []; showItems() { this.items = [0,1,2,3,4]; } hideItems() { this.items = []; } toggle() { this.items.length ? this.hideItems() : this.showItems(); } } //如今每次添加/刪除項目,而後是不透明度 //淡入淡出的動畫將會運行或每一個刪除的項目將淡出。 // 當這些動畫中的任何一個出現時,交錯效應將是 //在每一個項目的動畫開始以後應用。
十二、animateChild
每次在角度觸發動畫,父動畫將始終得到優先權,任何兒童動畫將被阻止。爲了爲了運行一個子動畫,父動畫必須查詢每一個元素包含兒童動畫,而後容許動畫使用`animateChild`運行。
// 下面的示例HTML代碼顯示了具備動畫的父元素和子元素 // 觸發器將在同一時間執行。 ```html <!-- parent-child.component.html --> <button (click)="exp =! exp">Toggle</button> <hr> <div [@parentAnimation]="exp"> <header>Hello</header> <div [@childAnimation]="exp"> one </div> <div [@childAnimation]="exp"> two </div> <div [@childAnimation]="exp"> three </div> </div> ``` //如今當`exp`值更改成true時,只有`parentAnimation`動畫會生成動畫 //由於它有優先權。可是,使用`query`和`animateChild`每一個內部動畫 //也能夠觸發: // parent-child.component.ts import {trigger, transition, animate, style, query, animateChild} from @Component({ selector: 'parent-child-component', animations: [ trigger('parentAnimation', [ transition('false => true', [ query('header', [ style({ opacity: 0 }), animate(500, style({ opacity: 1 })) ]), query('@childAnimation', [ animateChild() ]) ]) ]), trigger('childAnimation', [ transition('false => true', [ style({ opacity: 0 }), animate(500, style({ opacity: 1 })) ]) ]) ] }) class ParentChildCmp { exp: boolean = false; } ``` //在上面的動畫代碼中,當「parentAnimation」轉換開始時,它首先查詢 //找到標題元素並淡入。而後找到包含該元素的每一個子元素 //`@ childAnimation`觸發器,而後容許他們的動畫觸發。 //這個例子能夠進一步擴展使用交錯: query('@childAnimation', stagger(100, [ animateChild() ])) //如今每一個子動畫都是以「100ms」的蹣跚步驟開始的。 // ##第一幀子動畫 //當使用animateChild執行子動畫時,動畫引擎將始終應用該動畫 //動畫序列開頭的每一個子動畫的第一幀。這條路 //父動畫不須要在子元素以前設置任何初始樣式數據 //子動畫開始。 //在上面的例子中,'childAnimation'的'false => true'轉換的第一幀 //由「不透明度:0」的風格組成。這是在「parentAnimation」時當即應用的 //動畫轉換序列開始。只有當@ @ childAnimation被查詢和調用時 //與`animateChild`將它動畫到`opacity:1`的目的地。 //請注意,此功能旨在與{ @link query query()}一塊兒使用,而且僅適用於此功能 //使用角度動畫DSL分配的動畫(這意味着CSS關鍵幀 //和轉換不禁這個API處理)
1三、動畫回調
//當動畫開始和結束時,會觸發一個回調。 //對於例子中的這個關鍵幀,咱們有一個叫作@flyInOut的trigger。在那裏咱們能夠掛鉤到那些回調,好比: template: ` <ul> <li *ngFor="let hero of heroes" (@flyInOut.start)="animationStarted($event)" (@flyInOut.done)="animationDone($event)" [@flyInOut]="'in'"> {{hero.name}} </li> </ul> `, //這些回調接收一個AnimationTransitionEvent參數,它包含一些有用的屬性,例如fromState,toState和totalTime。 //不管動畫是否實際執行過,那些回調都會觸發。 //注意: 動畫結束名爲「done」,不是「end」
到這裏基本所有介紹完了,當大家用動效時,可能有些人會發現 路由轉場動效中的「離場」動效老是沒有,後面會介紹單獨寫一個路由動效示例。