svg要素の基本的な使い方まとめ

Written by defghi1977@xboxLIVE.この文書は全てテキストエディタで作成しています.えーと,そりゃもうゴリゴリと.

15.スクリプティング

htmlと同様にsvgにおいてもjavascriptを用いてその内容を操作することができる.svgを描画するjavascriptライブラリとしてはRaphaël—JavaScript Libraryが有名だが,本項ではより応用の効く,直接svgのもつapiを使ってグラフィックを描く方法について示す.因みにRaphaëlの使い方は別の項で述べる.なお,htmlでのjavascriptの利用法を理解していることを前提としているので,内容が解りにくかった場合は別途他のサイトを参照して欲しい.

script:スクリプトによる動的グラフィック

script要素はsvgファイル内部にjavascript(厳密にはapplication/ecmascript)によるプログラム処理を記述するためのもので,htmlにおけるscript要素とほとんど同じ機能をもつ.htmlファイルにおいて埋め込みsvg要素を用いた場合,style要素と同様にhtmlの要素とsvgの要素とを混在させたスクリプトも正しく動作する.

html等の文書においては,dom(Document Object Model)と呼ばれるインターフェースが定義されており,スクリプトなどはこのdomを介して文書を操作する.domは文書の種類により様々なものがあるが,svgにおいてはsvgdomが,htmlにおいてはhtmldomが定められている.どちらも汎用的なxml操作の為に策定された「dom core」を拡張したものとなっており,共通的な要素の操作(例:element.appendChild, element.removeChild, document.getElementById, document.getElementsByTagName等)はここで定義されている.従って,svgdomでもhtmldomでも基本的な使い方に違いはない.以下に関係を示す.

htmldomとsvgdomとは兄弟の関係にあるものの,文書の特性に合わせて独自のapiを持つため,直接的な関連を持たない.従ってhtmldomを前提に設計されたライブラリ(例えばjQuery)はsvg文書においては動作しない

html文書をブラウザで開いた場合,変数documentにHTMLDocumentオブジェクトが,svg文書を開いた場合はSVGDocumentオブジェクトが設定される. また埋め込みsvg要素を使ったhtml文書の場合は,document.getElementByIdメソッドで得られるオブジェクトがSVGElementの可能性があり,htmldomを前提としたプログラムを作成するとエラーとなる.

上記以外についてはほとんど同じである.例えばjavascriptのもつ関数(alert等)は全て利用可能であるし,window.location等のオブジェクトもdocumentプロパティの実体が異なる点を除き同じである.またスクリプトの実行タイミングもscript要素が読み込まれた時点であるため,存在しない要素にアクセスしようとするとエラーとなる.このように,基本的な挙動についてはhtmlのものと同じであるため,既存のノウハウをそのまま流用することができる.

但しsvgファイルは文書として扱う場合の他に画像ファイルとして扱う場合があるが,この時にjavascriptが実行されるとは限らない.svgファイルをiframe要素に設定した場合はjavascriptが動作するが,img要素のsrcに設定した場合やbackground-imageに設定した場合はjavascriptが無効となるのだ.従って,動きのある背景を作りたいといった場合には,animate要素を用いるなど静的な構造で動きを表現することとなる.なお,埋め込みsvg要素についてはjavascriptは問題なく動作する.(もちろんブラウザ側でjavascriptが実行可能となっていなければならない.)

svg文書をメイン文書とサブ文書に分解する場合,メイン文書でのみ正しくスクリプトが動作する点に注意する.use要素も,image要素も参照先のsvg文書のスクリプトまでは実行してくれる保証はない.svgだけではhtmlでのframeやiframeのような複数の文書が連携すると言った機構を取りにくいのだ.よってスクリプトはメイン文書に集約し,サブ文書はグラフィックに特化させたり,htmlでsvgを利用することを前提とした設計をすると良い.

スクリプトの記述法

一般にsvgにおいてスクリプトプログラムを挿入するにはhtmlと同様の機構を含め次に挙げる2〜3つの方法がある.

script要素によるもの

最も一般的な記述法であり,svg文書が先頭行から順に読み込まれ,script要素が読み込まれたタイミングで直ぐに実行されるという特徴を持つ.スクリプトが記述された外部ファイルを参照することもできる.

script要素には原則的にjavascriptによるプログラムを挿入することになるが,環境によっては別の言語を指定することもできる.例えばIE環境では「text/vbs」を指定することでvbs(visual basic scripting edition)を使ってスクリプトを記述することが可能だ.※本文書ではvbsについては触れないので必要に応じて各自調べて欲しい.

※正直な所スクリプト言語にvbsを採用するのはお勧めできない.あくまでも下位互換性を保つ目的で用意されているものとして考えよう.但しvbs自体は優れた言語なので,使い所さえ間違えなければ非常に便利である.

type
スクリプトの種類.「application/ecmascript」が規定値.
xlink:href
スクリプトの外部参照先.

イベント属性によるもの

svgを構成する要素にはそれぞれ「on」から始まるイベント属性と呼ばれる属性が定義されており,ここにスクリプトを記述することができる.例えば「onclick」属性にスクリプト「alert("hellow")」を記述しておけば,この要素をマウスなどでクリックした際にスクリプトが実行され,メッセージ「hellow」が表示されるだろう.

svgで用いることが可能なイベント属性については本ページの後半にて示したのでそちらを参照して欲しい.なお,全ての要素で全てのイベント要素が有効となるとは限らない点に注意すること.

script要素と同様にイベント属性に記述するスクリプトの言語はsvg要素のcontentScriptTypeにて指定することができる.

onXXX
イベント属性.内部にスクリプトを記述しておくと,対応するイベントが発生した際にそのスクリプトが実行される.
contentScriptType
svg要素において要素のonXXX属性に記述するスクリプトの言語を指定する.「application/ecmascript」が規定値.

listener要素・handler要素によるもの(svg1.2 tiny)

svg1.2 tinyではイベント属性をサポートしないため,イベント処理を実行するための要素が定義されいる.なおsvg1.1では利用できないので,気にする必要はない.

htmlとsvgのスクリプトの記述法の比較

htmlをベースとした(svg要素をhtmlに埋め込んだ際の)スクリプティングとsvgをベースとした(svgファイル単体で動作する)それとでは自ずと異なる点が出てくるのでまとめてみた.

htmlsvg備考
scriptファイルの外部参照 <script type="text/javascript" src="参照先"></script> <script xlink:href="参照先"/> 記述がxlink形式となる.svgではcharset属性が定義されていないため,スクリプトは文字コードに原則としてutf-8を選ぶと良いかも知れない.
※スタイルの外部参照 <link rel="stylesheet" type="text/css" href="参照先"/> <?xml-stylesheet href="参照先" type="text/css"?> 記述がxml形式となる.
<![CDATA[]]>の必要性 必要なし.xhtmlでは必要 スクリプトをファイルに埋め込む場合は必要. script,style要素の中身を囲む記述.さもないと,「>」等の演算子を「&gt;」とエスケープしなければならず,コードの可読性を損ねる.
スクリプトを参照する場合はこの限りではない.
window.documentの実体 HTMLDocumentオブジェクト SVGDocumentオブジェクト ほとんど同じAPIを持つが,細かい部分で異なる.特に要素の生成に注意のこと.
文書の描画を行うルート要素 document.body document.documentElement SVGSVGElementが返される.

