作成2001年5月25日
改訂2012年11月20日
SVGに未来のWebグラフィックスを発見
SVGとは
Scalable Vector Graphics (SVG)フォーマットは、Web上のグラフィックスの表示に新しい変革をもたらすものとして注目すべき技術である。SVGとは一体どのようなものなか? SVGはW3Cで議論されているXMLベースの2次元ベクター・グラフィックス・フォーマットである。ベクターグラフィックスとして有名なものにアドビシステムズのPostScriptがあり、これは印刷の品質向上を格段の貢献をしている。SVGはWebへの対応を最初から視野に入れているため、PostScriptをはるかに越える可搬性を有する。W3Cで進められているSVG規格は、2001年9月、勧告された(SVGの標準化に向けて、マイクロソフト、アドビシステムズ、アップル、ネットスケープ、マクロメディア、IBM、クォークはじめ名だたるベンダーが参加)。
SVGはXMLの派生した技術で、XML同様、CSS、JavaScriptやDOMなどの技術が利用でします。これらの技術によって、SVGは基本グラフィックスを始め、グラデーション、アニメーション、フィルタ・エフェクトなど洗練されたグラフィック描画機能があり、またJavaScriptによるインタラクティブなインターフェイスを提供している。アドビシステムズからはIEやNNにプラグインできるSVGViewerが提供されており、同社のサイト(http://www.adobe.com/jp/svg/viewer/install/)からダウンロードできる。このサイトにはSVGの機能を紹介する優れたドキュメントと表現豊かなSVGサンプルがたくさんあり、SVGを勉強される方はまずこのサイトから。
一方、SVGを生成できるツールとして、Adobe IllustratorやMS visioなどのアプリケーションがあり、保存書式としてsvgを選択すれば、svgファイルができあがる。
Webでの画像表現として、GIF、JPEG、PNGなどが利用されているが、HTML5では、更にcanvas要素によるビットマップ画像表示、SVGによる2次元ベクターグラフィックスと、充実した画像表現が可能となっている(IE9+、FireFox、GoogleChromeなどのHTML5対応ブラウザーは標準でSVGを表示できる機能を搭載)。
現在の欠点は、HTML5の規格が勧告されていないためか、ブラウザー毎に挙動がことなること、またリソース消費が高いことである。
スマートフォンでも描画することができる(アニメーションは現在のところ、動かないようである)。
参考サイト
Scalable Vector Graphics (SVG) 1.1 日本語版仕様
SVGの仕様について
SVGの仕様には、描画要素を格納するコンテナー、コンテナーの参照機能、基本描画機能、アニメーション機能、フィルタ機能が盛り込まれ、2次元ベクターグラフィックとして十分な機能が搭載されている。現在SVGの仕様書はPDFファイルで500ページを越えるボリュームであるが、豊富なサンプルコードが用意され、理解し易いものとなっている。詳細は参考サイトSVG1.1の日本語版仕様を参照のこと。
SVG1.1の仕様より
|
要素名 |
要素の内容 |
コンテナー機能など |
svg |
SVGドキュメントの宣言 |
title |
タイトルの記述 |
|
desc |
コメントの記述 |
|
g |
表示要素のグルーピング |
|
defs |
参照要素のためのコンテナー宣言 |
|
symbol |
コンテナーの中にある複数の表示要素のグルーピング化 |
|
use |
defsの中にある表示用コンテナーの要素参照 |
|
tref |
defsの中にあるテキスト用コンテナーの要素参照 |
|
基本機能 |
rect |
四角形(角の丸いものも含む)の描画 |
circle |
円の描画 |
|
ellipse |
楕円の描画 |
|
line |
線の描画 |
|
polyline |
折れ線の描画 |
|
polygon |
多角形の描画 |
|
path |
汎用的な描画要素 |
|
text |
テキストの表示 |
|
tspan |
テキストの部分修飾 |
|
textPath |
pathで指定された線上へのテキスト表示 |
|
image |
イメージの表示 |
|
a |
リンクの設定 |
|
アニメーション機能 |
animate |
描画要素のアニメーション指定 |
set |
アニメーションのためのXMLやCSSの属性値の設定変更 |
|
animateMotion |
pathに沿って描画要素の移動 |
|
animateColor |
描画要素の色変更 |
|
animateTransform |
transformによる描画要素の移動・変形 |
フィルタ機能は省略している。
<svg> SVGドキュメントの宣言
SVGドキュメントはこの要素の中に記述します。この要素の宣言に先立ち、DOCTYPEの宣言も必要となる。またSVGドキュメントの宣言に留まらず、表示エリアの定義を行う。この例では幅12cm、高さ7cmをSVGの表示エリアとする。SVGは、下記のような書式で、”svg”と言うファイル識別子のXMLファイルを、直接ブラウザーに表示できるブラウザーもある。
<?xml version="1.0"
standalone="no"?>
<!DOCTYPE svg
PUBLIC "-//W3C//DTD SVG 20001102//EN"
"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd">
<svg
width="12cm" height="7cm">
・・・・・・・
</svg>
HTML5では、次のようにHTML文書の中にsvg要素を埋め込み、HTMLとSVGの共存が可能となっている。属性にxmlns=http://www.w3.org/2000/svgを加えることが無難である。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<body>
<svg xmlns="http://www.w3.org/2000/svg"
width="600" height="400">
・・・・・・・
</svg>
</body>
</html>
<title>、<desc> タイトルやコメントの記述
HTMLやXMLでのコメントの記述は、<!-- -->の中に行います。SVGも同様の記述でコメントが記述できる。SVGでは、これ以外にtitleとdescが用意されている。これらの要素は、属性として名前空間が指定できるため、外部のXML概念を記述することができる。titleやdese要素で括られた内容は、SVG上で何も作用もしない(表示処理の対象外)。
<desc xmlns:mydoc="http://example.org/mydoc">
<mydoc:title>This is an
example SVG file</mydoc:title>
<mydoc:para>The global
description uses markup from the
<mydoc:emph>mydoc</mydoc:emph>
namespace.</mydoc:para>
</desc>
<g> 表示要素のグルーピング
この要素は、HTMLでのDIV要素と同じ働きをする。この要素で括られた範囲にある描画要素に対して属性を与え、一つのグループとして扱えるようになる。次の例では、rect要素とcircle要素に対して、fill:redのスタイル属性を与えることができる。
<g id="group1" style="fill:red">
<rect x="30"
y="30" width="60" height="60" />
<circle cx="220" cy="60" r="60"
/>
</g>
<defs>、<use> 参照要素のためのコンテナー宣言とその参照
defs要素はいくつかの場所で参照される描画要素をテンプレートとして定義し、use要素によってそのテンプレートが参照できる。この例では、rect要素のid属性が参照元、参照側のインターフェイスになる。このrectでは幅、高さが定義されていて、参照された場合、表示座標属性が付加されて、四角形が表示される。
<defs>
<rect id="MyRect" width="300" height="150"
style="fill:yellow;stroke:purple;stroke-width:2"/>
</defs>
<use x="200" y="100" xlink:href="#MyRect" />
<symbol> 複数の表示要素のテンプレート宣言
複数の描画要素を一塊として扱えるよう、defs要素の中で複数のテンプレート宣言ができる。この例では、2つの赤丸をuse要素で指定する座標に表示する。
<defs>
<symbol
id=”MyCircle” style=”fill:red”>
<circle cx=”100” cy=”100” r=”80"/>
<circle cx=”300” cy=”100” r=”80"/>
</symbol>
</defs>
<use x="20" y="10" xlink:href="#MyCircle" />
<tref> テキストコンテナーの宣言
上記では描画要素のテンプレート化した。テキストも同様にテンプレート化できる。テンプレート化したテキストの参照はtref要素によって行う。
<defs>
<text
id="Confidential">極秘資料</text>
</defs>
<text
x="20" y="50" style="font-size:30pt; fill:red; font-family:'MS
Gothic'">
<tref xlink:href="#Confidential"/>
</text>
<rect> 四角形の描画
四角形の描画はrect要素によって行う。指定する属性は、開始座標、幅、高さ、それにスタイル情報である。この例では縁が幅4のスカイブルーで、中がグリーンの大きな四角形を描画する。rx、ryによって角を丸くすることもできる。
<rect x="5" y="5" width="690"
height="490" rx=”20” ry=”20”
style="fill:green;
stroke:skyblue; stroke-width:4" />
<circle> 円の描画
円の描画はcircle要素によって行う。指定する属性は円の中心座標、半径、それにスタイル情報である。この例では半径80の青丸を(300,100)を中心として描く。
<circle
cx="300" cy="100" r="80" style="fill:blue" />
<ellipse> 楕円の描画
楕円の描画はellipse要素によって行う。指定する属性は、楕円の中心座標、x径、y径、それにスタイル情報である。この例ではx径80、y径50のピンクの楕円を(150,200)を中心として描く。
<ellipse
cx="150" cy="200" rx="80" ry="50"
style="fill:pink" />
<line> 線の描画
線の描画はline要素によって行う。指定する属性は、開始座標、終了座標、それにスタイル属性である。この例では(200,10)から(10,200)まで赤い線を描く。
<line
x1="200" y1="10" x2="10" y2="200"
style="stroke:red" />
<polyline> 折れ線の描画
折れ線の描画はpolyline要素によって行う。指定する属性は、結ぶ点の座標列とスタイル情報である。この例ではpointsで指定された座標列を線幅3の緑色線を描く。
<polyline
points="10,10 20,50 80,100 140,40 200,200"
style="fill:none;
stroke:green; stroke-width:3" />
<polygon> 多角形の描画
多角形の描画はpolygon要素によって行う。指定する属性は、多角形頂点の座標列とスタイル情報である。この例ではpointsで指定された座標を多角形の頂点とし、線幅3で紺色の縁取りで、スカイブルーで塗られた多角形を描く。
<polygon
points="210,100 320,150 380,100 340,240 300,200"
style="fill:skyblue;
stroke:navy; stroke-width:3" />
<path> 汎用的な描画要素
この要素は汎用的な描画要素で、線の描画、多角形の描画、曲線(二次ベジェ、三次ベジェ、円弧)の描画ができる。
線を描く
<path
d="M 100 100 L 200 200 L 200 100"/>
<path
d="M 100,100 L 200,200 L 200,100"/>
<path
d="M 100 100 L 200 200 200 100"/>
<path
d="M100 100L200 200 200 100"/>
上記のコードはいずれも (100,100)から(200,200)を通り、(200,100)まで線を描
く。
<path
d="M 100 100 L 200 200 v -100"/>
このコードも同じように表示します。Vは垂直方向、hは水平方向の移動を示す。
<path
d="M 100 100 L 200 200 L 200 100 z"/>
このコードは(100,100)から(200,200)、(200,100)を通る閉領域を描く。
曲線を描く
三次ベジェ曲線
<path
d="M 100,200 C 100,100 250,100 250,200"/>
このコードは,(100,200)から(250,200)まで、(100,100)と(250,100)を制御点と
して、三次ベジェ曲線を描く。
<path
d="M 100,200 C 100,100 250,100 250,200 S 400,300 400,200"/>
上記の曲線に続き、(250,200)から(400,200)まで、同じパターンで一つ目の制御点
を想定し、もう一つ制御点(400,300)から生成する三次ベジェ曲線を描く。
二次ベジェ曲線
<path
d="M200,300 Q400,50 600,300 T1000,300"/>
(200,300)から(400,50)を通り(600,300)まで二次ベジェ曲線を描く。
この曲線と同じパターンで(1000,300)まで二次ベジェ曲線を描く。
円弧を描く
<path
d="M 125, 75 A 100,50 0 0 0 225,125"/>
(125,75)から(255,125)まで、長径100,50の楕円で、小さい弧でマイナス方向の
円弧を描く。
0
0 0はそれぞれ、回転角、large-arc-flag、sweep-flagである。large-arc-flag
が0のとき小さい方の円弧、1のとき大きい方の円弧が指定される。sweep-flagが
0のときマイナス方向の円弧、1のときプラス方向の円弧が指定される。
<text> テキストの表示
テキストの表示はtext要素によって行います。指定する属性は、表示位置、スタイル情報で、子供要素として、表示するテキストを記述する。この例ではMSゴシックのフォントサイズ20ptで“おはよう”を(20,50)の位置に表示する。
<text
x="20" y="50" style=”font-size:20pt; font-famly:’MS
Gothic’”>おはよう
</text>
<tspan> テキストへの部分修飾
テキストの一部を修飾するとき、tspan要素を用いる。指定する属性は表示位置をx,yで指定し、修飾したい属性をスタイル属性によって指定する。この例は“東京都新宿区河田町”の中で、”新宿区”を青色し、他の文字列は黒色で表示する。スタイル情報はtspan要素の中に留まり、それ以降は前段の要素のスタイル情報が継承される。
<text
x="20" y="50" style="font-size:20pt; font-famly:'MS Gothic'">東京都
<tspan style=”fill:blue”>新宿区</tspan>
河田町
</text>
下のコードのように指定すると、テキストの6文字をxで指定する間隔で表示する。
<text
x="20" y="50" style="font-size:20px; font-famly:'MS Gothic'">
<tspan x="10 40 70 100 130 160" y="50">東京都新宿区</tspan>
河田町
</text>
下のコードは“新宿区”だけを10ドット上に書くような指定をしている。その指定はdx,dy
属性で行う。IE9は正しく表示し、残念ながらGoogleChromeは正しく表示できなかった。
<text
x="20" y="50" style="font-size:20px; font-famly:'MS Gothic'">東京都
<tspan dy="-10"
style="fill:red">新宿区</tspan>
<tspan dy="20"/>
河田町</tspan>
</text>
サンプル17(左がIE9、FireFox、右がChrome)
<textPath> テキストの曲線上への表示
テキストを指定した曲線上に乗せて表示するとき、textPath要素によって行う。指定する属性は、defs要素で指定した曲線情報をxlink:hrefで参照するだけである。SVGはユニコードをベースにしているため、記述する日本語もユニコードでなければ表示されない。また、フォントの種類は、WindowsではMSゴシック、Macでは“osakaフォント“に限られる。
<defs>
<path
id="MyPath" d="M 100 200 C 200 100 300
0 400 100
C
500 200 600 300 700 200 C 800 100 900 100 900 100" />
</defs>
<text
style="font-family:'MS Gothic';
font-size:42.3333; fill:blue">
<textPath xlink:href="#MyPath">
私の名前は大坂哲司です。
</textPath>
</text>
サンプル18(左がIE9、FireFox、右がChrome)
<image> イメージの表示
イメージの表示はimage要素によって行う。指定する属性は、表示位置、表示領域の幅、高さ、それにxlink:hrefで参照ファイルを指定する。この例では表示位置(100,100)から表示領域400,300に、参照ファイルを表示される。
<image
x="50" y="50" width="600" height="100"
xlink:href="http://httpd.apache.org/images/httpd_logo_wide_new.png"
/>
<a> リンクの埋め込み
リンクは<a>要素によって行う。参照するリンク先はxlink:hrefで指定する。<a>要素で括られたテキストや図形をクリックすると、指定のリンク先に飛んでいく。この例では赤丸をクリックすると、W3Cのサイトへ行く。
<a
xlink:href="http://www.w3.org">
<circle cx="250" cy="150" r="10"
style="fill:red"/>
</a>
<animate> 描画要素のアニメーション指定
描画要素へのアニメーション指定は<animate>によって行う。指定する属性は次の通りである。attributeTypeはアニメーションさせる属性の種類を指定します。指定は“XML”、”CSS”、と”auto”である。“XML”はXMLの属性を示し、”CSS”はCSSのスタイル属性を示し、”auto”は両者の自動判定を示す。attributeNameはアニメーションさせる属性名を指定する。この属性に対して、具体的な変量はform、toで指定します。beginで開始時間、durで表示時間、fillで表示終了後の状態を指定する。fillには表示状態を残す”freeze”と非表示にする”remove”がある。repeatCountで表示回数を指定する。無限に繰り返す場合、repeatCount=”indefinite”とする。この例では、幅300、高さ100の黄色い四角形に対して、5秒間で幅を300から800、高さを100から300と変化させる指定を行っている。
<rect x="300" y="100"
width="300" height="100" style="fill:rgb(255,255,0)"
>
<animate
attributeName="width" attributeType="XML"
begin="0s" dur="5s"
fill="freeze" from="300" to="800" />
<animate
attributeName="height" attributeType="XML"
begin="0s" dur="5s"
fill="freeze" from="100" to="300" />
</rect>
サンプル21(IE9は×)
<set> アニメーションのためのパラメータ設定
描画要素の非数値属性やスタイル属性の変更は<set>によって行う。指定する属性は<animate>とほぼ同じである。この例では、半径5の緑色円を非表示でセットする。SVGドキュメント表示から6秒後、この円を表示し、半径を5から80まで5秒間で表示する。
<circle
cx="100" cy="150" r="5" style="fill:green; visibility:hidden">
<set
attributeName="visibility" attributeType="CSS" to="visible"
begin="6s" dur="5s"
fill="freeze" />
<animate
attributeName="r" attributeType="XML"
begin="6s" dur="5s"
fill="freeze" from="5" to="80"/>
</circle>
サンプル22(IE9は×)
<animateMotion> pathに沿った描画要素の移動
描画要素を指定したpath上で移動させる場合<animateMotion>によって行う。指定する属性は<animate>の属性に、pathの記述と描画要素に対する回転の指定が追加される。この例では、テキストの初期位置を(1000,280)に置き、水平方向に-2000までを3秒で移動する。このpathは単純ですが、複雑な曲線を指定すると、その上を巧みに移動する。
<text
style="font-family:'MS Gothic'; font-size:60; fill:blue">
私の名前は<tspan
style="fill:green">大坂</tspan>です。
<animateMotion dur="3" repeatCount="indefinite"
path="M 1000 280 h-2000"
rotate="0" />
</text>
サンプル23(IE9は×)
<animateColor> 描画要素の色変更
指定し時間の中での色変は<animateColor>によって行う。指定する属性は<animate>と同じである。色の指定はvalueによって行うこともできる。value="yellow;orange;yellow;"と指定すると、黄色からオレンジ色から黄色と変化させることができる。
<text
style="font-family:'MS Gothic'; font-size:60; fill:blue">
私の名前は<tspan
style="fill:green">大坂</tspan>です。
<animateMotion dur="3" repeatCount="indefinite"
path="M 1000 280 h-2000"
rotate="0" />
<animateColor attributeName="fill"
attributeType="CSS"
from="rgb(0,0,255)"
to="rgb(255,0,0)"
dur="3s" repeatCount="indefinite"
/>
</text>
サンプル24(IE9は×)
<animateTransform> transformによる描画要素の移動・変形
図形の移動・変形のアニメーションはanimateTransform要素で行う。この例では、テキストを表示し、1秒後から4秒間、5倍の大きさに拡大する。
<text x="5" y="15"
style="font-size: 8pt;">私の名前は
<tspan
style="fill:blue">大坂</tspan>です。
<animateTransform
attributeName="transform"
type="scale" from="1"
to="5" begin="1" dur="4s" fill="freeze"/>
</text>
サンプル25(IE9は×)
SVGのDOM
ブラウザー上でSVGが表示されるとき、HTMLやXMLと同じようにそのドキュメントはDOMの中に管理され、SVGの描画要素に従ってレンダリングされる。SVGのDOMはDOM Level2及びCSS2をサポートしているため、SVGのDOMやCSSもまたHTMLやXMLと同様にJavaScriptからアクセスでき、2次元グラフィックの表示だけに留まらずダイナミックでインタラクティブな演出が可能となる。
SVGはXMLドキュメントであるためDOMを操作することによって種々の効果が出せる。DOMを通して描画属性を変更することで表示オブジェクトが移動したり、大きさが変わったりする。またCSSの属性値を変更すると、色が変わったり、フォントサイズが変わったりする。
ダイナミックにSVGを生成
JavascriptでHTMLの要素をダイナミックに生成できるように、SVGでもSVGの要素がダイナミックに生成できる。HTMLとSVGとの違いは、要素の生成に使うメソッドになり、HTMLはcreateElementメソッドで、SVGは createElementNSメソッド(SVGの名前空間を指定)を利用すると言う違いだけである。
次のサンプルコードは、HTMLの中に2つのsvg要素が埋め込まれていて、それぞれのSVG空間の中にそれぞれpolygon要素、circle要素を生成し、描画する(HTMLの中にSVGを記述したSVGをインラインSVGと呼ぶ)。インラインSVGは、この例からも分かるように、HTMLの中に埋め込むことができ、より多彩なページが制作できる。
<!DOCTYPE
html>
<html
lang="ja">
<head>
<title>SVG描画</title>
<meta
charset="utf-8" />
<script
type="text/javascript">
function
draw(){
var
polygon1=document.createElementNS("http://www.w3.org/2000/svg","polygon");
polygon1.setAttribute("points","0,50
50,100 100,50 50,0");
polygon1.setAttribute("style","fill:blue");
document.getElementById("svg1").appendChild(polygon1);
var
circle1=document.createElementNS("http://www.w3.org/2000/svg","circle");
circle1.setAttribute("cx","50");
circle1.setAttribute("cy","50");
circle1.setAttribute("r","40");
circle1.setAttribute("fill","red");
document.getElementById("svg2").appendChild(circle1);
}
</script>
</head>
<body>
<h2>SVG(HTML5)で描く</h2>
<div
id="mydiv">
<svg id="svg1" width="200"
height="120"></svg>
<span
style="font-size:40px">●</span>
<svg id="svg2" width="200"
height="120"></svg>
</div>
<button
onclick="draw();">描画</button>
</body>
</html>
作成 大坂哲司