0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Webページの描画方式を比較する ~ CSS・SVG・Canvasの使い分け ~

0
Posted at

はじめに

Webページで次のような図形を表示するには、どのような方法があるでしょうか。

  • ボタンやカードのような四角形
  • 円や線を組み合わせた図解
  • 拡大・縮小できる地図
  • 大量の点を表示するグラフ
  • ブラウザ上で動くゲーム

代表的な方法として、次の3つがあります。

  • CSS:HTML要素を装飾して表現する
  • SVG:図形を要素として追加する
  • Canvas:描画領域に図形を描き込む

どれも画面に図形を表示できますが、得意なことやプログラムからの操作方法が異なります。

本記事では、それぞれの特徴と使い分けを解説します。

Webページで図形を描く

まずは、今回比較する3つの方法を確認します。
円を書く例で見ていきます。

CSSで描く

<div class="circle"></div>
.circle {
  width: 100px;
  height: 100px;
  background-color: tomato;
  border-radius: 50%;
}

CSSの特徴

CSSの最大の特徴は、Webページの部品を作る仕組みをそのまま利用できることです。

CSSはWebページの部品や簡単な図形を表現する場合に向いています。

  • ボタンやカード
  • 円形のアイコン背景
  • 進捗状況を表すバー
  • 簡単な装飾やアニメーション
  • 吹き出しやラベル

また、HTML要素なので、クリックイベントやキーボード操作など、通常のWebページと同じ仕組みを利用できます。

一方、複雑な図形を作ろうとすると、HTML要素やCSSの指定が増えてしまいます。

SVGで描く

<svg width="200" height="150" viewBox="0 0 200 150">
  <circle cx="100" cy="75" r="40" fill="tomato" />
</svg>

SVGでは、図形を座標で表現するため、表示領域の大きさを変更しても、元の図形の形状を保ったまま拡大・縮小できます。

SVGの特徴

SVGはHTML要素と同じようにDOMの一部として扱われるため、JavaScriptから操作できます。

SVGは個々の図形を識別したり、操作したりする必要がある場合に向いています。

  • アイコンやロゴ
  • フローチャート
  • 図解や模式図
  • グラフ
  • クリックや選択が必要な図形

ただし、大量の図形を個別の要素として生成すると、DOMの管理や更新に負荷がかかる場合があります。

Canvasで描く

<canvas id="myCanvas" width="200" height="150">
</canvas>

<script>
  const canvas = document.getElementById("myCanvas");
  const ctx = canvas.getContext("2d");

  ctx.fillStyle = "tomato";
  ctx.beginPath();
  ctx.arc(100, 75, 40, 0, Math.PI * 2);
  ctx.fill();
</script>

Canvasの特徴

Canvasでは描画した円が独立したDOM要素として保存されるわけではありません。

Canvasに円を描いた後、JavaScriptから「2番目に描いた円の色を変更する」といった操作を直接行うことはできません。

個々の図形を操作したい場合は、座標や色などの情報をJavaScript側で管理し、必要に応じて描画し直します。

一見すると不便ですが、この仕組みには利点もあります。

大量の図形を描く場合、図形ごとにDOM要素を生成する必要がありません。
また、描画領域全体を更新する処理も実装できます。

Canvasは描画領域全体を効率よく更新したい場合に向いています。

  • ブラウザ上のゲーム
  • 動的なグラフ
  • 画像処理
  • 大量の点や線の描画
  • アニメーション
  • 手書き入力やペイントツール

ただし、Canvasだから必ず高速というわけではありません。描画する図形の数や複雑さ、更新方法によって性能は変わります。

比較

CSS・SVG・Canvasの基本的な仕組みを確認しました。
ここからは、実際の開発で気になるポイントを比較します。

図形をクリックしたときの違い

画面に円を表示し、クリックすると色が変わる機能を考えます。
CSS、SVG、Canvasでは、それぞれ実装方法が異なります。