htmlと異なり,svgがxml文書であることからこのような違いが現れる.htmlとsvg間でソースコードを移動させる場合はこれらの点に注意すること.

要素の検索・生成・挿入

svg文書が読み込まれた際にスクリプトを実行するにはウインドウのloadイベント(window.onload)svg要素のloadイベント(document.documentElement.onload)の何れかに関数を設定すればよい.ここを起点にsvg画像を構成する各要素へアクセスすることとなる.

svgの要素(SVGElement)を取得するには,これまでどおりdocument.getElementByIdやdocument.getElementsByTagNameメソッドを利用することができる.

document.getElementById
idに対応する要素を取得する.
document.getElementsByTagName
指定した要素名に相当する要素のリストを取得する.
document.querySelector
セレクタに合致した先頭の要素を取得する.
document.querySelectorAll
セレクタに合致した要素のリストを取得する.

一方SVGElementの生成にはdocument.createElementNS("http://www.w3.org/2000/svg", "要素名")を用いる.これはsvgに関わる要素であることを明確化するためのもので,document.createElementメソッドではhtml要素が指定されたと解釈される.(なお,テキストノードの生成にはdocument.createTextNodeメソッドを用いる.)

つまりdocument.createElement("circle")と指定すると,svgのcircle要素ではなく不明なcircle要素が生成される.無論この不明な要素はレンダリング時に無視されるため,このことに気がつかないで実装を進めてしまうと,非常に根深いバグとなる可能性がある.デバッガのdomツリー上でも見た目上問題ないからだ.以下に例を示す.

ただ一箇所異なるだけで,前者では何も表示されていないことがわかる.

svgの名前空間uriを取得する

svgの名前空間uriはsvg要素等のnamespaceURIプロパティから内容を取得することができるため,既にsvg要素がdomに存在している場合は次のように記述することができる.

もちろんインラインsvgを自動生成する場合など,大本となるsvg要素が存在しない場合は直接名前空間uri文字列を指定する必要がある.

属性値の設定

SVGElementの属性値の参照・設定をするには主に次の4つの方法がある.

  1. getAttribute・setAttributeを用いる方法.
    svgをxmlとして扱い,直接属性値を書き換える方法に相当する.要素の種類によらず属性値を操作できるが,これらのメソッドはdomツリーの中を逐一検索する為にパフォーマンスに劣る事を憶えておこう.また,属性値の優先順位の兼ね合いからスタイルシートが設定されている場合に設定した値が無視されるケースがある.なおxlink:href等のxlinkで定義されている属性を書き換える場合はgetAttributeNS・setAttributeNSメソッドを用いる(getAttributeNS("http://www.w3.org/1999/xlink","href")).
  2. SVGElementがもつプロパティにアクセスする方法.
    要素の配置に関わる属性には専用のアクセッサが提供されている.例えばrect要素であれば対応するSVGRectElementにはx属性に相当するxプロパティが存在する.注意すべき点としてこれらのプロパティにアクセスするには「[オブジェクト名].[プロパティ名].baseVal」(href等のSVGAnimatedString型等)もしくは「[オブジェクト名].[プロパティ名].baseVal.value/valueAsString」としなければならない(例:rect.x.baseVal.value = 3; rect.x.baseVal.valueAsString = "3px").要素の属性値には元々の値(baseVal)とアニメーション途中の値(animVal:読み取り専用)の2つが考えられるため,このような設計となっている.なお,唯一class属性についてはclassNameプロパティ([オブジェクト名].className.baseVal)からアクセスする必要があることを憶えておこう.
  3. 専用メソッドを利用する方法.
    svgで定義されている属性の内,複雑な構成を取るもの(transform属性や,d属性等)については専用のインターフェースが提供されていることが多い.このインターフェースを利用することでsetPropertyメソッドを利用する場合に必要となる無用なstringオブジェクトの生成を抑えたり,より高度な処理を行うことが可能となる.
  4. SVGElementのstyleプロパティを参照する方法.
    色や線の太さ等のスタイルシートで設定可能な属性値(プレゼンテーション属性)についてはstyleプロパティのsetProperty・getPropertyValueメソッド,もしくはスタイル毎に定義されたプロパティ(例えばfill-opacityに対してはfillOpacityプロパティが提供されている)を操作することで内容の取得・変更を行うことが出来る.この値はsetAttributeでの設定値やスタイルシートによる値に優先する.

†この形式をcamel形式と呼ぶ.

専用メソッド

複雑な記述を要する属性値については専用のアクセスメソッドが提供されている場合がある.属性値の文字列をスクリプトで構築するのは,浮動小数点型の数値を連結する際に丸めなどの処理が必要となりいささか面倒だが,専用メソッドを用いればそのような事を考えずに済む.一方で記述量が多くなりがちなので適宜使い分けると良いだろう.なお,メソッドの一覧についてはmozillaのsvgのAPI解説ページ/MSDNのsvg解説ページに詳しい.以下に主なものを示す.

path要素のd属性

d属性は直線や円弧等の操作毎にオブジェクトが提供されており,pathSegListプロパティにリストとして管理されている.このオブジェクトを操作することでパス切片毎に制御することが可能だ.以下は先程の例をsvgDOMの内容を用いて書き換えたものである.

polyline要素,polygon要素のpoints属性

points属性はSVGPointオブジェクトのリストとして実装されている.

テキスト要素のx,y,dx,dy,rotate属性

text要素,tspan要素,tref要素,altglyph要素はSVGTextPositioningElementインターフェースを実装しており,x,y,dx,dy,rotate属性に相当するプロパティはSVGAnimatedLengthList/SVGAnimatedNumberListとして実装されている.従って単一の値を設定するにしても直接値を挿入することが出来ず,一旦SVGLengthオブジェクト等を生成してからリストに値を追加することとなる.

本日は晴天なり

transform属性

数有る属性の中でも最も扱いが面倒なものがこのtransform属性だ.以下にその構成を示す.

circle,rect等の図形要素はSVGTransformableインターフェースを実装しており,trasformプロパティをSVGTransformListオブジェクトとして実装している.同様にlinearGradient,radialGradient要素はgradientTransformプロパティを,pattern要素はpatternTransformプロパティをSVGTransformListとして実装している.他のプロパティと同様にこれらのプロパティもbaseVal,animValを持っているので適切に選択する必要がある.

上で得られるSVGTransformListオブジェクトには,SVGTransformオブジェクトのリストが格納されている.このSVGTransformオブジェクトはscale,skewX,skewY,rotate,translate,matrix関数に相当するもので,それぞれ対応するメソッドが定義されている.関数の設定を取得するためのプロパティにはtype(関数の種類),angle(角度),matrix(設定値)の3つがあり,直接transform属性に設定した文字列を取得する方法は無い.

この3つのうち,matrixプロパティから得られるSVGMatrixオブジェクトはtransformの項で示したアフィン行列に相当するものだ.a〜fのプロパティから構成されており,これらの値を変更すると即座にグラフィックの内容が書き換わる.

( X Y 1 ) = ( a c e b d f 0 0 1 ) ( x y 1 )

例えば,e,fプロパティを書き換えることで平行移動を表現することが出来る.

リスト系オブジェクトのもつapi

