この記事は、記事「JavaScript製アニメーションライブラリの原理を理解しよう」の続編となります。前回の記事ではアニメーションの基本的な仕組みと、基礎部分の実装について解説しました。
今回はより実践的に活用できる機能として、動きに深みを出す「イージング」と、演出にエフェクトを加える「CSSフィルター」のアニメーションを実装していきます。CSSコーダーの方であれば、イージングはCSS Transition
で、CSSフィルターもボタンなどの演出で馴染みがあると思います。
☞︎イージングとは
前回アニメーションとは、時間経過とともに「ある値を0(0%)〜1(100%)の間で連続して変化をさせる」と解説しましたが、例えば「最初はゆっくりで、徐々に早く変化させる」といった具合に時間経過に応じて変化の速度を調整するのが「イージング」です。
イージングには色々な種類がありますが、一般的には「easeIn~」(徐々に加速)、「easeOut~」(徐々に減速)、「easeInOut~」(加速してから減速)という名前となっています。こちらの「Easing Function 早見表」では、グラフで様々なイージングが視覚的に紹介されているのでぜひご参考ください。
今回はこのグラフの中から、非常に使い勝手のよい「easeInExpo」「easeOutExpo」「easeInOutExpo」の3つを自力で実装します。難しい印象を持つかもしれませんが、イージングの第一人者のRobert Penner氏が「Robert Penner's Easing Functions」にて文献やコードを公開されているので、ここからJavaScriptの数式を流用させてもらいます(*)。このイージングはFlashやJavaScriptのトゥイーンエンジンで広く採用され、いまやデファクトスタンダードとなっています。
※「Open Source under BSD License」のライセンスで公開されているため、著作権の表示と免責条項を明記すれば再利用・再配布が可能です。
☞︎イージングの実装方法
イージングの使用イメージとしては、イージング名を文字列で渡して実行できる形を目指します。
animateTranslate( 'mitarashi' , 1000, 'easeInOutExpo' , 500, 150, 1000); |
次は、イージング名から「イージング関数」を返す関数を作成します。switch
文の中でease
に代入される「イージング関数」は、公開さているコードからそのまま移植しています。ただ第1引数に元々あった「x
」の値については、使用しないため削除しています。
const ease = getEasing(easing); |
function getEasing(easingName) { |
ease = function (t, b, c, d) { |
return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; |
ease = function (t, b, c, d) { |
return (t == d) ? b + c: c * (-Math.pow(2, -10 * t / d) + 1) + b; |
ease = function (t, b, c, d) { |
if (t == d) return b + c; |
if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b; |
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; |
今回移植するイージング関数には、4つの引数を渡します。それぞれ、「t:アニメーションの経過時間」「b:始点」「c:変化量」「d:変化にかける時間」となっているので、必要な値を渡せばイージングを反映した結果を返してくれます。ただし、今回は変化割合(0〜1)という形で扱いたいため、進捗率のprogress
を経過時間として渡し、「始点:0」「変化量:1」「変化時間:1」とそれぞれ指定し、算出された値をprogress
の代わりに使用します。
easeProgress = ease(progress, 0, 1, 1); |
これでイージングの実装ができました。試しに「easeInOutExpo」でアニメーションさせると、等速でのっぺりした印象から、緩急のついたいい感じの動きに変わります。
次のページでは、演出をより華やかにする「CSSフィルター」のアニメーションを実装していきます。