ngAnimateでclass属性の変更のフックをつかったアニメーションをやってみた

こんにちは。久しぶりに背脂チャッチャ系らーめんを食べて、テンションがあがっているきたけーです。

AngularJS で class属性の変更のフックをつかったアニメーションをやってみたのでメモ。

ngAnimate

アニメーション用のモジュールが公式であるのでそれを使います。

インストール

bower install angular-animate --save

class属性の変更のフック

基本はCSSアニメーションで、class属性※の変更をフックして、アニメーション用のclassをclass属性の値として追加します。 たとえば、expandがclass属性に追加された場合を例にすると

  • expand-add 追加されたときのアニメーションを定義する(元の値に-addが付いている)
  • expand-add-active ↑のアニメーションをトリガーする。expandが追加された場合に到達するスタイルを定義する(元の値に-add-activeが付いている)

逆にexpandが除かれた場合は

  • expand-remove 除かれたときのアニメーションを定義する(元の値に-removeが付いている)
  • expand-remove-active ↑のアニメーションをトリガーする。expandが除かれた場合に到達するスタイルを定義する(元の値に-remove-activeが付いている)

というかんじです。

※ ただし、class属性にAngular式 あるいは ng-classディレクティブを使っている要素に限る

お題: マウスオーバーしたら展開して、リーブしたら閉じるサイドメニュー

↑の説明を踏まえて、マウスオーバーしたら展開して、リーブしたら閉じるサイドメニューを実装してみます。こんなかんじです。

HTML

<!DOCTYPE html>
<html lang="ja" ng-app="App">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="./app.css">
  <script src="./bower_components/angular/angular.js"></script>
  <script src="./bower_components/angular-animate/angular-animate.js"></script>
  <script src="./app.js"></script>
  <title></title>
</head>
<body ng-controller="SidemenuController">
  <div ng-class="expandedMenu ? 'expand' : ''" class="sidemenu" ng-mouseover="expandedMenu = true" ng-mouseleave="expandedMenu = false">
  </div>
</body>
</html>

CSS

.sidemenu {
  top: 0;
  position: fixed;
  z-index: 1000;
  width: 314px;
  height: 100%;
  left: -280px;
  background-color: #333;
}

/* expandが追加、削除されたときのアニメーションの定義 */
.sidemenu.expand-add,
.sidemenu.expand-remove {
  -webkit-transition: left linear 0.5s;
  -moz-transition: left linear 0.5s;
  -o-transition: left linear 0.5s;
  transition: left linear 0.5s;
}

/* expandが追加されたときのアニメーションの到達結果とトリガー */
.sidemenu.expand,
.sidemenu.expand-add.expand-add-active {
  left: 0px;
}

/* expandが除かれたときのアニメーションの到達結果とトリガー */
.sidemenu.expand-remove.expand-remove-active {
  left: -280px;
}

JavaScript

var App = angular.module('App', ['ngAnimate']);

App.controller('SidemenuController', ['$scope', function ($scope) {
  $scope.expandedMenu = false;
}]);

うごかしてみる

f:id:kitak:20141103185457g:plain

ぼやき

ngAnimate、リストの追加とか並び替え時のアニメーションなど他にもたくさん機能があるようなので( refs: https://docs.angularjs.org/guide/animations )、もうちょい掘り下げてみる。