2012年4月3日火曜日

SVGの基礎知識

SVGは比較的古くからある仕様の1つですが,2010年3月にマイクロソフトがInternet Explorer 9でのサポートを表明してから一気に注目が高まりました。そんな古くて新しいSVGを今から使える情報と,将来の展望を全4回の集中連載で解説します。

SVGとは

SVG(Scalable Vector Graphics)は,XMLベースのベクターグラフィック言語もしくは画像フォーマットです。W3Cによってその仕様が定義されており,画像フォーマットとして用いる場合は拡張子.svgが使用され,MIME形式はimage/svg+xmlが用いられます。

SVGの現状

Firefox,Safari,Google Chrome,Operaなどのブラウザが既にサポートしており,Internet Explorerもそのバージョン9,具体的にはInternet Explorer 9: Platform Demosで公開されているPlatform Preview版でSVGをサポートします。

SVGはHTML5関連のAPIとして挙げられる仕様の中ではかなり古くからある仕様で,現在主要であるSVG 1.1は2003年1月14日にW3Cによって勧告されています。しかし,マイクロソフトはVML,アドビはPGMLなど,対立する仕様を提案していました。そのため,Internet ExplorerのSVGサポートは進みませんでした。また,SVGは多数のモジュールで構成された巨大な仕様であるため,Internet Explorer以外のブラウザのサポートも順調ではありませんでした。そのため,長らくSVGは陽の目を見ることがなかったというのが実情です。

しかし,2010年3月にマイクロソフトがInternet Explorer 9にてSVGをサポートすることを明らかにし,かつほかのブラウザのSVGのサポート状況もようやく足並みが揃ってきたため,一気に注目が集まりました。もちろん依然として無条件で使える技術というわけではありませんが,近い将来には広く使われるようになるかもしれません。

なお,Internet Explorer 9はSVGの仕様のうち,フィルタ,アニメーション(SMIL),フォント(SVG Fonts)をサポートしません。これらCSS3などで定義される範囲との重複があるため,サポートを見送ることにしたとされています。

XMLとしてのSVG

SVGはXMLで記述します。つまり,SVGファイルはテキストエディタで編集することが可能で,差分が取れるなど,テキストファイルのメリットを享受できます。

その一方で,複雑な描画をするとファイルが巨大になってしまう問題があります。そのため,gzipで圧縮して利用する場合もあり,その場合は拡張子.svgzが用いられます。

SVGを描く

SVGは画像フォーマットでもあるので,いくつかのグラフィックソフトウェアがSVG形式での入出力に対応しています。メジャーなところではAdobe社のIllustrator,Microsoft社のOffice Visioなど,オープンソースのソフトウェアではInkscapeなどが対応しています。特にInkscapeはSVGを標準の形式として開発されており,SVGの多くの機能をサポートしています。

SVGの様々な機能を学びたい場合,Inkscapeで描画して保存したsvgファイルをテキストエディタ等で開くことで手軽に描画結果と整合した記述を知ることができます。

SVGとCanvas 2D

SVGとCanvas 2D(ここではHTML Canvas 2D Contextを指しています。以降,特に注記がない限りCanvas 2D Contextのことを指します)はどちらもW3Cによって定義されている,図を描いて表示するための仕様です。両者はどう違うのか,確認しておきましょう。

まず1つ目の大きな違いは,SVGがベクター形式で,Canvas 2Dはビットマップ形式という点です。SVGで描かれた線はどんなに拡大しても綺麗な線を描きます。一方,Canvas 2Dで描かれた線は拡大したときにどうしてもぼやけてしますし,拡大ではなくCanvas自体を大きく描画した場合は処理も重くなりますしメモリも多く消費してしまします。一方,ビットマップ形式のCanvas 2Dではピクセルに対する操作が可能ですが,SVGではそういったことはできず,ピクセル単位のような細かい描画には不向きです。

もうひとつの大きな違いは,SVGは単体で画像フォーマットとして保存し,対応ビューアで表示することができますが,Canvasはブラウザとその上で動くJavaScriptが存在して初めて描画が可能となります。CanvasもPNGなどの形式で画像ファイルとして出力することはできますが,Canvas自体は画像フォーマットではありません。

SVGとCanvasの違いは,Adobe社製のIllustratorとPhotoshopの関係と似たところがあります。SVGはIllustratorに,CanvasがPhotoshopに対応します。

Flashとの比較

もうひとつ,Flashとの違いですが,そもそもFlashは全部入りの巨大なアプリケーションプラットフォームです。SVGのようなベクター形式も扱えますし,CanvasのようなBitmapも扱えます。それどころか,外部ファイルとの通信や,ストレージもありますし,動画や音声なども再生できます。(2010年6月時点において)単純に機能で比較すれば,Flashのほうが高機能かつ高速です(ただしこれらは開発者からみたメリットでしかなく,利用者の視点はまた別の問題です)。

ブラウザとSVG

SVGはXMLであり,すなわちマークアップによって記述されます。XHTMLではHTMLとSVGを混在させることが可能ですし,HTML5ではSVGをHTML中に直接記述(インラインSVG)できるように定義されました。インラインSVGをサポートしているのは2010年6月時点ではInternet Explorer 9(Platform Preview版)とFirefox4.0b2pre(minefield)だけですが,近いうちにほかのブラウザもサポートすると思われます。

