🖼️

【Web標準】CSSとCanvasの狭間としてのSVG

2024/12/10に公開

この記事はteam411 Advent Calendar 2024アドベントカレンダーの9日目です。

昨日はluuguasさんの「Docker+Poetry+GitでPythonの開発環境を構築しよう」でした。team411の多くのプロジェクトで使われている構成なので、このようなノウハウをまとめた記事はとてもありがたいですね。

SVGとは

SVGは、一般にベクター画像形式の1つとして認識されることが多いですが、実はWebでのレンダリングに特化しているという一面があります。

スケーラブルベクターグラフィック (SVG) は XML ベースのマークアップ言語で、二次元ベースのベクターグラフィックを記述します。

そのため、テキストベースで、どんなサイズでもきれいにレンダリングできる画像を記述するためのオープンなウェブ標準であり、特に CSS、DOM、JavaScript、SMIL を含む他のウェブ標準とうまく動作するように設計されています。 SVG は本質的に、テキストに対する HTML のような位置づけの、グラフィックに対するものです。
(出典: MDN Web Docs)

上記の通り、SVGはWeb標準として位置づけられており、HTMLやCSSと同じように、Webページ上で利用できます。また、HTMLに組み込み可能なXML形式で、記述もシンプルなため、JavaScriptと連携した動的な描画も可能です。
次の例ではボタンを押した時にアニメーションするようなSVGを描画しています。

なぜWeb標準がいいの?

最近はRemixの登場などによりWeb標準が再注目されています。Web標準の指向に準拠することで、普遍的なコードを書くことができ、将来的なメンテナンス性が高まります。また、知識が長期にわたって活きるというのも大きなメリットです。
SVGもそんなWeb標準の1つであるため、押さえておいて損はないでしょう。

Canvas vs SVG

Web上でグラフィックを描画する方法として、Canvasタグを使う方法もあります。Canvasタグは、Canvas APIもしくはWeb GLを用いてJavaScriptにより描画します。SVGと違い、Canvasはラスター画像を描画します。
特徴は、描画の自由度が高いことです。Canvas APIでは、ラスター故にピクセル単位で描画できます。
例えば、SVGでは難しいフラクタル図形などもCanvasなら簡単に描画できます。

一方、特に便利なフィルターなどが標準であるわけではないので、いちいち自分で実装する必要があります。
以下はガウスブラーをCanvasで実装した例です。

また、ラスターなので、本来SVGであればブラウザやOSが自動で行ってくれるアンチエイリアス処理なども、自分で実装する必要があります。

総合すると、Canvasは自由度が高い分、実装が複雑なため、かなりこだわったグラフィックを描画したい際にツール (Three.jsやUnity) などと組み合わせて使うのが良いでしょう。ただし、そのような領域になればタイトルでも掲げたWeb標準からは遠ざかることになります。

CSS vs SVG

Web上で見た目を整える時、多くのケースでCSSを使います。当然、文章を扱うWebコンテンツにおいてCSSは非常に重要です。しかし、グラフィックの領域においてはSVGは痒いところに手が届くような使い勝手を持っています。

ケース1: パス

SVGの特徴の1つとして、パスの描画があります。HTMLとCSSだけではパスの表現において限界があります。
例えば、次のようなインジケーターを作る場合、CSSだけでは難しいです。

このようなパイグラフはインジケーターだけでなく、ローディングなどでも有用で、実際にMUIなどのライブラリでもSVGを使って描画しています (上のコードもMUIのコードを参考にしています)。

また、これを応用することでマウスに追従するアニメーションなども簡単に実装できます。

ケース2: フィルター

SVGの大きな特徴の2点目として、豊富なフィルターがあります。以下はSVGの要素一覧ですが、feから始まる要素は全てフィルターに関するものです。

この中から、CSSでは表現しきれないもののうち、いくつか厳選して紹介します。

feTurblenceとfeDisplacementMap

デザインや動画編集に詳しい方ならこれらのフィルター名を見ただけでピンとくるかもしれません。これらを組み合わせて使うことで、水によって歪むようなエフェクトを簡単に実装できます。

(AfterEffectsなどでいう「展開」がないのが辛いところ…)

feColorMatrix

色をRGBAの4次元ベクトルとして表現し、それに線形変換を施すフィルターです。色相の変換など、さまざまな色調補正が可能です。
以下は色相を変える例ですが、これ以外にも行列を直接指定できます。

まとめ

意外と知られていないSVGの一面を見ていただけたでしょうか。この記事を通して、SVGはただのベクター画像形式ではなく、多くの可能性を秘めているというところを感じ取っていただければ幸いです。

明日はSHINNさんの「undefined」です。勢いで登録していただいてありがとうございます!

Discussion