アニメーション
- チュートリアル
- リソース
- 重要なコンセプト
- ソーシャル
- その他
技術の選択
アニメーションはアプリケーションのいきいきとさせるためによく利用されます。今日のブラウザはCSSアニメーションをサポートしていますし、JavaScriptベースの高速なアニメーションをサポートするさまざまなライブラリもあります。また、最先端のものが好きであれば、これから登場するWeb APIとそのpolyfillもあります。
Mithrilそのものはアニメーションのための APIを提供していませんが、これらのさまざまなライブラリを活用することで、よりリッチで複雑なアニメーションが実現できます。Mithril自身は、以前はアニメーションが扱いにくかったいくつかのケースに対して、とても簡単に扱えるようなフックを提供しています。
エレメント作成時のアニメーション
要素作成時にCSSを使って要素をアニメーションさせるのは、これ以上簡単にはできないでしょう。CSSクラスにアニメーションを追加するだけです。
.fancy {animation:fade-in 0.5s;}
@keyframes fade-in {
from {opacity:0;}
to {opacity:1;}
}
var FancyComponent = {
view: function() {
return m(".fancy", "Hello world")
}
}
m.mount(document.body, FancyComponent)
要素の削除時のアニメーション
以前のバージョンでは、要素の削除時にアニメーションさせるのは、本当の削除が行われるまで実際の削除を遅延させるというややこしい実装が必要でした。幸い、Mithril 1.0以降ではonbeforeremove
フックを提供しており、要素の削除を遅延させるのが簡単に行えるようになりました。
それではopacity
を1から0までフェードさせるexit
アニメーションを作成してみましょう。
.exit {animation:fade-out 0.5s;}
@keyframes fade-out {
from {opacity:1;}
to {opacity:0;}
}
それでは前のセクションで作成したFancyComponent
コンポーネントを表示したり隠したりするコンポーネントを作成してみましょう。
var on = true
var Toggler = {
view: function() {
return [
m("button", {onclick: function() {on = !on}}, "トグル"),
on ?m(FancyComponent) : null,
]
}
}
次に、FancyComponent
を修正し、削除時にフェードアウトさせるようにします:
var FancyComponent = {
onbeforeremove: function(vnode) {
vnode.dom.classList.add("exit")
return new Promise(function(resolve) {
setTimeout(resolve, 500)
})
},
view: function() {
return m(".fancy", "Hello world")
}
}
vnode.dom
はコンポーネントのルートとなるDOMエレメント(<div class="fancy">
)を指しています。classList APIを使って、exit
クラスを<div class="fancy">
に付与しています。
その後、0.5秒後に解決されるPromiseを返しています。onbeforeremove
からPromiseを返すと、MithrilはそのPromiseが解決されるまで要素の削除を待ちます。このサンプルでは、終了時のアニメーションが完了するのとちょうど同じ時間である0.5秒待っています。
Toggler
コンポーネントをマウントすると、作成時と終了時の両方のアニメーションが動作することが確認できます。
m.mount(document.body, Toggler)
注意点としては、onbeforeremove
フックは、DOMから要素が切り離されてparentNode
がいなくなる要素に対してのみトリガーされます。この動作は設計上意図されたものです。ラウトの変更などで、ページ上のすべての要素の終了アニメーションが実行されてしまってユーザ経験が悪化するのを防ぐためです。終了アニメーションが実行されない場合は、ツリーの上位の削除される要素にonbeforeremove
ハンドラーを移動して、アニメーションが実行されるようにしてください。
パフォーマンス
アニメーションを作成する場合は、opacity
とtransform
のCSSルールだけを使うことをおすすめします。現代のブラウザであればハードウェアアクセラレーションが行えるため、top
、left
、width
、height
を操作するよりも良いパフォーマンスが得られます。
また、box-shadow
ルールや、:nth-child
などのセレクターを使うとパフォーマンスに大きな影響があります。もしbox-shadow
をアニメーションさせたいのであれば、疑似要素にbox-shadow
のルールを適用し、その疑似要素のopacityをアニメーションさせる方法を検討してください。それ以外では巨大な画像を使ったり、ダイナミックに画像をスケールさせたり、position
の値が異なる要素同士のオーバーラップ(fixedに対してabsoluteが重なる)も高コストになります。
License: MIT. © Leo Horie.