また,SVGはDOMの延長としてJavaScriptから各要素を操作することが可能です。そのため,一度描画した図を動かすことが容易にできます。

SVGをブラウザで表示する方法

SVGをブラウザで表示する方法にはいくつか種類があります。

objectタグでの埋め込み

最も手軽にsvgを表示する方法です。次のように,objectタグにtype="image/svg+xml"を指定し,data属性にsvgファイルのパスを指定します。

<object data="sample.svg" type="image/svg+xml"></object>
svg対応ブラウザはすべて対応している上に,svg非対応のブラウザ向けのコンテンツを提供しやすいところはメリットですが,object内のsvgはインラインフレームと同様に,別のウィンドウとして扱われるため外側のコンテンツから(主にJavaScriptから)扱いにくいというデメリットもあります。

dataスキームでの埋め込み

こちらも比較的手軽な方法です。img要素のsrc属性,CSSのbackground-imageなど,データスキームで画像を表示できる場合,そのデータとしてSVGを流しこむことができます。特にCSSのbackground-imageとして表示すれば,その名の通り背景としてSVGを利用することができます。

しかし,残念なことにこの方法はFirefoxがサポートしていません。

XHTMLでのHTMLとSVGの混在

XHTMLには名前空間が存在するので,HTMLの名前空間とSVGの名前空間を用意することで1つの文書中にHTMLとSVGを混在させることが可能です。こちらもSVGをサポートするブラウザではすべて利用可能ですが,非対応のブラウザ,特にIE 8以前ではContentTypeがapplication/xhtml+xmlで返されるコンテンツをダウンロードしようとしてしまうという問題から少々面倒な対応が必要となります。

具体的には,次のようにサーバー側でブラウザのUserAgentを見て,HTTP_ACCEPTにapplication/xhtml+xmlを含むブラウザにだけapplication/xhtml+xmlで返すようにする処理が必要となります。

以下はInline SVG - SVG wikiより,ApacheのModRewriteの設定サンプルです。

AddType text/html .xhtml
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml
RewriteCond %{HTTP_ACCEPT} !application/xhtml\+xml\s*;\s*q=0
RewriteCond %{REQUEST_URI} \.xhtml$
RewriteCond %{THE_REQUEST} HTTP/1\.1
RewriteRule .* - [T=application/xhtml+xml]
この上で,次のようなXHTMLを拡張子.xhtmlで保存してサーバーにアップすればHTMLとSVGを同時に表示することができます。

<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:lang="ja">
<head>
<meta charset="utf-8" />
<title>SVG in XHTML</title>
<style>
/*<![CDATA[*/
html,body,svg{
margin:0;
padding:0;
}
/*]]>*/
</style>
</head>
<body>
<h1>SVG in XHTML</h1>
<svg:svg viewBox="0 0 100 100">
<svg:circle cx="50" cy="50" r="50" style="fill:red;" />
</svg:svg>
</body>
</html>
JavaScriptからの埋め込み

最後の方法はJavaScriptからsvg要素を作り,HTML中に挿入する方法です。こちらはSVG対応ブラウザなら動作しますし,HTML自体は通常のHTMLでよいというメリットがあります。ただし,基本的にJavaScriptからすべての要素を作るので,手の込んだ図形の描画にはあまり適しません。画像フォーマットとして用意したsvgファイルを読み込ませるにもかなり手間がかかります。一方で,プログラム次第で人力では難しい幾何学的な図形などを描画することも可能です。

var SN ="http://www.w3.org/2000/svg";
var root = document.getElementById('svg-1');
var svg = document.createElementNS(SN, 'svg');
svg.setAttribute('viewBox','0 0 100 100');
var circle = document.createElementNS(SN, 'circle');
circle.setAttribute('cx',50);
circle.setAttribute('cy',50);
circle.setAttribute('r',50);
circle.setAttribute('style','fill:red;');
svg.appendChild(circle);
root.appendChild(svg);
Raphael

SVG,VML(IE 5〜IE 8がサポートするグラフィックフォーマット)をバックエンドにクロスブラウザなグラフィック表現を可能にするRaphaelというライブラリがあります。このRaphaelを使えば,ベクター形式のグラフィックをJavaScriptから扱うことが可能になります。今のところIE 6〜8をサポートしているのはこのRaphaelだけです。

なお,RaphaelのAPIは独自のものなので,RaphaelのAPIを覚える必要があります。逆に言えばSVGについて知らなくてもRaphaelから入ることも可能です。

Raphaelは画像フォーマットとしては扱えないため,JavaScriptで描画を組み立てなければいけないのでデザイナー向きではありませんが,グラフの描画には最適です。

Raphaelで円を描く
// ベースとなる要素を作る
paper = Raphael(root, 0, 0, 200, 100);
//引数はx座標、y座標、横幅、縦幅

// x:100px y:50pxの位置に半径2pxの円を作成
circle = paper.circle(100, 50, 2);
// 円の塗りつぶし色を赤に
circle.attr("fill", "red");
// 円の枠線を黒に
circle.attr("stroke", "black");
// 円の半径を50pxにするアニメーションを設定
circle.animate({r: 50}, 2000);
まとめ

今回はSVGの基礎知識として,その仕様と特徴について紹介し,SVGの表示方法を解説しました。次回からはSVGで図形を描画する方法を中心に解説します。

0 件のコメント:

コメントを投稿