これらのリスト状のオブジェクトに共通して次のインターフェースが実装されている.一般的なインデクサとlengthプロパティによる配列的なアクセスはできず,代わりにgetItemメソッドとnumberOfItemsプロパティを用いる.なお,firefox,operaにおいては配列と同様のインデクサが提供されているが,これはchromeで動作しないので注意のこと.

path要素とSVGPathSegオブジェクト

path要素のd属性についてはsetAttribute/getAttributeメソッドで中身を操作する他に,pathSegListプロパティ(SVGPathSegListオブジェクト)を介してパス切片(SVGPathSegオブジェクト)毎に編集できる.ここでパス切片とはパスを引く際のパス操作を指す.

path要素における操作にはMやLを始めとした合計19種類が存在するが,domではこのそれぞれに固有のオブジェクトが割り当てられている.以下にその一覧を示す.

操作オブジェクト内容種類type
--不明-0
z/ZSVGPathSegClosePathパスを閉じる-1
MSVGPathSegMovetoAbsパスを開始する絶対2
mSVGPathSegMovetoRel相対3
LSVGPathSegLinetoAbs直線を引く絶対4
lSVGPathSegLinetoRel相対5
CSVGPathSegCurvetoCubicAbs3次スプライン曲線を引く絶対6
cSVGPathSegCurvetoCubicRel相対7
QSVGPathSegCurvetoQuadraticAbs2次スプライン曲線を引く絶対8
qSVGPathSegCurvetoQuadraticRel相対9
ASVGPathSegArcAbs円弧を引く絶対10
aSVGPathSegArcRel相対11
HSVGPathSegLinetoHorizontalAbs水平線を引く絶対12
hSVGPathSegLinetoHorizontalRel相対13
VSVGPathSegLinetoVerticalAbs垂直線を引く絶対14
vSVGPathSegLinetoVerticalRel相対15
SSVGPathSegCurvetoCubicSmoothAbs3次スプライン曲線を引く(第一制御点省略)絶対16
sSVGPathSegCurvetoCubicSmoothRel相対17
TSVGPathSegCurvetoQuadraticSmoothAbs2次スプライン曲線を引く(制御点省略)絶対18
tSVGPathSegCurvetoQuadraticSmoothRel相対19

リストの中身を操作するためにはこれらのオブジェクトを識別する必要があるが,ご覧の通り名称が余りにも冗長なため,instanceof演算子による判定はいささか面倒である.そのためか,svgdomではこの他にpathSegTypeプロパティやpathSegTypeAsLetterプロパティが定義されている.前者はパス操作のタイプを返すもので,上の表におけるtype列の値を返す.後者はパス操作文字そのものを返す.type値を2で割るときれいに絶対位置指定,相対位置指定を分類できるので場合により使い分けるとよい.

また,パス切片オブジェクトのプロパティを操作する場合,いちいち型チェックをせずともそのオブジェクトがプロパティを持っているか(undefinedでない)を確認するだけで良い.

プロパティ種類説明M/mL/lC/cQ/qA/aH/hV/vS/sT/t
x終点のx座標 float 
y終点のy座標 float 
x1制御点1のx座標 float      
y1制御点1のy座標 float      
x2制御点2のx座標 float      
y2制御点2のy座標 float      
r1x座標方向の半径float
r2y座標方向の半径float
angle角度float
largeArcFlag円弧の選択boolean
sweepFlag円弧の方向boolean

※先頭のm操作はM操作と同等である.絶対位置指定・相対位置指定で処理を分ける必要がある場合は先頭のパス切片のみ例外処理としよう.

※A,a操作についてはフラグ値や角度が存在しているため,変形処理を行いにくい.事前にベジェ曲線に置き換えるなどしておくと良い.

このようにd属性を編集するのは面倒な場合が多いため,(path要素からglyph要素を生成するなど)特に必要がない限りpath要素を変形する場合はtransform属性を編集したほうが良い.

d操作のバリデート

手入力やスクリプトでパス操作を出力した場合,d属性の内容が正しい書式となっているとは限らない.ここでsvgの仕様においては,パス操作は問題のある箇所から後ろの部分を無視し,正しい部分までを描画することとなっており,pathSegListプロパティには正しい範囲のpathSegオブジェクトが格納されている.従って,pathSegListの内容からパス操作文字列を再構築することで,問題のあるd属性文字列から正しい部分のみを取り出すことができる.

内容の操作

子要素の全体を取得するプロパティとしては,childNodesを用いる.この場合無用なテキストノードが含まれてしまうが,これはノードのnodeTypeプロパティを確認することで要素ノード(1)かテキストノード(3)か判別できる.

なお,要素ノードのみを抽出可能なchildrenプロパティが存在する場合があるが,これは元来HTMLElementで利用可能なものであり,場合により不具合を引き起こす.※当初childrenを用いるとテキストノードが取り除かれて便利だとしていたが,これは間違いだと考えられる.実際chromeでエラーが発生してしまう.

aaabbbccc childNodes: children:

その他,firstChildやlastChildのと言ったものに加え,firstElementChild,lastElementChildといったプロパティを用いることもできる.これらのプロパティでは自動的にnodeTypeが1の要素ノードのみが抽出されるので使い勝手が良い.(これらはElement Traversal Specificationで定義されている.)

子要素の追加・削除はappendChild,removeChildメソッド等これまでと同様に行える.

style要素,script要素,text要素の内部のテキストにアクセスするにはtextContentを用いる.文字列のエスケープ(><&等)を自動的に行うため,扱いやすい.その一方であくまでテキスト部分にアクセスするものであるため,innerHTMLのような要素記述を挿入するといった用途には使えない.

svg要素のソースコードを取得する

svg要素の内容は次の何れかを利用することでsvgソースコードとして取得することが出来る.この仕組みを利用するとスクリプトで生成したsvgグラフィックを外部に取り出すことが出来るため,webブラウザをsvgエディタとして利用することも可能となる.

XMLSerializerを用いる

XMLSerializerオブジェクトのserializeToStringメソッドを用いることで簡単にdomの構成をテキストに変換することが出来る.

クリックでソースを表示

html要素のinnerHTMLプロパティを参照する

svg要素を囲んでいるhtml要素のinnerHTMLプロパティを参照することで間接的にコードの参照・書き換えは可能である.※本サイトではこのテクニックによりsvg要素部分のソースコードを直接ページ上に表示している.

クリックでソースを表示

また,ブラウザによってはxlink:hrefの属性名がhrefに切り詰められてしまうので,適宜書きなおす必要がある.

この機能で得られたsvgコードには名前空間の指定が欠落している場合がある.従って,スタンドアロンのsvgコードとして扱いたい場合は,予めsvgとxlinkの名前空間設定を明示すると良い.

クリックでsvgをダウンロード

svgのダウンロード

svgのソースコードを読み込む

svgはxmlをベースとしていることから,webブラウザのもつajax機構を利用することで外部のsvg画像を非同期に読み込むことも可能である.以下にXMLHttpRequestオブジェクトを使った外部svg読み込みのサンプルを示す.

<?xml version="1.0" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <script><![CDATA[
window.onload = function(){
    var req = new XMLHttpRequest();
    req.open("GET", "sample.svg", true);
    req.onreadystatechange = function(e){
        if(req.readyState != 4){return;}
        if(req.status == 200 || req.status == 0){
            var svg = req.responseXML.documentElement;
            svg.width.baseVal.value = 200;
            svg.height.baseVal.value = 200;
            document.documentElement.appendChild(svg);
        }
    };
    req.send(null);
};
    ]]></script>
