Oh MyUtils

CSS Cubic Bezierジェネレーター - イージング関数をオンラインで作成

インタラクティブなビジュアルエディターでカスタムCSSイージングカーブを作成。コントロールポイントをドラッグし、アニメーションをプレビューし、cubic-bezier()コードをコピーできます。

よくある質問

CSS cubic-bezier()関数とは何ですか?

CSS cubic-bezier()関数は、CSSトランジションやアニメーションのペースを制御する3次ベジェイージングカーブを定義します。4つの数値パラメータ — cubic-bezier(x1, y1, x2, y2) — を取り、X軸が時間の進行(0から1)、Y軸がアニメーションの進行(0から1)を表すカーブ上の2つの制御点(P1とP2)を定義します。始点P0は常に(0,0)、終点P3は常に(1,1)です。制御点を調整することで、アニメーションの加速、減速、オーバーシュートの仕方を決定します。

このcubic-bezierジェネレーターの使い方は?

インタラクティブグラフ上の2つのコントロールポイントハンドル(P1、P2)をドラッグして希望のイージングカーブを形成するか、X1、Y1、X2、Y2入力フィールドに正確な数値を入力してください。アニメーションプレビューがリアルタイムで更新されます。プリセットライブラリから開始点を選択することもできます。「Linearと比較」トグルで等速運動との違いを確認できます。生成されたCSSコードをコピーボタンでコピーしてください。

データは安全ですか?サーバーに送信されますか?

はい、完全に安全です。このツールはクライアントサイドJavaScriptを使用してブラウザ内で完全に実行されます。ベジェ値、アニメーション設定、その他いかなるデータもサーバーに送信されません。すべてのカーブ計算、アニメーションレンダリング、コード生成はお使いのデバイスでローカルに行われます。独自のデザインシステム作業にも安心してご使用いただけます。

cubic-bezier()のXとYの値は何を意味しますか?

4つの値は2Dグラフ上の2つの制御点を定義します。X値(x1とx2)は時間軸上の点を表し、0から1の間でなければなりません。Y値(y1とy2)は進行軸上の点を表し、任意の数値が可能です。Y値が0から1の間にある場合、アニメーションは正常に進行します。Y値が0未満または1を超える場合、アニメーションは一時的に目標状態をオーバーシュートまたはアンダーシュートし、バウンスや弾性効果を生み出します。

ease、ease-in、ease-out、ease-in-outの違いは?

これらは特定のcubic-bezier値に対応するCSSキーワードです。ease(0.25, 0.1, 0.25, 1)はわずかにゆっくり始まり、素早く加速し、滑らかに減速します — CSSトランジションのデフォルトです。ease-in(0.42, 0, 1, 1)はゆっくり始まり加速し、画面を離れる要素に便利です。ease-out(0, 0, 0.58, 1)は速く始まり減速し、画面に入る要素に最適です。ease-in-out(0.42, 0, 0.58, 1)はゆっくり始まり、中間で加速し、再び減速します。

オーバーシュートやバウンス効果の作り方は?

Y値(y1またはy2)を[0, 1]の範囲外に設定します。終わりのオーバーシュート(要素が目標を超えてから戻る)にはy2を1より大きく設定します。例えばcubic-bezier(0.34, 1.56, 0.64, 1)です。始まりのアンダーシュート(要素が前進する前に一瞬後退する)にはy1を0未満に設定します。ジェネレーターのグラフはこれらのオーバーシュートゾーンを表示するために0-1ボックスの外側まで視覚的に拡張されます。

どのイージングカーブを使うべきですか?

最適なイージングはアニメーションのコンテキストによります。UI表示(モーダル、ドロップダウンの出現)には自然な減速のためease-outまたはQuart/Quint Outカーブを使用してください。UI退出(要素の消失)にはスムーズな加速のためease-inを使用してください。状態変更(色の変化、サイズ調整)にはease-in-outがバランスの取れた加速を提供します。遊び心のあるインタラクション(ボタンフィードバック)にはBack Outカーブで微妙なオーバーシュートを加えてください。ほとんどのUIアニメーションではlinearは機械的に感じるため避けてください。

コード例

function evaluateBezier(t, p0, p1, p2, p3) {
  const u = 1 - t;
  return u * u * u * p0 + 3 * u * u * t * p1 + 3 * u * t * t * p2 + t * t * t * p3;
}

function cubicBezierY(x, x1, y1, x2, y2) {
  if (x <= 0) return 0;
  if (x >= 1) return 1;
  let low = 0, high = 1, mid;
  for (let i = 0; i < 20; i++) {
    mid = (low + high) / 2;
    const cx = evaluateBezier(mid, 0, x1, x2, 1);
    if (Math.abs(cx - x) < 0.0001) break;
    cx < x ? (low = mid) : (high = mid);
  }
  return evaluateBezier((low + high) / 2, 0, y1, y2, 1);
}

function formatCubicBezier(x1, y1, x2, y2) {
  const r = (n) => Math.round(n * 100) / 100;
  return `cubic-bezier(${r(x1)}, ${r(y1)}, ${r(x2)}, ${r(y2)})`;
}

console.log(formatCubicBezier(0.25, 0.1, 0.25, 1));
// cubic-bezier(0.25, 0.1, 0.25, 1)

// Animate using the bezier curve
function animate(x1, y1, x2, y2, durationMs, onProgress) {
  const start = performance.now();
  function tick(now) {
    const t = Math.min((now - start) / durationMs, 1);
    onProgress(cubicBezierY(t, x1, y1, x2, y2));
    if (t < 1) requestAnimationFrame(tick);
  }
  requestAnimationFrame(tick);
}

関連ツール