HTML5 CanvasとSVGは、素晴らしいグラフィックスやビジュアルエクスペリエンスを作成するために使用できる標準ベースのHTML5技術です。この記事で尋ねている質問は以下の通りです:プロジェクトでどちらを使用すべきかという点で重要でしょうか?言い換えれば、HTML5 CanvasをSVGよりも好む使用例はあるのでしょうか?
まず、HTML5 CanvasとSVGについて少し紹介しましょう。
HTML5 Canvasとは何か?
WHATWG仕様がcanvas
要素を紹介する方法は以下の通りです:
canvas
要素は、スクリプトに解像度依存のビットマップキャンバスを提供し、グラフィックス、ゲームグラフィック、アート、またはその他のビジュアルイメージをリアルタイムにレンダリングするために使用できます。
言い換えれば、<canvas>
タグは、JavaScriptプログラマブルインターフェイスを使用してピクセル単位でイメージを作成および操作できるサーフェスを公開します。
基本的なコードサンプルは以下の通りです:
HTML:
<canvas id="myCanvas" width="800" height="800"></canvas>
JavaScript:
const canvas = document.getElementById('myCanvas');
const context = canvas.getContext('2d');
context.fillStyle = '#c00';
context.fillRect(10, 10, 100, 100);
HTML5 Canvas APIのメソッドとプロパティを利用するために、2Dコンテキストオブジェクトへの参照を取得できます。上記の例では、100 x 100ピクセルのサイズで、<canvas>
の描画サーフェスから左に10px、上に10pxの位置に単純な赤い四角形を描画しています。
解像度依存であるため、<canvas>
で作成した画像は、拡大されたりRetinaディスプレイで表示されたりすると画質が低下する可能性があります。
シンプルな図形を描くことは、ほんの序章に過ぎません。HTML5 Canvas APIを使えば、弧、パス、テキスト、グラデーションなどを描画できます。また、画像をピクセル単位で操作することも可能です。これにより、特定の領域で色を置き換えたり、描画をアニメーション化したり、さらには動画をキャンバスに描画してその外観を変えることができます。
SVGとは何か?
SVGはScalable Vector Graphicsの略です。仕様によれば:
SVGは2次元グラフィックを記述する言語です。他のXMLと混在して独立した形式であれば、XML構文を使用します。HTML5と混在する場合は、HTML5構文を使用します。…
SVGの描画はインタラクティブで動的であり、アニメーションを宣言的に定義し(つまり、SVGアニメーション要素をSVGコンテンツに埋め込む)、スクリプティングによってトリガーすることができます。
SVGは、ベクターグラフィックを作成するためのXMLファイル形式です。拡大縮小が可能なことの利点は、ベクター画像のシャープさと高品質を維持したまま、それを拡大または縮小できることです。(HTML5 Canvasで生成された画像ではこれができません。)
ここに、以前HTML5 Canvasで作成したのと同じ赤い四角形がありますが、今回はSVGを使用して描画しています:
<svg xmlns="https://www.w3.org/2000/svg" viewbox="0 0 600 600">
<desc>Red rectangle shape</desc>
<rect x="10" y="10" width="100" height="100" fill="#c00" />
</svg>
SVGでは、Canvasでできることの大部分を行うことができます。例えば、図形やパス、グラデーション、パターン、アニメーションなどです。しかし、これら2つのテクノロジーは根本的に異なる動作をします。Canvasベースのグラフィックとは異なり、SVGにはDOMがあり、それによってCSSやJavaScriptがアクセスできます。例えば、CSSを使用してSVGグラフィックの外観を変更したり、CSSやJavaScriptでそのノードをアニメートしたり、<div>
と同様にマウスやキーボードイベントに対応させることができます。以下のセクションではっきりわかるでしょうが、この違いは、CanvasとSVGのどちらを次のプロジェクトに選ぶかを決定する際に大きな役割を果たします。
インメモリモードとリテイナルモード
インメモリモードとリテイナルモードの違いを区別することが重要です。HTML5 Canvasは前者の例であり、SVGは後者の例です。
インメモリモードは、描画がキャンバスに載ったら、キャンバスはそれを追跡しなくなることを意味します。言い換えれば、開発者として、オブジェクトを描画するためのコマンドを作成し、最終出力がどのようなものであるかのモデルやシーンを作成し、維持し、何を更新する必要があるかを指定する必要があります。ブラウザのグラフィックスAPIは、単に描画コマンドをブラウザに伝え、それを実行させるだけです。
SVGは保持アプローチを使用し、画面に表示したい内容の描画指示を発行するだけで、ブラウザのグラフィックスAPIが最終出力のメモリ内モデルやシーンを作成し、ブラウザの描画コマンドに変換します。
一方、Canvasは即時グラフィックスシステムであり、DOM(文書オブジェクトモデル)を持っていません。Canvasでは、ピクセルを描画し、システムはそれらをすべて忘れてしまい、内部モデルを維持するために必要な余分なメモリを削減します。SVGでは、描画する各オブジェクトがブラウザの内部モデルに追加され、開発者としての生活を少し楽にするかもしれませんが、パフォーマンスの面でコストがかかる場合もあります。
即時モードと保持モードの区別およびCanvasとSVGのそれぞれの固有の特性に基づいて、一方の技術を他方よりもプロジェクトの目標に適している場合を示すことができます。
HTML5 Canvas: 利点と欠点
HTML5 Canvas仕様は、著者が他により適切な手段を持っている場合に<canvas>
要素を使用すべきでないことを明確に推奨しています。
例えば、グラフィックが豊富な<header>
要素の場合、最良のツールはHTMLとCSSであり、<canvas>
(そしてSVGもまたそうではありません)ではありません。Zim JS canvasフレームワークの創設者であるDr. Abstractは、この見解を確認し、次のように書いています。
DOMとDOMフレームワークは、特にテキスト情報を表示するのに優れています。対照的に、キャンバスは画像です。テキストをキャンバスに追加してリアクティブにすることはできますが、テキストをDOMのように簡単に選択したり検索したりすることはできません。長いスクロールページのテキストやテキストと画像は、DOMの優れた使用法です。DOMは、ソーシャルメディアサイト、フォーラム、ショッピング、私たちが慣れ親しんでいるすべての情報アプリに適しています。—“JavaScriptのキャンバスライブラリまたはフレームワークを使用するタイミング”
つまり、<canvas>
を使用しない例が明確に示されています。しかし、いつ<canvas>
が良い選択肢となるのでしょうか?
このSarah Drasnerのツイートは、キャンバスの機能と能力の主な利点と欠点を要約し、この強力な技術の使用ケースを考えるのに役立ちます:
I had this slide in a lot of talks and workshops over the years: pic.twitter.com/4K0C7mNzg2
— Sarah Drasner (@sarah_edo) October 2, 2019
ツイートの画像をこちらで視聴できます。
HTML5キャンバスが優れている場合
Alvin Wanは、描画されるオブジェクトの数とオブジェクトまたはキャンバス自体のサイズに関連して、キャンバスとSVGのパフォーマンスをベンチマークしました。彼は次のように結果を述べています:
要約すると、DOMレンダリングのオーバーヘッドは、数百、あるいは数千のオブジェクトを扱う場合に特に顕著であり、この状況下ではCanvasが明らかに優れています。しかし、CanvasもSVGもオブジェクトのサイズに関して不変です。最終的な評価では、Canvasはパフォーマンスにおいて明確な勝者です。
Canvasについて知っていること、特に多くのオブジェクトを描画する際の優れたパフォーマンスに基づいて、SVGよりも適切、あるいは好ましい可能性のあるいくつかのシナリオを以下に示します。
ゲームとジェネラティブアート
高度にインタラクティブなゲームやジェネラティブアートなど、グラフィックスがパワフルな、高いインタラクティブ性を持つゲーム、そしてジェネラティブアートにおいて、Canvasが一般的に選ばれる方法です。
レイトレーシング
レイトレーシングは3Dグラフィックスを作成する技法です。
レイトレーシングは、画像プレーン内のピクセルを通して光の経路を追跡し、仮想オブジェクトとの遭遇の効果をシミュレートすることで画像を活性化することができます。…レイトレーシングによって達成される効果の範囲は、…単純なベクターグラフィックスから現実的な画像を作成するから、赤目を除去する写真のようなフィルターを適用するまで変わります。— SVG vs Canvas: どちらを選ぶべきか、Microsoft Docs。
興味があるなら、Mark Websterによるレイトレーサーアプリケーションの動作をご覧ください。
しかし、HTML5 CanvasはSVGよりも明らかにこのタスクに適しているが、それがつまりレイトレーシングが<canvas>
要素で最も効果的に実行されるというわけではない。実際、CPUへの負荷はかなり大きくなり、その結果としてブラウザが応答しなくなる可能性があります。
小さな表面に多くのオブジェクトを描画
別の例は、あなたのアプリケーションが比較的小さな表面に多くのオブジェクトを描画する必要がある状況です。たとえば、天候パターンのグラフィカル表現のような非対話型リアルタイムデータ可視化などです。
上記の画像はこのMSDN記事からのもので、この記事の研究の一部でした。
動画内のピクセル置換
このHTML5 Doctorの記事で示されているように、Canvasが適切な別の例は、動画の背景色を別の色、別のシーン、または画像で置き換える場合です。
HTML5 Canvasがあまり適していない場合
一方、CanvasよりもSVGが最適な選択であるというケースもいくつかあります。
スケーラビリティ
スケーラビリティが重要な多くのシナリオでは、CanvasよりもSVGを使用する方がより適しています。建築や工学の図面、組織図、生物学の図など、高忠実度で複雑なグラフィックスがその例です。
SVGを使用して描画すると、画像を拡大したり印刷したりしても、高い品質ですべての詳細が保持されます。また、これらのドキュメントをデータベースから生成することもでき、SVGのXML形式はこのタスクに非常に適しています。
さらに、これらのグラフィックスはしばしばインタラクティブです。オンラインで航空券を予約する際の座席マップを考えてみると、それがSVGのような保持グラフィックスシステムの良い使用例であることがわかります。
そうは言っても、CreateJSやZim(CreateJSを拡張したもの)のような素晴らしいライブラリの助けを借りて、開発者は比較的迅速にマウスイベント、ヒットテスト、マルチタッチジェスチャ、ドラッグアンドドロップ機能、コントロールなどをCanvasベースの作成物に統合できます。
アクセシビリティ
Canvasのグラフィックをよりアクセシブルにするための手順があることは確かですが、Zimのような良いCanvasライブラリがここでプロセスを高速化するのに役立つ可能性がありますが、アクセシビリティに関してはCanvasは輝いていません。Canvasの表面に描画されたものはただのピクセルの集まりであり、支援技術やサーチエンジンのボットによって読み取られたり解釈されたりすることはできません。これはSVGが好まれる別の分野です: SVGは単なるXMLであり、人間も機械も読むことができます。
ジャバスクリプト非依存
アプリケーションでJavaScriptを使用したくない場合、Canvasはあなたの親友ではありません。実際、<canvas>
要素で作業する唯一の方法はJavaScriptを使用することです。逆に、Adobe IllustratorやInkscapeのような標準的なベクターエディットプログラムを使用してSVGグラフィックスを描画し、それらの外観を制御し、目を引く微妙なアニメーションやマイクロインタラクションを実行するために純粋なCSSを使用できます。
HTML5 CanvasとSVGを組み合わせて高度なシナリオを実現
アプリケーションがHTML5 CanvasとSVGを組み合わせることで両方の世界の利点を得ることができるケースがあります。たとえば、Canvasベースのゲームは、ベクターエディットプログラムによって生成されたSVG画像からスプライトを実装し、PNG画像と比較して拡大縮小可能性と小さいダウンロードサイズを活用できます。また、ペイントプログラムはSVGを使用してユーザーインターフェイスを設計し、描画に使用できる埋め込み<canvas>
要素を持つことができます。
最後に、Paper.jsのような強力なライブラリを使用すると、HTML5 Canvasの上にベクターグラフィックスをスクリプト化できるため、開発者はこれら2つの技術で作業する便利な方法を提供されます。
結論
この記事では、HTML5 CanvasとSVGのいくつかの主要な機能を探り、特定のタスクに最も適した技術を決定するのに役立つかもしれません。
答えは何ですか?
Chris CoyierはBenjamin De Cockと同意見であり、後者のツイートによると:
一つの非常に基本的な答え方は、「SVGを使えない場合にキャンバスを使用する」(ここで「使えない」とは、数千オブジェクトをアニメーション化したり、各ピクセルを個別に操作したりする場合を指す)というものです。言い換えれば、SVGをデフォルトの選択肢とし、キャンバスを補助的な計画とするべきです。
— Benjamin De Cock (@bdc) October 2, 2019
Dr Abstractは、キャンバスを使用して最適に構築されるべきものの長いリストを提示しており、インタラクティブなロゴや広告、インタラクティブなインフォグラフィックス、eラーニングアプリなどが含まれます。
私の見解では、キャンバスを使用するべきかSVGを使用するべきかに関する明確なルールはありません。即時モードと保持モードの違いから、グラフィックが多いゲームの構築にはHTML5キャンバスが最適であり、フラットイメージ、アイコン、UI要素などにはSVGが好まれるとされています。しかし、その中間にはHTML5キャンバスがさらに広がる余地があり、特に様々な強力なキャンバスライブラリが提供するものを考えると、その可能性が高まります。これらのライブラリは、両方の技術を同じグラフィック作業で扱いやすくするだけでなく、インタラクティブなコントロールやイベント、レスポンシブデザイン、アクセシビリティ機能など、ネイティブなキャンバスベースのプロジェクトで実装が難しい機能を、ほとんどの開発者にとって手の届く範囲に置くことができます。これにより、HTML5キャンバスのさらなる興味深い用途の可能性が開かれることになります。
キャンバスとSVGに関するよくある質問(FAQ)
キャンバスとSVGの主な違いは何ですか?
CanvasとSVGは、どちらもグラフィックスを作成するためのWeb技術ですが、いくつかの重要な違いがあります。Canvasはビットマップベースのアプローチであり、ピクセルで動作します。これは、ゲームや動的な視覚効果を必要とするその他のアプリケーションなど、複雑でインタラクティブなグラフィックスを作成するのに適しています。ただし、形状が描画されると、それを再描画することを除いて変更できません。一方、SVGはベクターベースのアプローチです。形状やパスで動作し、各オブジェクトは描画後も操作可能です。これにより、SVGは静的なグラフィックス、ロゴ、およびクオリティを失うことなく拡大縮小できるアイコンを作成するのに最適です。
CanvasをSVGよりも使用すべき状況とは?
Canvasは、複雑でインタラクティブで高性能なグラフィックスが必要な場合に最適です。Canvasはピクセルで動作し、個々のピクセルの直接操作を可能にするため、リアルタイムのビデオ処理や大規模データセットのレンダリングに適しています。ただし、Canvasはイベントハンドラをサポートしていないため、インタラクティビティが必要な場合は、自分で実装する必要があります。
CanvasよりもSVGを使用するべき状況とは?
SVGは、クオリティを失うことなく拡大縮小できるグラフィックス、例えばロゴやアイコンが必要な場合に最適です。SVGはイベントハンドラもサポートしており、インタラクティブなグラフィックスを作成するのが容易です。さらに、SVG要素はDOMの一部であるため、CSSでスタイルを設定したり、JavaScriptで操作したりすることができます。
CanvasとSVGを同じプロジェクトで使用することは可能ですか?
はい、CanvasとSVGを同じプロジェクトで使用することができます。実際、それぞれの強みと弱みを活かすために両方を使うことが時には有益です。例えば、複雑でインタラクティブなグラフィックスが必要な部分のプロジェクトにCanvasを使用し、拡大縮小可能な静的グラフィックスが必要な部分にSVGを使用することがあります。
CanvasとSVGのブラウザサポートはどのように比較されますか?
CanvasとSVGはともに優れたブラウザサポートを持っています。Chrome、Firefox、Safari、Edgeを含むすべての現代のブラウザでサポートされています。ただし、古いブラウザをサポートする必要がある場合は、SVGがより長く存在しているため、若干のレガシーブラウザサポートがより良いことに注意してください。
CanvasとSVGはアニメーションをどのように扱いますか?
CanvasとSVGはどちらもアニメーションを作成するために使用できますが、それらを処理する方法は異なります。Canvasでは、アニメーションの各フレームのために手動でキャンバスをクリアして再描画する必要があります。一方、SVGでは、CSSまたはJavaScriptを使用してSVG要素をアニメートできるため、より簡単かつ効率的です。
CanvasとSVGはページの読み込み時間にどのように影響しますか?
ページの読み込み時間への影響は、作成するグラフィックの複雑さとサイズによって異なります。Canvasは、各オブジェクトのDOMを維持する必要がないため、複雑でインタラクティブなグラフィックスに対して高速です。しかし、SVGは、何かが変更されるたびに全体のグラフィックを再描画する必要がないため、シンプルで静的なグラフィックに対して高速です。
CanvasとSVGでCSSを使用できますか?
SVG要素はDOMの一部であるため、他のHTML要素と同様にCSSでスタイルを設定できます。一方、Canvasはビットマップであり、CSSスタイルをサポートしていません。ただし、Canvas要素自体のスタイルを設定するためにCSSを使用できます。例えば、背景色や境界線を設定することができます。
CanvasとSVGはリスポンシビリティをどのように処理しますか?
SVGはベクタベースのフォーマットであるため、本質的にリスポンシブであり、品質を失うことなくよくスケールします。一方、Canvasはビットマップベースのフォーマットであるため、本質的にリスポンシブではありません。しかし、JavaScriptを使用してビューポートのサイズに基づいてそのサイズを調整することで、Canvasをリスポンシブにすることができます。
CanvasとSVGのどちらをプロジェクトに使用すべきか?
CanvasとSVGの選択は、プロジェクトの特定のニーズによって異なります。作成するグラフィックの複雑さやインタラクティビティ、スケーラビリティやリスポンシビリティの必要性、ブラウザサポート、そしてそれらの技術に対するあなたの快適さなどの要因を考慮してください。場合によっては、同じプロジェクト内でCanvasとSVGの両方を使用することが有益かもしれません。