</svg>

文字列データからsvg要素を生成する

スタンドアロンのsvgを利用している場合,svgのソースコードをdomオブジェクトに変換するにはDomParserオブジェクトを用いる.これはsvgにhtmlのinnerHTMLプロパティのような仕組みを持たないためである.この場合,正しくsvgdomとして解釈されるためにはソース内部に名前空間設定が含まれている必要がある.

<script>
    var source = "<svg width='200px' height='200px' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1'><circle cx='50' cy='50' r='40' fill='orange'/></svg>";
    var parser = new DOMParser();
    var svgDoc = parser.parseFromString(source, "text/xml");
    var svg = document.querySelector("#svgCanvas");
    svg.appendChild(svgDoc.documentElement);
</script>

インラインフレーム内部のsvgを操作する

親となるhtmlファイルと同じドメインのhtml/svg文書をiframe・object要素で参照している場合は,親文書からフレーム内部の構造を操作することができる.逆にimg要素等から参照したsvg画像をスクリプトから操作することは出来ない.(※ajax等で別途svgを読み込み,内容を編集してからdataスキーム形式にすると言ったやり方は考えられる.)

window.addEventListener("load", function(){
    var objElem = document.getElementById("objElem");
    //フレーム内部のsvg要素を取得する.
    var svg = objElem.contentDocument.documentElement;
    var circle = document.createElementNS("http://www.w3.org/2000/svg","circle");
    circle.cx.baseVal.value = 100;
    circle.cy.baseVal.value = 100;
    circle.r.baseVal.value = 80;
    circle.style.setProperty("fill", "green");
    circle.style.setProperty("fill-opacity", "0.5");
    svg.appendChild(circle);
},false);

図形要素の表示範囲を取得する

複雑な図形を定義した場合に,その図形を囲む矩形範囲が判ると何かと都合が良い場合がある.このような場合,getBBoxメソッドを実行することで図形の位置及びサイズをSVGRectオブジェクトとして取得することができる.この値にはstroke幅等が含まれず,純粋に図形のサイズとして算出される.

loadイベント直後など,svgの描画のタイミングによっては正しく値を取ることが出来ないようなので,適宜try-catch構文等でエラー制御を行うと良い.

animate要素でアニメーションしている図形についてもサイズを取得できるが,あくまでも図形要素が描画されている座標系における描画範囲なので,transform属性が設定されていた場合には得られる値と見た目の座標との間に乖離が発生する.

補足)svg micro domにおけるgetScreenBBoxについて

svg tiny 1.2のdomapi(svg micro dom)のメソッドではあるが,operaにおいてはgetScreenBBoxメソッドを用いることでtransform属性が設定されていた場合の見た目の表示範囲を取得可能だ.しかし,必ずしも正しい値とはならないようなので注意のこと.

文字の描画位置・範囲を取得する

text(及びtspan/textPath)要素によって描画されている文字の位置を取得するには専用のSVGTextContentElementインターフェースを利用すると良い.先ほどのgetBBoxメソッドがtext要素全体を対象とするのに対し,部分文字列に対する座標を求めることが出来る.以下にメソッドの相関について示す.

getNumberOfChars
文字数を取得する
getComputedTextLength
文字列の描画幅を取得する
getSubStringLength
部分文字列の描画幅を取得する
getExtentOfChar
文字の描画範囲をSVGRectオブジェクトとして取得する
getStartPositionOfChar
文字の描画基準座標をSVGPointオブジェクトとして取得する
getEndPositionOfChar
文字の描画終了座標をSVGPointオブジェクトとして取得する
getRotationOfChar
文字の傾きを取得する
getCharNumAtPosition
指定した(SVGPointオブジェクト)座標に描画されている文字の位置を取得する
selectSubString
指定した位置を選択済み(反転)とする.

文字が傾いていた場合,getExtentOfCharによって得られた矩形が実際のサイズよりも大きくなる点に注意しよう.を示す.

この例では傾きを考慮した上で文字を矩形で囲んでいるが,この矩形は簡単な三角関数による計算で求められる.

カーソル位置をsvg座標にマップする

webブラウザが捕捉するマウスイベント等の発生位置は,通常スクリーンやブラウザの描画位置を基準に行われるが,その際に左上を原点とする座標系(スクリーン座標)を考えることが出来る.一方svg図形はsvg要素の描画位置とサイズsvg要素のviewBox属性,preserveAspectRatio属性図形要素に対するtransform属性の3つから定まる座標系を基準に描画される.するとこの二つの座標系の間に変換行列(ScreenCTM)を考えることができる.

ここでスクリーン座標(X,Y)とsvg要素内部の座標(x,y)との間には次の関係が成り立つ.

( X Y 1 )=[ScreenCTM ] ( x y 1 )

通常カーソルイベントによって得られる座標値はスクリーン座標(X,Y)から求められるので,上記の式に左から[ScreenCTM]の逆行列を掛けることで次の式が成り立つ.

( x y 1 )=[ScreenCTM ] -1 ( X Y 1 )

この式に基づくと,下記の手順に従いスクリーン上のカーソル位置にsvg画像を描画する事が可能となる.

  1. スクリーン座標を取得し,SVGPointオブジェクトに座標を設定する.
  2. svg要素に対するSVGSVGElementオブジェクトを取得し,getScreenCTMメソッドからScreenCTMを取得する.
  3. ScreenCTMの逆行列を生成し,(1)の座標にこの逆行列を掛けて座標変換する.
  4. 得られたSVGPointが目的となるsvg画像内部の座標なので,これを基準に図形を描画する.

use要素に対する操作について

use要素はノードツリーを複製して図形を描画するが,SVGUseElementオブジェクトの持つinstanceRootプロパティから現在参照しているノードを操作することが出来る.なお,複製した図形要素にアクセスする方法は無い.現在operaでのみ動作する.

また,イベント処理を行う場合にuse要素が関連する場合は次のような注意点が存在する.通常イベントを発生したオブジェクトはイベントオブジェクトのtargetプロパティを参照することで取得できるが,この内容がブラウザによって異なるのだ.下記の例のようにuse要素で描画した内容をクリックすると,firefoxではSVGUseElementが,chromeとoperaにおいてはSVGElementInstanceオブジェクトが取得されてしまう.なお後者の場合はSVGElementInstanceオブジェクトのもつcorrespondingUseElementからその図形を生成したsvg要素への参照を得ることができるので,さほど問題とはならないはずだ.

イベント属性によるスクリプトのモジュール化

図形要素のonclick等のイベント属性にスクリプトを設定しておくと,use要素を使ってそのスクリプトごと要素をコピーすることができる.その際のスクリプトはコピーした文書内に参照先の要素がそのまま存在しているかのように動作する.この動作は外部svgを参照している場合も同様であり,イベントに関わる処理については外部モジュール化することが可能となっている.但しoperaでは動作しないようだ.

subMod.svgの内容
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <defs>
        <g id="clickable" onclick='
                dispMsg(this);
            '>
            <circle cx="100" cy="100" r="80"/>
            <text x="100" y="110" text-anchor="middle" fill="white">click me!</text>
        </g>
    </defs>
</svg>

但し,このテクニックを用いた場合に注意すべき点としては,先程示した通りイベントを発生したオブジェクトがchrome/operaではSVGElementInstanceであるのに対し,firefoxでは図形要素そのものが取得されてしまう点がある.これは明らかにfirefoxのバグ(w3cに準拠していない)と言える.

