イージング

Easing別名:イージング関数、タイミング関数、緩急

概要

動きの始まりと終わりに、加速や減速を付けること。経過時間に対して進み具合をどう配分するかを、0 から 1 への曲線(イージング関数)で決める。等速の動きより、重さや勢いのある自然な動きに見える。

デモ

デモを読み込んでいます
上段は等速、下段は選んだイージングで、同じ時間をかけて同じ距離を動きます。玉の下の印は、一定の時間ごとの位置です。印の間隔が広いところほど速く動いています。

使われる場面

  • UI のアニメーション

    メニューの開閉、画面の切り替え、ボタンを押したときの反応に付ける。現れる動きには減速(ease-out)、去る動きには加速(ease-in)を使うことが多い。

  • キャラクターアニメーション

    キーフレームのあいだの補間に緩急を付け、振りかぶりや着地の重さを表す。手描きのアニメーションで、原画の近くほど中割りの間隔を詰めて描くのと同じ考え方である。

  • カメラの移動

    カメラが動き出すときと止まるときに緩急を付け、急な発進や急停止による違和感を減らす。

  • ゲームの演出

    ダメージの数字が弾む動き、アイテムが吸い込まれる動き、画面の揺れの収まり方に、オーバーシュートやバウンドの曲線を使う。

判断基準

こういうときこうする
画面に入ってくる、または動いて止まるease-out を使う。素早く動き出して目的地で減速するので、反応が速く見え、止まる位置も目で追える。
画面から出ていく、消えるease-in を使う。ゆっくり動き出して加速し、勢いのまま去る。
画面の中で、ある位置から別の位置へ移るease-in-out を使う。動き出しと止まりの両方がなめらかになる。
弾力や勢いを強調したい(ポップアップ、通知、ゲームの演出)オーバーシュートやバウンドを使う。多用すると落ち着きのない印象になるので、目立たせたい動きに絞る。
一定の速さで続く動き(回り続ける読み込み表示、流れ続ける背景)リニアを使う。繰り返す動きに緩急を付けると、周期ごとに速さが脈打って見える。

こう見えたら

  • 動きが機械的で、ぴたっと止まる動き
  • 動き出しが急で、重さが感じられない動き
  • 回り続ける動きが、周期ごとに脈打つ動き

指示の例

  • メニューの開き方が機械的に見える。ease-out にして、素早く動き出してゆっくり止まるようにして

  • 画面から消える動きがもたつく。ease-in にして、加速しながら去るようにして

  • 通知の出方を少し弾ませたい。0.3 秒くらいで、少し行き過ぎて戻るオーバーシュートの曲線にして

  • 読み込み中の回転表示が脈打って見える。イージングを外して、等速(リニア)にして

詳細

進み具合を時間の関数として決める

動きを作るとき、始点と終点の位置、かかる時間を決めれば、あいだの位置は補間で求まる。経過時間を 0〜1 に正規化した値を tt、始点から終点までの進み具合を 0〜1 で表した値を pp とすると、等速の動きは p=tp = t である。イージングは、この tt から pp への対応を、直線ではない曲線 p=f(t)p = f(t) に置き換える。f(0)=0f(0) = 0 と f(1)=1f(1) = 1 を満たせば、始点と終点は変わらず、途中の速さの配分だけが変わる。

x(t)=x0+(x1−x0) f(t)x(t) = x_0 + (x_1 - x_0)\, f(t)

グラフの傾き f′(t)f'(t) が、その瞬間の速さにあたる。傾きが小さいところでは少ししか進まず、大きいところでは一気に進む。デモの玉の下に並ぶ印は、この傾きを位置の間隔として見えるようにしたものである。

代表的な曲線

  • ease-in:f(t)=t3f(t) = t^3 のように、始めの傾きが 0 になる。ゆっくり動き出して加速する。
  • ease-out:f(t)=1−(1−t)3f(t) = 1 - (1 - t)^3 のように、終わりの傾きが 0 になる。速く動き出し、減速して止まる。
  • ease-in-out:前半を ease-in、後半を ease-out にしたもの。
  • オーバーシュート:途中で f(t)f(t) が 1 を超え、終点を行き過ぎてから戻る。
  • バウンド:終点に当たって跳ね返る動きを、放物線をつないで近似したもの。

多くの環境では、イージングを 3 次ベジェ曲線で指定する。両端を (0,0)(0, 0) と (1,1)(1, 1) に固定し、残る二つの制御点で曲線の形を決める方式で、CSS の cubic-bezier() もこれにあたる。

// 3 次の ease-in-out
const easeInOut = (t) => (t < 0.5 ? 4 * t ** 3 : 1 - (-2 * t + 2) ** 3 / 2);

const p = easeInOut(elapsed / duration); // 0〜1 の進み具合
x = x0 + (x1 - x0) * p;

見分け方と落とし穴

等速の動きは、始まりで急に動き出し、終わりでぴたりと止まるので、機械的に見える。コマごとの位置を並べたとき、間隔が一定なら等速、端に向かって詰まっていればイージングがかかっている。

イージングは速さの配分を変えるだけで、かかる時間は変わらない。端をゆっくり動くぶん、中央では等速より速く動き、3 次の ease-in-out では中央の速さが等速の 3 倍になる。長い距離を短い時間で動かすと、中央の速さが目で追えないほどになることがあるので、移動距離に応じて時間も調整する。

オーバーシュートの曲線では、f(t)f(t) が 0〜1 の範囲の外に出る。この値で透明度や色を補間すると範囲外の値になり、表示が崩れることがある。位置や大きさに使うか、値を 0〜1 に制限してから使う。

関連