この記事は、記事「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」のライセンスで公開されているため、著作権の表示と免責条項を明記すれば再利用・再配布が可能です。

イージングの実装方法

イージングの使用イメージとしては、イージング名を文字列で渡して実行できる形を目指します。

// みたらしくんを1秒後に1秒かけて座標(500, 150)へ、加速〜減速しながらアニメーションさせる
animateTranslate('mitarashi', 1000, 'easeInOutExpo', 500, 150, 1000);

次は、イージング名から「イージング関数」を返す関数を作成します。switch文の中でeaseに代入される「イージング関数」は、公開さているコードからそのまま移植しています。ただ第1引数に元々あった「x」の値については、使用しないため削除しています。

const ease = getEasing(easing); // 使用するイージング関数

function getEasing(easingName) {
  let ease;
  switch (easingName) {
    case 'easeInExpo':
      ease = function (t, b, c, d) {
        return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
      }
      break;
    case 'easeOutExpo':
      ease = function (t, b, c, d) {
        return (t == d) ? b + c: c * (-Math.pow(2, -10 * t / d) + 1) + b;
      }
      break;
    case 'easeInOutExpo':
      ease = function (t, b, c, d) {
        if (t == 0) return b;
        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;
      }
      break;
  }
  return ease;
}

今回移植するイージング関数には、4つの引数を渡します。それぞれ、「t:アニメーションの経過時間」「b:始点」「c:変化量」「d:変化にかける時間」となっているので、必要な値を渡せばイージングを反映した結果を返してくれます。ただし、今回は変化割合(0〜1)という形で扱いたいため、進捗率のprogressを経過時間として渡し、「始点:0」「変化量:1」「変化時間:1」とそれぞれ指定し、算出された値をprogressの代わりに使用します。

easeProgress = ease(progress, 0, 1, 1); // 進捗率からイージング関数を通した変化割合を算出

これでイージングの実装ができました。試しに「easeInOutExpo」でアニメーションさせると、等速でのっぺりした印象から、緩急のついたいい感じの動きに変わります。

次のページでは、演出をより華やかにする「CSSフィルター」のアニメーションを実装していきます。