アニメーション
技術選定
アニメーションは、アプリケーションをより魅力的にするために広く利用されています。近年のブラウザは CSS アニメーションを十分にサポートしており、高速な JavaScript ベースのアニメーションを提供する様々な ライブラリも存在します。最先端の技術を利用したい場合は、将来的な Web API とその polyfill も利用可能です。
Mithril.js は、独自のアニメーション API を提供していません。これは、上記のような他の選択肢で、リッチで複雑なアニメーションを実現するのに十分であるためです。しかし、Mithril.js は、従来アニメーションの実装が難しい特定のケースにおいて、開発を容易にするためのフックを提供します。
要素生成時のアニメーション
要素が生成される際に 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.js は、要素の削除を遅延させることができる 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;
},
},
'Toggle'
),
on ? m(FancyComponent) : null,
];
},
};
次に、削除時にフェードアウトするように FancyComponent
を修正します。
var FancyComponent = {
onbeforeremove: function (vnode) {
vnode.dom.classList.add('exit');
return new Promise(function (resolve) {
vnode.dom.addEventListener('animationend', resolve);
});
},
view: function () {
return m('.fancy', 'Hello world');
},
};
vnode.dom
は、コンポーネントのルート DOM 要素 (<div class="fancy">
) を指します。ここでは classList
API を使用して、<div class="fancy">
に exit
クラスを追加しています。
次に、animationend
イベントが発生したときに解決される Promise を返します。onbeforeremove
から Promise を返すと、Mithril.js は Promise が解決されるまで待機し、その後でのみ要素を削除します。この例では、exit アニメーションが終了するのを待ちます。
Toggler
コンポーネントをマウントすることで、enter アニメーションと exit アニメーションの両方が正しく動作することを確認できます。
m.mount(document.body, Toggler);
onbeforeremove
フックは、要素が DOM からデタッチされる際に parentNode
を失う要素に対してのみ実行されることに注意してください。この挙動は意図的なもので、ルート変更時にページ内の全ての要素に対して exit アニメーションが実行され、ユーザー体験を損なうことを防ぐためです。exit アニメーションが実行されない場合は、アニメーションコードが確実に呼び出されるように、コンポーネントツリーのできるだけ上位に onbeforeremove
ハンドラーを配置してください。
パフォーマンス
アニメーションを作成する際は、opacity
と transform
の CSS プロパティのみを使用することを推奨します。これらは最新のブラウザでハードウェアアクセラレーションに対応しており、top
、left
、width
、および height
をアニメーション化するよりも優れたパフォーマンスを発揮するためです。
また、box-shadow
プロパティや :nth-child
などのセレクタも、リソース消費が大きいため、避けることを推奨します。box-shadow
をアニメーションさせる場合は、box-shadow
を疑似要素に適用し、その要素の opacity をアニメーションさせることを検討してください。パフォーマンスに影響を与える要因としては、大きな画像や動的にスケーリングされた画像、および異なる position
値を持つオーバーラップする要素(例えば、固定要素の上に絶対配置された要素)などが挙げられます。