CSS で linear() イージング関数を使用して複雑なアニメーション曲線を作成する

linear() を導入しました。これは、ポイント間で線形に補間する CSS の減衰関数で、バウンス エフェクトやスプリング エフェクトを再現できます。

CSS でのイージング

CSS で要素をアニメーション化または遷移する場合は、animation-timing-function プロパティと transition-timing-function プロパティを使用して、イージング関数で値の変化率を制御します。

CSS では、lineareaseease-inease-outease-in-out などのキーワードをプリセットとして使用できます。独自の減衰カーブを作成するには、cubic-bezier() 関数を使用します。または、steps() 減衰関数を使用してステップベースのアプローチを使用します。

適切に使用すると、アニメーション要素に重みを与え、勢いを増しているように見せることができます。

バウンスやスプリング エフェクトなどの複雑なカーブは CSS では作成できませんが、linear() を使用すると、驚くほど正確に近似できます。

linear() の概要

対応ブラウザ

  • Chrome: 113。
  • Edge: 113.
  • Firefox: 112。
  • Safari: 17.2。

CSS でイージングを定義する新しい方法として、linear() があります。この関数は、カンマ区切りで複数の停留所を指定できます。各停留所は 0 ~ 1 の単一の数値です。各停留所の間では、関数の名前を説明するリニアな方法で補間が行われます。

animation-timing-function: linear(0, 0.25, 1);

これらの停留所は、デフォルトでは等間隔に配置されます。上記のスニペットでは、50% の時点で 0.25 の出力値が使用されます。

linear(0, 0.25, 1) のグラフは次のようになります。

linear(0, 0.25, 1) のグラフ可視化。

停留所を等間隔に配置しない場合は、必要に応じて停留所の長さを渡します。1 つの値を停止時間として渡す場合は、その開始点を定義します。

animation-timing-function: linear(0, 0.25 75%, 1);

ここで、0.25 の出力値は 50% マークではなく 75% で使用されます。

linear(0, 0.25 75%, 1) のグラフ可視化。

2 つの値を停留所の長さとして指定する場合は、開始点と終了点の両方を定義します。

animation-timing-function: linear(0, 0.25 25% 75%, 1);

出力値 0.25 は、時間の 25% ~ 75% で使用されます。

linear(0, 0.25 25% 75%, 1) のグラフ可視化。

linear() を使用して複雑な曲線を作成する

上記の例は非常に単純なイージングですが、linear() を使用すると、精度が低下するという妥協点はあるものの、複雑なイージング関数を非常にシンプルな方法で再作成できます。

たとえば、以下のバウンス イージング カーブは、CSS では直接表現できないイージング カーブの一種で、JavaScript を使用して定義されます。

function easing(pos) {
  const t = 7.5625;
  const e = 2.75;
  return pos < 1 / e
    ? t * pos * pos
    : pos < 2 / e
    ? t * (pos -= 1.5 / e) * pos + 0.75
    : pos < 2.5 / e
    ? t * (pos -= 2.25 / e) * pos + 0.9375
    : t * (pos -= 2.625 / e) * pos + 0.984375;
}

コードだけでは判断できないことも、ビジュアリゼーションによって判断できる場合があります。出力は青い曲線として可視化されます。

青色で描画された滑らかなバウンス曲線。

カーブは、複数の停留所を追加することで簡素化できます。緑色のドットは停留所を表しています。

青色の滑らかなバウンス曲線に緑色のドットが重ねて表示されています。

linear() に渡すと、元の曲線に似ていますが、エッジが少し粗い曲線になります。

元の滑らかな曲線(青色)の上に、簡素化された曲線(緑色)を重ねた図。

緑色のアニメーション ボックスと青色のボックスを比較すると、緑色のボックスの方がスムーズではありません。

ただし、十分なストップを追加すると、元の曲線をかなり正確に近似できます。更新版は次のとおりです。

更新されたカーブ。停留所の数は 2 倍になっています。

ストップの数を 2 倍にすると、すでにスムーズな結果が得られます。

アニメーションに使用されるコードは次のようになります。

animation-timing-function: linear(
  /* Start to 1st bounce */
  0, 0.004, 0.016, 0.035, 0.063 9.1%, 0.141, 0.25, 0.391, 0.563, 0.765, 1,
  /* 1st to 2nd bounce */
  0.891, 0.813 45.5%, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785, 0.813 63.6%, 0.891, 1 72.7%,
  /* 2nd to 3rd bounce */
  0.973, 0.953, 0.941, 0.938, 0.941, 0.953, 0.973, 1,
  /* 3rd bounce to end */
  0.988, 0.984, 0.988, 1
);

役立つツール

この停留所リストを手動で作成するのは非常に手間がかかります。幸い、JakeAdam が、イージング カーブを linear() に対応するカーブに変換するためのツールを作成しています。

リニア イージング生成ツールのスクリーンショット。
https://linear-easing-generator.netlify.app/ の使用中のスクリーンショット。

このツールは、JavaScript イージング関数または SVG カーブを入力として取り、linear() を使用して簡素化されたカーブを出力します。スライダーを使用して、必要な停留所の数と精度を調整します。

右上にあるプリセットから、[スプリング]、[バウンス]、[シンプルな弾性]、[マテリアル デザインの強調イージング] のいずれかを選択することもできます。

DevTools のサポート

DevTools では、linear() の結果を可視化して編集できます。アイコンをクリックすると、停留所をドラッグできるインタラクティブなツールチップが表示されます。

Chrome DevTools の「linear()」エディタのスクリーンショット。
Chrome DevTools の「linear()」エディタのスクリーンショット。

この DevTools 機能は、Chrome 114 に同梱されている DevTools で利用できます。

写真提供: Howie MapsonUnsplash