[Angular] Animation 4.2版 = wow

Animation 在 4.2 版以後,整個功能強度往上跳了好幾級,我對 Animation 本身真的沒什麼研究,但是還是盡量整理了一下,新增的功能有哪些(目前尚無完整的文件)

新增功能

Animation在 4.2 版以後有增加了許多功能,以下一一的整理,如果有遺漏或是不正確的地方,還請指教

animation

animation 方法讓我們可以使用包裝動畫效果,也可使用變數來當作動畫的參數範本。範例程式碼

1
export declare function animation(steps: AnimationMetadata | AnimationMetadata[], options?: AnimationOptions | null): AnimationReferenceMetadata;
1
2
3
4
5
6
7
8
9
10
11
export let flyIn = animation(
[
...
group([
animate(
'0.3s 0.1s ease',
style({transform: 'translateX(0px)', width: '{{width}}px'})),
animate('0.3s ease', style({opacity: 1}))
])
],
{params: {width: 120}});

透過上述的方式,可以將 animation 單獨的抽離至新檔案,也可以給予參數的能力,如果使用這個 animation 的當下如設定任何參數時,就會使用預設值。

useAnimation

如果要使用單獨抽離的 animation 時,可以使用 useAnimation ,第一個參數是要使用的 animation 名稱,如果使用的 animation 允使使用參數來改變內建的變數,那就可以設定於第二個參數位置

1
export declare function useAnimation(animation: AnimationReferenceMetadata, options?: AnimationOptions | null): AnimationAnimateRefMetadata;
1
2
3
4
5
6
7
8
9
import {flyIn} from './my-animation';
...
animations: [trigger(
'heroState',
[
...
transition('void => *', [useAnimation(flyIn, {params: {width: 100}})]),
...
])]

query

這也是另外一個強大的新功能,這功能允許使用類似 jquery 的 query 功能,透過這個可以快速地針對特定的 HTMLElement 加上動畫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
animations: [trigger(
'flyInOut',
[
...
transition(':enter', [group([
useAnimation(flyIn, {params: {width: 100}}),
query('p',
[
style({ opacity: 0 }),
animate(4000, style({ opacity: 1 }))
])
])
])
...
])]
1
2
3
4
5
6
<ul>
<li *ngFor="let hero of heroes" [@flyInOut]="'in'">
<p>{{hero.name}}</p>
</li>
</ul>

animateChild

animateChild 搭配 query 的使用,可以觸發內層元件的動畫事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@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;
}
1
2
3
4
5
6
7
8
9
10
11
12
<div [@parentAnimation]="exp">
<header>Hello</header>
<div [@childAnimation]="exp">
one
</div>
<div [@childAnimation]="exp">
two
</div>
<div [@childAnimation]="exp">
three
</div>
</div>

stagger

stagger 這個方法可以去設定再跑 ngFor 時,可以讓動畫一筆一筆的跑,這方法需要再 query 內使用

1
export declare function stagger(timings: string | number, animation: AnimationMetadata | AnimationMetadata[]): AnimationStaggerMetadata;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@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 }))
], {optional: true})
]),
query(':enter', [
style({ opacity: 0 }),
stagger(100, [
animate('0.5s', style({ opacity: 1 }))
], {optional: true})
])
])
])
]
})
class ListComponent {
items = [];

showItems() {
this.items = [0,1,2,3,4];
}

hideItems() {
this.items = [];
}

toggle() {
this.items.length ? this.hideItems() : this.showItems();
}
}
1
2
3
4
5
6
7
<button (click)="toggle()">Show / Hide Items</button>
<hr />
<div [@listAnimation]="items.length">
<div *ngFor="let item of items">
{{ item }}
</div>
</div>

AnimationBuilder

AnimationBuilderbuild 方法會產生一個 AnimationFactory,而 AnimationFactorycreate 方法可以產生一個 AnimationPlayer,這個 AnimationPlayer 是可以被撥放,暫停或停止。這模式可以讓我們用程式碼的方式,建立與 decorator 內 animations 區塊相同功能出來,且可以手動控制執行動畫的時間點。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
export class HeroListComponent {
constructor(private _builder: AnimationBuilder) {}
...
makeAnimation(element: any) {
// first build the animation
const myAnimation = this._builder.build(
[style({opacity: 0}), animate('0.3s 0.2s ease', style({opacity: 1}))]);

// then create a player from it
const player = myAnimation.create(element);
player.play();
}
}

總結

Angular 4.2 版大大的加強 animation 的功能,或許還有些新功能我沒有注意到,但是上述的這些新用法,就已經足以玩出很多種變化。

尤其是讓動畫的效果可以重複使用,對於前端設計者,就可以專注於動畫的設計,而其他對於 animation 不熟悉的人,也可以簡單的使用已經設計好的動畫效果。

非常期待一些大師發布 angular animation 作品,可以讓我們簡單的使用設計好的動畫效果。