AngularJSでちゃちゃっとアニメーションを試す


AngularJS 1.2.4

AngularJS 1.2.4 がリリースされ、$animate 関連の Bug Fixes が入り ng-include をネストした ng-repeat でアニメーションが効かない問題も解消されたので、アニメーションをちゃちゃっと試す方法を紹介。

angular-animate.js

HTML に angular と angular-animate の js ファイルを記述する。

1
2
<script src="angular.min.js">
<script src="angular-animate.min.js">

ngAnimate モジュール

依存モジュールとして ngAnimate を記述する。

1
angular.module('app', [ 'ngAnimate' ])

CSS 定義

これだけでもうゴール間近で、あとはどんなアニメーションを適用するのかを考えて定義するだけ。

アニメーションを CSS で定義する方法と JavaScript で記述する方法があり、ここではちゃちゃっと試すのが簡単な CSS を例示する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.ng-enter,
.ng-leave,
.ng-move {
  -webkit-transition: opacity 0.15s linear;
  transition: opacity 0.15s linear;
}
.ng-enter {
  opacity: 0;
}
.ng-enter.ng-enter-active {
  opacity: 1;
}
.ng-leave {
  opacity: 1;
}
.ng-leave.ng-leave-active {
  opacity: 0;
}
.ng-move {
  opacity: .5;
}
.ng-move.ng-move-active {
  opacity: 1;
}

この CSS 定義だけで、enter leave move系のngRepeat ngView ngInclude ngSwitch ngIf directives に fade(フェード)のアニメーションが適用される。

アニメーションを限定的に適用

ちゃちゃっとアニメーションを試してみるのにはさっきの CSS で OK だけど、アニメーションされすぎで気持ち悪いとか、アニメーションのせいでむしろ遅い UI に感じられるとか、テーブルタグなどで不自然なレンダリングになるとか…。

なので、ちゃんとアニメーションを使うときには CSS のセレクタに class name(以下では animated)を追加し、適用箇所を限定する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.animated.ng-enter,
.animated.ng-leave,
.animated.ng-move {
  -webkit-transition: opacity 0.15s linear;
  transition: opacity 0.15s linear;
}
.animated.ng-enter {
  opacity: 0;
}
.animated.ng-enter.ng-enter-active {
  opacity: 1;
}
.animated.ng-leave {
  opacity: 1;
}
.animated.ng-leave.ng-leave-active {
  opacity: 0;
}
.animated.ng-move {
  opacity: .5;
}
.animated.ng-move.ng-move-active {
  opacity: 1;
}

そして、HTML 側でアニメーションさせたいng-ifng-repeatを指定した要素の class 属性に animated を追記する。

1
<div ng-if="model.visible" class="animated">...</div>

むやみやたらにアニメーションするのでなく、こうしてポイントポイントで上品に適用していくことを心掛けよう。

サンプル

JS Bin

class 属性の変化

class 属性が変化する流れを見ておく。

model.visible = false;(非表示状態)のときがこのようなコードだとして、

1
<div ng-if="model.visible" class="animated">...</div>

model.visible = true;(表示に切替)になるとまずng-enterが追加(opacity: 0;)されて、

1
<div ng-if="model.visible" class="animated ng-enter">...</div>

その後すぐにng-enter-activeが追加(opacity: 1;)されることでアニメーションが開始する。CSS で定義している transition: opacity 0.15s linear;により 0.15s の速度でフェードしながら表示(fadeIn)され、

1
<div ng-if="model.visible" class="animated ng-enter ng-enter-active">...</div>

要素の class 属性は元に戻る。

1
<div ng-if="model.visible" class="animated">...</div>

その逆で表示から非表示になるときには、ng-enterの代わりにng-leaveng-leave-activeが class 属性に追加される。

アニメーションに対応する標準 directive

以下の AngularJS 標準 directive には、アニメーションのための処理が実装されているので、表示・非表示が切り替わるタイミングで class 属性に先述したような値(ng-enterなど)が反映される。

Directive Supported Animations
ngRepeat enter, leave, move
ngView enter, leave
ngInclude enter, leave
ngSwitch enter, leave
ngIf enter, leave
ngClass add, remove
ngShow / ngHide add, remove (ng-hide class 値)

もちろんカスタム directive でも $animate service を利用して標準 directive と同じようにアニメーションを実現できるけど、その方法についてはまた別の機会に。

ngAnimate-animate.css

最後に、animate.css を AngularJS 1.2 で利用できるようにするドライバーモジュール ngAnimate-animate.css を紹介。

animate.css とこのモジュールを使えば、class 属性に dn-fade と記述するだけでフェードのアニメーションを利用できるようになる。その他いろいろなアニメーションも class 属性に指定するだけで試せる。