xlink:href属性の操作について

svgで頻出するhref属性はもともとxlinkにおいて定義されているプロパティなので,setAttributeメソッドを用いた場合やsetAttributeNSメソッドにおいて名前空間の設定を間違えると正しく動作しない.正しくxlinkに相当する"http://www.w3.org/1999/xlink"を指定するか,hrefプロパティを直接操作すること.これはxlinkを名前空間に持つ他の属性についても同様である.このようにsetAttributeNSメソッドによる値の設定は非常に間違いに気づきにくいと言ったデメリットが存在するため,できる事ならsvgdomが提供しているapiを利用するようにしたい.

画像の読み込み判定

image要素に対応するSVGImageElementは,htmlにおけるHTMLImageElementのcompleteプロパティに相当する機能を持たない.従って画像読み込みの完了処理はloadイベントを用いる必要がある.(が,chromeではこのloadイベントが発生しないようだ.)

同様に画像の読み込みに失敗したことを取得する場合はerrorイベントを用いると良い.ブラウザによっては読み込み失敗のアイコンが表示されてしまうので,visibility値をhiddenに設定し画像を隠してしまおう.

なおloadイベントは仕様ではsvg要素・image要素の他に設定することができるとあるものの,実際に試してみると動作しないようだ.

chrome対策

chromeにおいてimage要素のloadイベントが発生しない問題は代替としてhtmlのimg要素を用いることで回避することが出来る.foreignObject要素を宣言し,その中にimg要素を配置しておく.後は先ほどと同様に記述することで画像読み込み時・読み込み失敗時の処理を実行することが可能となる.

canvas要素との連携

文書に追加した要素はDOMツリー上に存在し続けるため,余りに多量の要素を追加した場合パフォーマンスに影響を及ぼす.この場合は,描画のタイミングを調整したり,svg要素で表現していた図形を事前に外部ラスタ形式の画像ファイル(pngやjpg)とできないか検討する.

もしくは描画後の動作が軽快なcanvas要素を利用する手もある.svg要素を全てcanvas要素で置き換えてもよいが,canvasのもつtoDataURLを使って描画処理の一部を置き換えることが出来る.toDataURLで得たdataスキーム形式の文字列をsvgのImage要素に設定して,svgに画像を埋め込んでしまうのだ.こうすると,svgの持つ「構造が保たれる,図形の移動・変形が容易」といったメリットを残しつつ,スクリプトの軽量化を図ることができる.

それとは逆にsvg画像をimg要素に読み込ませれば,canvas要素に書きこむことができる.だが,構造が複雑な場合エラーとなるケースがある.例えばcanvasで作った画像をsvgでfilterを掛けて再度canvasに書き戻すと言った処理は(クライアントサイドスクリプト単体では)実現が難しい.

なお,canvas要素にsvg画像を描画するライブラリcanvgを利用する方法もある.

スクリプトによるスタイルシートの切り替え

htmlではlink要素を操作することでも簡単にスタイルシートを切り替えることができるが,スタンドアロンのsvgにおいては概ね次の3つの方法が挙げられる.しかし実際に試してみると実用に耐える方法は非常に限られている.

代替スタイルを利用する

svg文書に適用されうるスタイルシートを予め代替スタイルシートとして定義しておき,それをスクリプトから操作する方法である.documentオブジェクトのselectedStyleSheetSetプロパティにtitleで定義したしたスタイルの名称を指定する.

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet href="cssa.css" type="text/css" title="main"?>
<?xml-stylesheet href="cssb.css" type="text/css" title="sub" alternate="yes"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <rect x="20" y="20" width="160" height="160"/>
    <script>
window.onload = function(){
    //selectedStyleSheetSetメソッドを使って代替スタイルに変更する.
    document.selectedStyleSheetSet="sub";
};
    </script>
</svg>

この方法ではブラウザのスタイルシート切り替え機構でユーザーが任意にスタイルを切り替えることができてしまうが,フレーム内でsvgを表示している場合は比較的無難な方法と言える.だが残念ながらchromeとoperaで動作しない.

ProcessingInstructionオブジェクトを用いる方法

xml-stylesheet処理命令を操作し,cssファイルの参照先を変更する.この方法は先ほどと異なりブラウザからスタイルを変更することは出来ないが,xml処理命令オブジェクトを取得するにはいささか面倒な手順を踏む必要があるため,使い勝手はさほど良くない.更にoperaにおいて正しく動作しないため,この方法はあまりお勧めできない.

下記の例ではスクリプトを使って「cssa.css」から「cssb.css」にスタイルシートの参照先を切り替えた例である.rect要素の塗り潰しが,redからblueに変化していれば正しく動作している.

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet href="cssa.css" type="text/css"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <rect x="20" y="20" width="160" height="160"/>
    <script>
window.onload = function(){
    //既存のxml-stylesheet処理命令にアクセスするには
    //[1]document.styleSheets.item(0)でStyleSheetオブジェクトを取得し,
    //[2]ownerNodeプロパティからProcessingInstructionオブジェクトを参照する.
    document.styleSheets.item(0).ownerNode.nodeValue = 'href="cssb.css" type="text/css"';
};
    </script>
</svg>

@import規則を用いる方法

新たにstyle要素を生成し,@import規則でcssファイルを読み込むもの.先ほどのxml-stylesheet処理命令を書き換えるのではなく,新たにcssを読み込むことで設定を上書きしてしまう.この方法は新たなapiを憶える必要がなく,firefox,chrome,operaの何れのブラウザでも動作するため,通常はこちらの方法を選択するのが良いだろう.

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet href="cssa.css" type="text/css"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <rect x="20" y="20" width="160" height="160"/>
    <script>
window.onload = function(){
    //style要素を生成し,文書に挿入する.
    var style = document.createElementNS("http://www.w3.org/2000/svg", "style");
    style.textContent = "@import url(cssb.css)";
    document.documentElement.appendChild(style);
};
    </script>
</svg>

ie9対策

しかしこのままではie9では正しく動作しない.この問題を回避するには,style要素を追加してから中身を書き換えるようにする.ieは古くからdomに追加されていないstyle要素の中身は無視されてしまうのだ.

<?xml version="1.0" standalone="no"?>
<?xml-stylesheet href="cssa.css" type="text/css"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
    <rect x="20" y="20" width="160" height="160"/>
    <script>
window.onload = function(){
    //style要素を生成し,文書に挿入する.
    var style = document.createElementNS("http://www.w3.org/2000/svg", "style");
    //先にスタイルを設定してから中身を書き換える.
    document.documentElement.appendChild(style);
    style.textContent = "@import url(cssb.css)";
};
    </script>
</svg>

アニメーションとスクリプト

document.documentElementメソッドで得られるSVGSVGElementには描画に関わる多くのメソッドが提供されている.描画を遅延させたり,描画を強制したりする他にアニメーションを制御することができるなど,興味深い内容となっている.多数のオブジェクトを操作する際,再描画を一括で行いたい場合に効果的と思われる.その他,矩形範囲における要素の包含チェック処理など,使い方によっては便利な機能が含まれる(だが,未実装なものが多い).

モーダルダイアログとアニメーション