CSSの場合

HTML要素にクリックイベントを設定します。

<div id="circle" class="circle"></div>

<script>
  document.getElementById("circle")
    .addEventListener("click", event => {
      event.currentTarget.style.backgroundColor = "royalblue";
    });
</script>

SVGの場合

円そのものにイベントを設定できます。

<svg width="200" height="150" viewBox="0 0 200 150">
  <circle id="target" cx="100" cy="75" r="40" fill="tomato" />
</svg>

<script>
  const circle = document.getElementById("target");

  circle.addEventListener("click", () => {
    circle.setAttribute("fill", "royalblue");
  });
</script>

Canvasの場合

Canvasでは、クリックされた座標を取得し、その座標に図形が存在するかを判定する必要があります。

単純な円なら、次のような計算で判定できます。

const dx = mouseX - circleX;
const dy = mouseY - circleY;

const distance = Math.sqrt(dx * dx + dy * dy);

if (distance <= radius) {
  // 円がクリックされた
}

mouseX と mouseY はクリック位置、circleX と circleY は円の中心座標、radius は円の半径です。

クリック位置と円の中心との距離が半径以下なら、円の内側をクリックしたと判定できます。

実際には、Canvas上の表示座標と内部座標の変換、複数図形の重なり、拡大・縮小なども考慮する必要があります。

比較結果

項目 CSS SVG Canvas
クリック対象 HTML要素 図形要素 描画領域
図形の特定 要素を取得 要素を取得 座標などから判定
色の変更 CSSを変更 属性を変更 再描画する
実装の分かりやすさ 簡単 簡単 自前の管理が必要

図形を個別にクリックしたい場合は、CSSやSVGが扱いやすいです。

拡大・縮小したときの違い

次に、図形を拡大・縮小した場合を考えます。
表示サイズを2倍する例です。

CSSの場合

CSSでは、transform: scale() などを使って要素を拡大・縮小できます。

.circle {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background-color: tomato;
  transform: scale(2);
}

CSSによる拡大・縮小は簡単ですが、複雑な図形を拡大しながら、その内部の座標や線の太さなども管理したい場合には、別途設計が必要になります。

SVGの場合

SVGでは、viewBox を利用して内部座標と表示領域の関係を指定できます。

<svg width="200" height="200" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="30" fill="tomato" />
</svg>

SVGはベクター形式なので、拡大・縮小しても図形の輪郭を鮮明に保ちやすいという特徴があります。

Canvasの場合

Canvasでは、描画時に座標変換を適用できます。

ctx.scale(2, 2);

ctx.fillStyle = "tomato";
ctx.beginPath();
ctx.arc(50, 50, 30, 0, Math.PI * 2);
ctx.fill();

内部の描画解像度を変えずに表示だけを大きくすると、輪郭が粗くなることがあります。
高解像度で描き直すことで画質を改善できますが、メモリや描画処理とのバランスを考える必要があります。

比較結果

項目 CSS SVG Canvas
拡大・縮小 得意 得意 可能
輪郭の鮮明さ 通常は良好 良好 解像度に依存
再描画の管理 ブラウザが担当 ブラウザが担当 必要に応じて自前で実装

SVGは拡大・縮小してもベクターとして描画できる一方、Canvasでは描画解像度の管理が重要になります。

大量の図形を描画する場合

大量の図形を描画するケースを考えます。
10万個の点を表示する例です。

CSSの場合

要素数が増えると、DOMの管理やレイアウト、スタイル計算などの負荷が問題になる場合があります。

CSS自体が遅いというよりも、大量のHTML要素を管理する構成が負担になりやすいと考えるとよいでしょう。

SVGの場合

ただし、図形の数が増えるほどDOMが大きくなり、生成・更新・イベント管理などの負荷が増えます。

すべての図形を常に表示する必要があるのか、画面に表示される範囲だけを描画するのか、といった工夫が重要です。

