Angular Workshop - Animationsに参加してきたので忘れないうちにメモ。
スライドは http://slides.com/gerardsans/ng-japan-animations#/ です。
Gerardさんの説明がわかりやすく途中に手を動かす練習問題もあって大変良かったです
Angular Animationって?
-
Web Animations APIの上に実装されている
- まだ実装していないブラウザもあるのでそのときはpolyfillを使う
- Web Animations APIはローレベルでできないこともあるので、Angular Animationを作った
- CSS Transitions, CSS Animationsと似たAPI
CSS Transitions
- 初期状態・終了状態を定義する
- 途中の状態は自動的に計算される
- アニメーションするプロパティを指定する
- アニメーションは計算コストが高い
- opacity, transformがオススメ(って言ってた気がする)
-
transition: color 5s ease-in 1s;
-
color
アニメーションするプロパティ -
5s
アニメーションにかける時間(duration) -
ease-in
アニメーションの値の変化(timing) -
1s
アニメーション開始を遅らせる時間(delay)
-
- ease-inとかcubic-bezierとかを理解するのに便利なサイト
CSS Animations
- CSS TransitionにKeyframeを追加したようなやつ
- 初期状態・終了状態の間に中間状態を任意の数定義できる
- その中間状態の間は自動的に計算される
-
animation: fade 5s 1s infinite linear
-
fade
アニメーション名、別のところで@keyframes fade {...}
を定義 -
5s
アニメーションにかける時間(duration) -
1s
アニメーション開始を遅らせる時間(delay) -
infinite
アニメーションの繰り返し(iterations) -
linear
アニメーションの値の変化(timing)
-
@keyframes fade {
0% { opacity: 1; }
100% { opacity: 0; }
}
Angular Animations
- 基本はCSS Transitionsのように状態と、状態の間の遷移を定義する
-
fadeIn
fadeOut
のような文字列で状態を定義 - 状態の遷移を矢印で表した文字列で定義
fadeIn => fadeOut
fadeIn <= fadeOut
fadeIn <=> fadeOut
-
void
と*
は特殊なキーワード-
void
は要素が画面からなくなっている状態 -
*
はvoid
を含む全ての状態
-
-
:enter
はvoid => *
のショートハンド :leave
は* => void
のショートハンド-
animationは別モジュールなのでnpmインストール、TSでのインポートが必要
npm i @angular/animations
@NgModule({ imports: [ BrowserAnimationModule ], ... })
Animation Example
@Component({
selector: 'my-app',
template: `<button [@fade]='fade' (click)="toggleFade()">Fade</button>`,
animations: [ trigger('fade', [
state('fadeIn', style({ opacity: 1 })),
state('fadeOut', style({ opacity: 0.1 })),
transition('fadeIn <=> fadeOut', animate('2000ms linear'))
])]
})
export class App {
fade = 'fadeIn';
toggleFade(){
this.fade = this.fade === 'fadeIn' ? 'fadeOut' : 'fadeIn';
}
}
-
[@fade]
- アニメーションする要素のプロパティにアニメーションをバインディング
-
@
がアニメーションを意味するプレフィックス -
[@fade]
はtrigger('fade', ...)
のアニメーションを指定している -
[@fade]="fade"
の右辺は状態を表す文字列が入っているAppクラスの変数を指している。toggleFadeで文字列が入れ替わって、その文字列に当たる状態へのtransitionが始まる
-
animations
- アニメーションの状態を
state
で定義 - 状態の間の遷移を
transition
で定義
- アニメーションの状態を
- デモ
Keyframes Example
export const grow = trigger('grow' , [
state('small', style({ transform: 'scale(1)' })),
state('large', style({ transform: 'scale(1.4)' })),
transition('small <=> large', animate('200ms linear', keyframes([
style({transform: 'scale(1.6)', offset: 0}),
style({transform: 'scale(1.4)', offset: 1})
])
))
])
-
keyframes
の中に2つ並べるとそれぞれ初期、終了状態 - 複数並べると等分されていく
- 別途どの位置に来るかをoffsetで明示できる
style({opacity: 1, transform: 'translateX(15px)', offset: 0.3})
Animation Callbacks
import {fade} from './animations';
@Component({
selector: 'my-app',
template: `<img [@fade]='fade'
(@fade.start)="start($event)"
(@fade.done)="done($event) >`,
animations: [ fade ]
})
export class App {
start(e) { }
done(e) { }
}
- (この例みたいにアニメーションを別ファイルに定義するのがComponentがでかくなりすぎないのでベストプラクティスだった言ってた気がする)
- start, doneのコールバックがある
-
$event
のペイロードのかたち
$event == {
element: any, // div element
triggerName: string, // "fade"
phaseName: string // "start" or "done"
fromState: string, // "in" or "out"
toState: string, // "in" or "out"
totalTime: number, // 1000 (milliseconds)
}
New in Angular 4.2
後日。。。