alert関数,confirm関数,prompt関数を使い,モーダルダイアログを表示した場合でもanimate要素を用いたアニメーションはバックグラウンドで動作し続ける.これを止めたい場合はSVGSVGElementオブジェクトのもつpauseAnimationsメソッドとunpauseAnimationsメソッドを使ってアニメーションの実行を制御する.

スクリプトからアニメーションを制御する

animate要素にはアニメーションを制御するためのapi(TimeEventインターフェース)が定義されており,これを操作することでスクリプトからアニメーションの開始,終了を行うことができる.beginElement/beginElementAtメソッドはbegin属性に相当し,eneElement/endElementAtメソッドはend属性に相当する.At付きのメソッドは引数に指定した秒数が経過してから指定した動作が実行される.

begin end begin-to end-to

アニメーション途中の値を取得する

プレゼンテーション属性以外の属性値(例えばx,y等)については対応するプロパティのanimValプロパティを参照することでアニメーション途中の値を取得することができる.

cx:

一方プレゼンテーション属性に関わるアニメーション途中の値はwindowオブジェクトの持つgetComputedStyleメソッドを利用することで取得する事が可能だ.このメソッドで得られたCSSStyleDeclarationオブジェクトは,元の図形要素のstyleプロパティから得られるものとは異なるオブジェクトとなる.

fill-color:

アニメーションイベントのhtmlへの応用

animate要素はアニメーション処理に伴い「beginEvent」「endEvent」「repeatEvent」イベントを発生させるので,これらのイベントをトリガーとしhtml要素を制御すると言った処理を実装することが出来る.タイマー処理の代替や,様々な処理の同期を行うのに活用できそうだが,いかんせんchromeで動作しない.

この例ではアニメーションが繰り返される毎に以下の内容を書き換えている.0回繰り返した.

アニメーションとスクリプトの連携例

次の例はsvgで時計を作ったものである.animate要素で事前に時計の動きを定義し,スクリプト側ではアニメーションの経過時間を設定するようにした.このようにjavascriptとanimate要素とを組み合わせることで, 複雑となりがちなスクリプト部を短くまとめることが出来る.

アニメーションタイミングAPIの利用

webブラウザでのアニメーション処理はcssのanimateプロパティを使ったものやsmilを応用したもの等,現状でも様々なパターンのものが存在している.その際,これらの処理とjavascriptとの処理を同期させる為のapiが現在検討されており,現状でも一部のブラウザにおいて限定的に利用可能である.またこのapiはアニメーション処理に特化したものとなっているため,利用することでバックグラウンドに隠れた際のリソースのコストを低減し,バッテリー消費の削減を見込むことができると有る.

window.requestAnimationFrame
アニメーションフレームを要求する.コールバック関数はスクリーンの書き換えのタイミングで呼び出される.(callback)return long
window.cancelAnimationFrame
アニメーションの実行をキャンセルする.(handle)

例を示す.同期したいアニメーションの間隔は5秒なので,getCurrentTimeメソッドでアニメーション開始からの時間を取得し,それを5で割った余りが現在位置を計算する上での基準時刻となる.なおrequestAnimationFrame関数未実装のブラウザに対しても同様の動作をさせる場合は,setTimeout関数を用いて動作をエミュレートさせるようにすると良い.

※getCurrentTimeメソッドはブラウザ毎に挙動が異なるため,利用には注意を要する.(animate要素の有無,smilアニメーションの有無で挙動が変化する.)

なお,最終的にどのような形となるかはまだ分からないので,この機能を利用する場合はそのリスクを踏まえた上で利用すること.

svgdomのapi概観

以下に主なdomのapiを示す.スクリプトでどのようなことができるか前もって眺めておくと後で何かと便利だ.詳しくはw3cによるsvgの仕様の他にこちらもしくはこちらから調べることが可能だ.htmlにおけるdomの知識だけでもある程度のことは実現できるが,svgを自在に操るには専用のapiを知っておいたほうが良い.ただ,svgのapiの詳細に関するドキュメントが少なく,多分に手探りのプログラムが必要となってしまう.しかも元々の仕様に曖昧さが残るため,ブラウザ毎に各メソッドの挙動は驚くほどバラバラであるし,未実装なものも少なくない.簡単なプログラムでさえ単一の環境のみで動作を確認するのは非常に危険である.