Canvasの場合

図形ごとにDOM要素を生成しなくてよいため、大量の単純な図形を描画する用途では有力な選択肢になります。

ただし、10万個の図形を毎フレーム描き直すような処理では、Canvasでも負荷が高くなります。
描画範囲の限定、不要な再描画の削減、描画処理の最適化などが重要です。

比較結果

項目 CSS SVG Canvas
大量の図形 DOM管理に注意 DOM管理に注意 有力な選択肢
個別の操作 得意 得意 自前の管理が必要
描画更新 要素の状態を変更 要素の状態を変更 再描画する設計が多い
性能の決まり方 要素数やレイアウトなど 要素数や描画内容など 描画回数や描画内容など

図形の種類、更新頻度、クリック判定、ブラウザや端末の性能などによって結果は変わります。

どの方式を選ぶべきか

ここまでの内容を整理すると、次のようになります。

やりたいこと おすすめの方式 理由
ボタンやカードを作る CSS HTML要素と組み合わせやすい
円や四角形を装飾として表示する CSS 簡単に実装できる
アイコンやロゴを作る SVG 拡大しても鮮明
フローチャートを作る SVG 図形ごとの管理がしやすい
クリック可能な地図を作る SVG 図形ごとのイベントを設定しやすい
大量の点を表示する Canvas DOM要素を大量に生成せず描画できる
ペイントツールを作る Canvas 描画領域全体を更新する用途に向く
ブラウザゲームを作る Canvas ゲームの描画処理に向く

これはあくまで目安です。

すべてを1つの方法で実装する必要はありません。

  • 背景はCanvasで描画する
  • 操作用の図形はSVGで描画する
  • 検索条件やボタンなどはCSSで作る

このように、複数の方式を組み合わせる設計も考えられます。

実際の開発では、描画性能だけでなく、操作性、保守性、実装コストも含めて判断することが大切です。

おわりに

今回は、Webページで図形を描画する方法として、CSS・SVG・Canvasを比較しました。

それぞれの特徴を簡単に振り返ります。

  • CSS:Webページの部品や簡単な図形を作る
  • SVG:図形を個別に管理し、拡大・縮小や操作を行う
  • Canvas:描画領域に図形を描き込み、動的な描画を行う

大切なのは、どれか一つが常に優れているわけではないということです。

  • 何を表示したいのか
  • 個々の図形を操作する必要があるのか
  • どれくらいのデータ量を扱うのか

この3点を整理すると、描画方式を選びやすくなります。

Webページで図形を扱う際には、ぜひ今回紹介した特徴を参考にしてみてください。


おまけ

WebGL・WebGPUという選択肢

CSS・SVG・Canvasの3つを比較してきました。
しかし、大量の図形や3Dデータを扱う場合には、もう一つ知っておきたい技術があります。

それがWebGLとWebGPUです。

WebGLとは

WebGLはWebブラウザ上でGPUを利用してグラフィックスを描画するためのAPIです。

WebGLを利用すると、次のようなものをブラウザ上で描画できます。

  • 3Dモデル
  • 地形や建物の3D表示
  • 大量の点群データ
  • 3Dゲーム

Canvas 2Dでも大量の点を描画できますが、3D表示やGPUを活用した高度な描画ではWebGLが有力な選択肢になります。

WebGPUとは

WebGPUは、GPUを利用するための比較的新しいWeb APIです。
高度なグラフィックス描画だけでなく、GPUによる計算処理も視野に入れた設計になっています。

どこから検討すべきか

最初からWebGLやWebGPUを使うのではなく、必要な機能やデータ量に応じて段階的に検討するとよいでしょう。

  1. 通常のWebページの部品ならCSS
  2. 個別に操作する図形ならSVG
  3. 動的な描画や大量の図形ならCanvas
  4. 高度な3D描画やGPU活用が必要ならWebGL・WebGPU
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?