【JavaScript入門】ベジェ曲線の描画

 ベジェ曲線は 制御点 (control point) の位置を操作して滑らかな曲線を生成するベクター描画の代表格です。Canvas 2D API では

  • 制御点 1 つ:2 次ベジェ曲線
  • 制御点 2 つ:3 次ベジェ曲線

 をパスに追加できます。ロゴや手書き風ライン、スプライン補間など “自由曲線” を表現する際の基礎となるため、制御点と曲線の関係を視覚的に理解することが重要です。ここでは両曲線の作り方とデバッグに役立つ補助線の描き方を学びます。

1.ベジェ曲線メソッド一覧

メソッド役割主な引数
quadraticCurveTo(cx, cy, x, y)2 次ベジェ:始点 → 制御点 → 終点制御点 (cx, cy)、終点 (x, y)
bezierCurveTo(cx1, cy1, cx2, cy2, x, y)3 次ベジェ:始点 → 制御点1 → 制御点2 → 終点制御点1 (cx1, cy1)、制御点2 (cx2, cy2)、終点 (x, y)

TIPS: 曲線を “どちら側へ膨らませるか” は制御点の位置で決まります。補助線を描いて直感的に確認しながら調整すると効率的です。

2.2 次ベジェ曲線の例

ファイル名: qc_demo.html

PNGファイルのダウンロードは、ここ「checker.png」からできます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>🎯 Quadratic Bézier Demo</title>
<style>
  body{font-family:"Segoe UI",sans-serif;background:#f5fbff;text-align:center;margin:2rem}
  h1{font-size:1.8rem;margin-bottom:1rem}
  canvas{border:1px solid #666;border-radius:6px;background:url(./checker.png)}
  #msg{margin-top:.8rem;color:#00695c;font-weight:bold}
</style>
</head>
<body>
  <h1>🎯 2 次ベジェ曲線</h1>
  <canvas id="qcv" width="420" height="260"></canvas>
  <p id="msg">2 次ベジェ曲線を描画しました!</p>

<script>
(() => {
  const ctx = document.getElementById('qcv').getContext('2d');

  /* 座標 */
  const P0 = {x:  60, y:  30};   // 始点
  const CP = {x: 360, y: 130};   // 制御点
  const P1 = {x:  60, y: 230};   // 終点

  /* 本線を描画 */
  ctx.strokeStyle = '#ff7043';
  ctx.lineWidth   = 10;
  ctx.beginPath();
  ctx.moveTo(P0.x, P0.y);
  ctx.quadraticCurveTo(CP.x, CP.y, P1.x, P1.y);
  ctx.stroke();

  /* 補助線とポイント可視化 */
  ctx.strokeStyle = '#0091ea';
  ctx.lineWidth   = 2;
  ctx.beginPath();
  ctx.moveTo(P0.x, P0.y);
  ctx.lineTo(CP.x, CP.y);
  ctx.lineTo(P1.x, P1.y);
  ctx.stroke();

  ctx.fillStyle = '#d50000';
  [P0, CP, P1].forEach(p => ctx.fillRect(p.x-8, p.y-8, 16, 16));
})();
</script>
</body>
</html>

ブラウザの出力例

 オレンジ色の太い曲線が左上から右下へ弧を描き、青い補助線が始点→制御点→終点を結びます。赤い四角が 3 点の位置を示します。

プログラム解説

  • quadraticCurveTo1 つの制御点 しか取らないため、曲線は制御点を “引っ張る” ような単純な形状になります。
  • 補助線を lineWidth = 2 で描くと制御点調整時のイメージが掴みやすいです。

3.3 次ベジェ曲線の例

ファイル名: cc_demo.html

PNGファイルのダウンロードは、ここ「checker.png」からできます。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>🧩 Cubic Bézier Demo</title>
<style>
  body{font-family:"Segoe UI",sans-serif;background:#f5fbff;text-align:center;margin:2rem}
  h1{font-size:1.8rem;margin-bottom:1rem}
  canvas{border:1px solid #666;border-radius:6px;background:url(./checker.png)}
  #note{margin-top:.8rem;color:#00695c;font-weight:bold}
</style>
</head>
<body>
  <h1>🧩 3 次ベジェ曲線</h1>
  <canvas id="ccv" width="420" height="260"></canvas>
  <p id="note">3 次ベジェ曲線を描画しました!</p>

<script>
(() => {
  const ctx = document.getElementById('ccv').getContext('2d');

  /* 座標 */
  const P0  = {x:  60, y:  30};
  const CP1 = {x: 360, y:  30};
  const CP2 = {x: 360, y: 230};
  const P1  = {x:  60, y: 230};

  /* 本線を描画 */
  ctx.strokeStyle = '#7e57c2';
  ctx.lineWidth   = 10;
  ctx.beginPath();
  ctx.moveTo(P0.x, P0.y);
  ctx.bezierCurveTo(CP1.x, CP1.y, CP2.x, CP2.y, P1.x, P1.y);
  ctx.stroke();

  /* 補助線とポイント */
  ctx.strokeStyle = '#00b8d4';
  ctx.lineWidth   = 2;
  ctx.beginPath();
  ctx.moveTo(P0.x, P0.y);
  ctx.lineTo(CP1.x, CP1.y);
  ctx.lineTo(CP2.x, CP2.y);
  ctx.lineTo(P1.x, P1.y);
  ctx.stroke();

  ctx.fillStyle = '#c51162';
  [P0, CP1, CP2, P1].forEach(p => ctx.fillRect(p.x-8, p.y-8, 16, 16));
})();
</script>
</body>
</html>

ブラウザの出力例

 紫の曲線が S 字を描き、シアン色の補助折れ線が 4 点の関係を示します。赤いポイントで各座標が明示されます。

プログラム解説

  • bezierCurveTo では 2 点の制御点 が曲線の始点側/終点側の「接線」を決めます。これにより S 字や逆カーブなど複雑な形状が表現可能。
  • 補助線は P0→CP1→CP2→P1 と順に結ぶと曲線がどのように“引っ張られる”かを直感的に把握できます。

まとめ

  • 2 次ベジェ:制御点 1 つで単一方向へ膨らむシンプルな曲線。
  • 3 次ベジェ:制御点 2 つで複雑な S 字や波形を表現できる。
  • デバッグ時は 補助線と制御点の描画 が必須。見た目と数値の関係が掴みやすくなり、調整時間を大幅短縮できます。

 これらのテクニックを応用すれば、シグネチャの手書き演出、SVG パスアニメーション、ゲームのスプライン移動など、多彩な曲線表現を自在に生成できます。