アニメーションデータ型
各SVGElementのプロパティに設定されており,内部に元の値とアニメーション途中の値とを格納している.これらの値はSVGNumberを始めとするsvg基本データ型として定義されているため,ここから更にvalueプロパティを参照しなければならない.種類としては次のようなものがある.
SVGAnimatedAngle, SVGAnimatedBoolean, SVGAnimatedEnumeration, SVGAnimatedInteger, SVGAnimatedLength, SVGAnimatedLengthList, SVGAnimatedNumber, SVGAnimatedNumberList, SVGAnimatedPreserveAspectRatio, SVGAnimatedRect, SVGAnimatedString, SVGAnimatedTransformList
baseVal
元の値
animVal
アニメーション途中の値
svg基本データ型
svgにおける基本データ型を表す.valueプロパティにアクセスして値を書き換える.これらのオブジェクトを別途生成したい場合はSVGSVGElementオブジェクトに専用のメソッドが定義されている.種類としては次のようなものがある.なおオブジェクト毎に様々な機能を提供する.
SVGAngle, SVGColor, SVGICCColor, SVGElementInstance, SVGElementInstanceList, SVGLength, SVGLengthList, SVGMatrix, SVGNumber, SVGNumberList, SVGPaint, SVGPoint, SVGPointList, SVGPreserveAspectRatio, SVGRect, SVGStringList, SVGTransform, SVGTransformList
一般
value
値の参照
リスト系オブジェクト
appendItem
値の追加を行う.
clear
内容を初期化する.
getItem
指定した位置の値を取得する.
Initialize
与えられた値で内容を初期化する.
InsertItemBefore
指定した位置の前に値を挿入する.
removeItem
指定した位置の値を削除する.
replaceItem
指定した位置の値を引数の値に入れ替える.
numberOfItems
リストのサイズ
SVGPoint
x
x座標を取得する.
y
y座標を取得する.
SVGRect
x
x座標を取得する.
y
y座標を取得する.
width
幅を取得する.
height
高さを取得する.
SVGTransform
setMatrix
マトリクス変形を施す.
setRotate
回転変形を施す.
setScale
拡大・縮小を施す.
setSkeyX
せん断を施す.
setSkeyY
せん断を施す.
setTranslate
平行移動を施す.
angle
角度を取得する.
matrix
変形の内容を変換行列として取得する.
type
変換の種類を取得する.
SVGMatrix
a,b,c,d,e,f
アフィン行列の各セル値.
flipX
x軸での反転を表す行列を取得する.
flipY
y軸での反転を表す行列を取得する.
Inverse
逆行列を取得する.
multiply
行列の掛け算を行う.
rotate
行列に回転行列を掛ける.
rotateFromVector
行列に(座標指定に依る)回転行列を掛ける.
scale
行列に拡大縮小行列を掛ける.
scaleNonUniform
行列に拡大縮小行列(x軸,y軸別)を掛ける.
skewX
行列にせん断行列を掛ける.
skewY
行列にせん断行列を掛ける.
translate
行列に平行移動行列を掛ける.
SVGElementInstance
correspondingElement
図形のテンプレートとなった要素.
correspondingUseElement
図形を生成したuse要素.
SVGDocument
svg文書に相当するオブジェクト.HTMLDocumentとapiを多数共有している.
documentElement
一番外側のsvg要素に対応するオブジェクトへの参照.
location
svg文書のuri情報の取得.
createElementNS
名前空間を指定した要素の生成.
createTextNode
テキストノードの生成.
createCDATASection
CDATAセクションノードの生成.
getElementById
idを元にした要素の抽出.
getElementsByTagName
要素名を元にした要素の抽出.
getElementsByTagNameNS
名前空間を指定した要素名を元とした要素の抽出.
SVGElement
svgの各要素の基底となるオブジェクト.要素の抽出・生成に関わる部分でHTMLElementとapiを多数共有している.その他描画位置に関わるプロパティを持つ.
querySelector
セレクタ文字列による要素の抽出.
querySelectorAll
セレクタ文字列による要素の抽出.
cloneNode
要素を複製する.
ownerDocument
要素が属しているドキュメントオブジェクトへの参照.
ownerSVGElement
この要素が所属する最も内側のsvg要素.
viewportElement
この要素を表示するビューポートを生成している要素.(svg要素の他にもsymbol要素等のviewBox属性を含む要素が返る場合がある)
parrentNode
親要素.
childNodes
子要素のリスト.
childElementCount
テキストノードを除いた子要素の数.
firstChild
最初の子要素.
lastChild
(テキストノードではない)最後の子要素.
firstElementChild
(テキストノードではない)最初の子要素.
nextElementSibling
(テキストノードではない)次の要素.
previousElementSibling
(テキストノードではない)前の要素.
lastElementChild
最後の子要素.
appendChild
子要素を追加する.
removeChild
子要素を削除する.
replaceChild
子要素を置換する.
hasChildNodes
子要素の存在を確認する.
insertBefore
前に要素を挿入する.
addEventListener
イベントを定義する.
removeEventListener
イベントを削除する.
dispatchEvent
イベントを発生させる.
getAttribute
属性値を取得する.
getAttributeNS
属性値を取得する.
setAttribute
属性値を設定する.
setAttributeNS
属性値を設定する.
hasAttribute
属性の存在を確認する.
hasAttributeNS
属性の存在を確認する.
hasAttributes
属性の存在を確認する.
removeAttribute
属性を削除する.
removeAttributeNS
属性を削除する.
style
スタイルオブジェクト.setProperty([属性名],[設定値]),getPropertyValue([属性名]),removeProperty([属性名])で値の設定・取得・削除が可能.→CSSStyleDeclatation
className
クラス名称.但し中身はSVGAnimatedStringである.
transform
transform属性の設定値.中身はSVGAnimatedTransformList.
nodeType
ノードのタイプ.1:要素ノードを返す.(3:テキストノード)
CSSStyleDeclaration
styleプロパティの実体.
getPropertyValue
スタイル値を取得する.
getPropertyCSSValue
スタイル値を取得する.
removeProperty
スタイル値を削除する.
getPropertyPriority
important指定の有無を取得する.
setProperty
スタイル値を設定する.
cssText
css文字列
length
スタイル設定の長さ.
item
指定したインデックスのスタイル値のキーを取得する.
SVGSVGElement
svg要素に相当するオブジェクト.グラフィック描画に関わる機能を提供する.
suspendRedraw
描画を指定のミリ秒だけ中断する.
unsuspendRedraw
suspendRedrawで中断した描画を再開する.
unsuspendRedrawAll
suspendRedrawで中断した描画を全て再開する.
forceRedraw
描画を強制する.
pauseAnimations
アニメーションを中断する.
unpauseAnimations
アニメーションを再開する.
animationsPaused
アニメーションが中断されているか.
getCurrentTime
svgが読み込まれてから経過した秒数を取得する.(loadイベント発生時からの経過秒数)
setCurrentTime
経過秒数を上書きする.
getIntersectionList
矩形範囲と重なる描画要素のリストを取得する.
getEnclosureList
矩形範囲に含まれる描画要素のリストを取得する.
checkIntersection
描画要素が矩形範囲と重なるかを取得する.
checkEnclosure
描画要素が矩形範囲に含まれるかを取得する.
createSVGRect
矩形範囲を表すオブジェクトを生成する.
deselectAll
テキストの選択を解除する.
SVGPathElement
path要素に相当するオブジェクト.線分を引くためのメソッドが多数定義されている.生成されたパス切片はそれぞれ異なるAPIを持つ.
pathSegList
パス切片のリスト.
getTotalLength
パスの全長を取得する.
getPointAtLength
パスの指定した道のりに対する座標位置を取得する.
getPathSegAtLength
パスの指定した道のりに対するパス切片のインデックスを取得する.
createSVGPathSegClosePath
z操作(パスを閉じる)に相当するパス切片を生成する.
createSVGPathSegMovetoAbs
M操作(起点の移動)に相当するパス切片を生成する.
createSVGPathSegMovetoRel
m操作(起点の移動)に相当するパス切片を生成する.
createSVGPathSegLinetoAbs
L操作(直線の描画)に相当するパス切片を生成する.
createSVGPathSegLinetoRel
l操作(直線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoCubicAbs
C操作(3次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoCubicRel
c操作(3次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoQuadraticAbs
Q操作(2次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoQuadraticRel
q操作(2次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegArcAbs
A操作(円弧の描画)に相当するパス切片を生成する.
createSVGPathSegArcRel
a操作(円弧の描画)に相当するパス切片を生成する.
createSVGPathSegLinetoHorizontalAbs
H操作(水平線の描画)に相当するパス切片を生成する.
createSVGPathSegLinetoHorizontalRel
h操作(水平線の描画)に相当するパス切片を生成する.
createSVGPathSegLinetoVerticalAbs
V操作(水平線の描画)に相当するパス切片を生成する.
createSVGPathSegLinetoVerticalRel
v操作(水平線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoCubicSmoothAbs
S操作(3次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoCubicSmoothRel
s操作(3次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoQuadraticSmoothAbs
T操作(2次ベジェ曲線の描画)に相当するパス切片を生成する.
createSVGPathSegCurvetoQuadraticSmoothRel
t操作(2次ベジェ曲線の描画)に相当するパス切片を生成する.
SVGPathSegList
SVGPathElementにおけるパスを構成するパス切片のリストを表す.pathSegListプロパティから参照する.
SVGPathSeg
SVGPathElementにおけるパス切片を表す.SVGPathオブジェクトのもつ専用メソッドで生成する.種類としては次のようなものがある.
SVGPathSegArcAbs, SVGPathSegArcRel, SVGPathSegClosePath, SVGPathSegCurvetoCubicAbs, SVGPathSegCurvetoCubicRel, SVGPathSegCurvetoCubicSmoothAbs, SVGPathSegCurvetoCubicSmoothRel, SVGPathSegCurvetoQuadraticAbs, SVGPathSegCurvetoQuadraticRel, SVGPathSegCurvetoQuadraticSmoothAbs, SVGPathSegCurvetoQuadraticSmoothRel, SVGPathSegLinetoAbs, SVGPathSegLinetoHorizontalAbs, SVGPathSegLinetoHorizontalRel, SVGPathSegLinetoRel, SVGPathSegLinetoVerticalAbs, SVGPathSegLinetoVerticalRel, SVGPathSegMovetoAbs, SVGPathSegMovetoRel
pathSegType
パス切片の種類.
pathSegTypeAsLetter
パス切片の種類文字.
x
パス切片の終点座標.
y
パス切片の終点座標.
x1
制御点1のx座標.
y1
制御点1のy座標.
x2
制御点2のx座標.
y2
制御点2のy座標.
angle
a操作における角度.
largeArcFlag
a操作におけるlargeArcFlag値.
r1
a操作におけるx軸方向半径.
r2
a操作におけるy軸方向半径.
sweepFlag
a操作におけるsweepFlag値.
SVGAnimationElement
アニメーション要素(animate,animateMotion,animateColor,animateTransform,set)の基底となるオブジェクト.
getStartTime
アニメーションの開始秒数を取得する.
getCurrentTime
現在秒数を取得する.
getSimpleDuration
アニメーションの持続時間を取得する.
beginElement
アニメーションを開始する.
beginElementAt
引数に与えた秒数経過してからアニメーションを開始する.
endElement
アニメーションを停止する.
endElementAt
引数に与えた秒数経過してからアニメーションを停止する.
SVGUseElement
use要素に対応するオブジェクト.
instanceRoot
use要素が生成した図形オブジェクトインスタンス(SVGElementInstanceオブジェクト).
animatedInstanceRoot
use要素が現在表示している図形オブジェクトインスタンス(SVGElementInstanceオブジェクト).

イベント

svgにおいても各種イベントを利用することが出来る.イベントはスクリプト実行のトリガとすることが出来る他,アニメーションの実行トリガに指定することが出来る.通常rect要素などの図形を定義する要素によってイベントは生成され,それ以外の例えばg要素等はこれらの処理には関係しない.が,アニメーションに関わるイベントなど一部はそれ以外の要素が発生するものもある.但しイベントごとに実装状況が異なるので,十分な動作検証が必要である.以下は仕様書より抜粋したものでdomイベントについては記述を省いた.

focusin
onfocusin.
要素がフォーカスを得たときに発生する.textが選択されたとき等.
focusout
onfocusout.
要素がフォーカスを失ったときに発生する.textの選択が解除された時など.
activate
onactivate.
要素が活性化したときに発生する.1:単純クリック・Enter,2:ダブルクリック・shiftクリック
click
onclick.
要素上でポインティングデバイスをクリックした際に発生する.mousedown→mouseup→clickの順で発生する.
mousedown
onmousedown.
要素上でポインティングデバイスのボタンが押下された際に発生する.
mouseup
onmouseup.
要素上でポインティングデバイスのボタン押下が解放されたときに発生する.
mouseover
onmouseover.
要素の描画領域にカーソルが入った際に発生する.
mousemove
onmousemove.
要素の描画領域上でカーソルが動かされた際に発生する.
mouseout
onmouseout.
要素の描画領域からカーソルが出た際に発生する.
SVGLoad
onload.
svg要素の構文解析が完了した際に発生する.
SVGUnload
onunload.
最も外側のsvg要素でのみ発生.svg文書がウインドウやフレームなどから削除される際に発生する.
SVGAbort
onabort.
svg文書の読み込みが中断された際に発生する.
SVGError
onerror.
要素の読み込みに失敗した,もしくはスクリプトの実行時エラーの際に発生する.
SVGResize
onresize.
最も外側のsvg要素でのみ発生.文書ビューの大きさが変更された際に発生する.
SVGScroll
onscroll.
最も外側のsvg要素でのみ発生.文書ビューがずらされた際に発生する.
SVGZoom
onzoom.
最も外側のsvg要素でのみ発生.文書ビューのズーム度合いが変更された,もしくはcurrentScaleプロパティが変更された際に発生する.特色機能文字列「SVGZoomEvents」にてこのイベントをサポートするか判定することが出来る.
beginEvent
onbegin.
アニメーション要素が始動した際に発生する.
endEvent
onend.
アニメーション要素が停止した際に発生する.
repeatEvent
onrepeat.
アニメーション要素が繰り返された際に発生する.

keydown,keyup,keydown等のキーイベントはsvgの仕様そのものには定義されていないため利用することができない.例えば「<svg onkeypress="alert('')">…</svg>」といったコードは動作しない.その一方,windowオブジェクトでキーイベントを捕捉するスクリプトは正しく動作するので,こちらで代用する.html5の埋め込みsvgであればhtml要素でキーイベントを取得するようにする.

keydown
onkeydown.
キーボードのキーを押し下げた際に発生する.
keyup
onkeyup.
キーボードのキーを離した際に発生する.
keypress
onkeypress
キーボードのキーを押して離すという一連の動作をした際に発生する.

html埋め込みのsvg要素の場合はhtmlに準じたイベントが発生するため,これらに加えてドラッグドロップに関わるイベントが発生する.

dragstart
ondragstart.
ドラッグを開始時に発生する.
drag
ondrag.
ドラッグ中に発生する.
dragenter
ondragenter.
ドラッグ中にドロップ要素にカーソルが入った時に発生する.
dragleave
ondragleave.
ドラッグ中にドロップ要素からカーソルが離れた時に発生する.
dragover
ondragover.
ドラッグ中にカーソルがドロップ要素に重なっているときに発生する.
drop
ondrop.
ドロップ時に発生する.
dragend
ondragend.
ドラッグの終了時に発生する.

同様に環境によってはタッチイベントが発生しうる.これはiPhone等のiOS系の環境で実装されているイベントである.(※とりあえず掲載だけしています)

touchstart
ontouchstart.
タッチが開始した際に発生する.
touchend
ontouchend.
タッチが終了した際に発生する.
touchmove
ontouchmove.
タッチ箇所を移動した際に発生する.
touchcancel
ontouchcancel.
タッチがキャンセルされた際に発生する.

スクリプトの応用

スクリプトは様々な使い途があるが,ここでは有効な使い途についてのヒントとなるようなトピックスを紹介する.

svgに対応したjavascriptライブラリ

ここまでsvgdomをjavascriptで直接操作する方法を見てきた.これだけでも様々なスクリプト処理を行えることとなるが,いかんせん提供されている機能が貧弱であり,コードの記述量が増加する傾向にある.従って,何らかのフレームワークを導入してコーディングの負担を減らしたいところだが,svgに対応したライブラリには既に様々なものが存在する.何れも得意とする分野があるため,慎重に選択したい.

その他jQuery等のjavascriptライブラリによってはsvg用のアドオンが提供されているものもある.使い方に慣れているライブラリを使ってsvgを操作できるため,場合により導入を検討しても良いだろう.それでも,100%本来のライブラリの機能を利用できるとは考えないほうが良く,svg独自の処理が必要となるケースがある.

svgに未対応のブラウザの判定方法

htmlドキュメント内部でスクリプトを実行するにあたり,動作環境となるブラウザがsvgの描画に対応しているかを判定したい場合がある.このような場合は次のようにすると良い.

if(!window.SVGSVGElement){
    //svgをサポートしない場合
}else{
    //svgをサポートする場合
}

機能毎の実装状況を確認する場合はdocument.implementation.hasFeatureメソッドを利用する方法もある.これはswitch要素で行った処理をscriptで行なっていることになる.なおsvg1.0と1.1とで書式が異なるため,使い勝手はよくない.またブラウザの自己申告値なので,はっきり言って信用ならない.

SVG: SVG-static: SVG-animation: SVG-dynamic: SVGDOM: