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

CSS のイージング関数である linear() が導入され、地点間を直線的に補間して、跳ねる効果とばねの効果を再現できるようになりました。

CSS のイージング

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

CSS には、lineareaseease-inease-outease-in-out の複数のキーワードがプリセットとして用意されています。独自のイージング カーブを作成するには、cubic-bezier() 関数を使用するか、steps() イージング関数を使用してステップベースのアプローチを行います。

イージングを適切に使用すると、アニメーション要素に勢いがついたように見えるため、重み感が生まれます。

CSS ではバウンス効果やばね効果などの複雑な曲線を作成することはできませんが、linear() のおかげで驚くほどうまく近似できるようになりました。

linear() の概要

対応ブラウザ

  • 113
  • 113
  • 112
  • 17.2

CSS でイージングを定義する新たな方法として、linear() があります。この関数には、カンマで区切った複数の停車地を指定できます。各停車地は 0 ~ 1 の範囲の 1 つの数字です。各停車地の間では、関数名を説明する線形な補間が行われます。

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

デフォルトでは、停車地は等間隔に散らばっています。上記のスニペットでは、0.25 の出力値が 50% の箇所で使用されるということです。

linear(0, 0.25, 1) のグラフを可視化すると、次のようになります。

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

経由地を等間隔にする場合は、停車地の長さを任意で渡すことができます。停車地の長さとして 1 つの値を渡す場合は、その始点を定義します。

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

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

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

経由地の長さとして 2 つの値を指定する場合は、その始点と終点の両方を定義します。

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

25% から 75% の時間で 0.25 の出力値が使用されます。

線形(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() を使用して簡素化された曲線を出力します。スライダーを使用して、必要な停車地の数と精度をコントロールします。

右上では、[Spring]、[Bounce]、[Simple elastic]、[Material Design でイージングが強調されている] のいずれかのプリセットを選択することもできます。

DevTools のサポート

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

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

この DevTools 機能は、Chrome 114 でリリースされる DevTools で利用できます。

写真撮影: Howie Mapson(出典: Unsplash