この記事と関連の高い記事
関連キーワード:DOM- デベロッパーズコーナー:XMLとデータベース I(10)
- デベロッパーズコーナー:XMLとデータベース I(7)
- デベロッパーズコーナー:実践!XSLT(8)
- デベロッパーズコーナー:実践!XSLT(6)
- デベロッパーズコーナー:実践!XSLT(5)
- デベロッパーズコーナー:DOMプログラミング講座 II(1)
- 【リレーコラム:XMLの今と未来】 XMLを動かす
関連キーワード:SVG
ホーム > X-Plus > XML Square > デベロッパーズコーナー > 実践!SVG
本連載第1回では、SVGグラフィックを動かすにはSMIL AnimationとDOMの2つの方法があり、SMIL Animationの書き方を簡単に解説しました。第3回では、DOM+JavaScriptでSVG表示を変更したり動かしたりする方法を紹介します。
Adobe社の「SVG Viewer」をIEにプラグインして使います。Adobe社のダウンロードサイトからダウンロードしてください。指定されたインストール手順に従うと、IEにプラグインされます。
SVGファイル中にスクリプトを書き込むには、以下の2つの方法があります。
①<script>部分にスクリプトを書く
<script>部分にスクリプト言語を書き込みます。
<script>要素の書き方 <svg width="100" height="100"> <script type="text/ecmascript"> ・・・・・・コーディング・・・・・・ </script> ・・・・・・SVG要素・・・・・・ </svg> |
<svg>要素中のcontentScriptType属性にデフォルトのスクリプト言語を指定しておくことができます。デフォルト値は"text/ecmascript"なので、何も指定しないと"text/ecmascript"になります。また、<script>要素のtype属性に個々のスクリプト言語を指定することもできます。<script>要素は、HTMLの<script>要素と同じように、スクリプトを書くための場所を表します。
SMIL AnimationをSVG用に拡張したものが以下のものです。
*ECMAScriptは、標準化団体ECMAが1997年7月にECMA-262として策定したスクリプト言語です。競合していた2つの言語、Netscape社のJavaScriptとMicrosoft社のJScriptとを融合したものです。現在のバージョンは、1999年12月に公開された"3rd edition"です。 |
SVGでは、"onclick"や"onmouseover"などのイベント属性をSVG要素中に書き、イベントに対応した処理を行わせることができます。
SVG要素中の書き方 (1) <rect onclick="create_obj(evt)" x="100" y="100" width="200" height="50" /> =>マウスをクリックすると、スクリプト中で定義されたcreate_obj(evt)関数が呼び出される。 (2) <rect x="100" y="100" width="200" height="50" fill="none" onmouseover="evt.target.setAttribute('fill', 'red')"/> =>矩形の上をマウスが通過すると、矩形が赤に塗りつぶされる。 |
多くの場合、最初の例のようにスクリプト中で定義された関数を呼び出すためにイベント属性が使われますが、2番目の例のように属性の中に直接JavaScriptのコマンドを書くこともできます。2番目の例では、DOMのsetAttribute()メソッドを使用しています。
SVGは、以下のイベント属性をサポートしています。
表1 SVG要素中で使用できるイベント属性
イベント属性
|
イベント発生時
|
グラフィック要素とコンテナ要素のイベント属性 | |
onfocusin | 要素がフォーカスされたとき |
onfocusout | 要素のフォーカスが解除されたとき |
onactivate | 要素がアクティブになったとき |
onclick | クリックされたとき |
onmousedown | 要素上でポインティング・デバイスのボタンが押されたとき |
onmouseup | 要素上でポインティング・デバイスのボタンが放されたとき |
onmouseover | 要素内にポインティング・デバイスが移動してきたとき |
onmousemove | 要素上でポインティング・デバイスが移動しているとき |
onmouseout | 要素外にポインティング・デバイスが去ったとき |
onload | 要素と子孫を完全に解析し、その要素の処理に入るとき |
ドキュメント・レベルのイベント属性 | |
onunload | DOMインプリメンテーションがドキュメントをウィンドウやフレームから削除したとき |
onabort | 要素のロードが完全に終了する前にページロードが停止したとき |
onerror | 要素が正しくロードされなかった場合やスクリプト実行中にエラーが発生した場合 |
onresize | ドキュメント表示のサイズが変更された場合 |
onscroll | ドキュメント表示がX方向またはY方向に、あるいはその両方向にシフトしたとき |
onzoom | ドキュメントがズームレベルをユーザー操作に応じて変更するとき |
アニメーション・イベント属性 | |
onbegin | アニメーション要素が開始したとき |
onend | アニメーション要素が終了したとき |
onrepeat | アニメーション要素が繰り返すとき |
では実際に、DOMによりグラフィックをダイナミックに変更するスクリプトを書いてみましょう。
①色や大きさを変更する
簡単な矩形を表す次のファイルをベースに考えてゆきます。
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="12cm" height="10cm"> <rect x="2cm" y="2cm" width="8cm" height="6cm" rx="50" ry="50" fill="blue" stroke="blue"/> </svg> |
これは、青色に塗りつぶされた矩形を表します。この矩形をクリックすると赤色の塗りつぶしに変わるように書き換えてみましょう。
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="12cm" height="10cm"> <rect onclick="evt.target.setAttribute('fill', 'red')" x="2cm" y="2cm" width="8cm" height="6cm" rx="50" ry="50" fill="blue" stroke="blue"/> </svg> |
このサンプルでは、DOMのElementオブジェクトのsetAttributeNode()メソッドを使用し、クリックされたら"fill"属性の属性値を"red"に変更するようにしています。
ではさらに、塗りつぶしの色だけでなく矩形の大きさも変更してみましょう。JavaScriptでは、複数のコマンドを書き込むときにはセミコロン(";")で分離して書くことができます。
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="12cm" height="10cm"> <rect onclick="evt.target.setAttribute('fill', 'red');evt.target.setAttribute('width', '4cm');evt.target.setAttribute('height', '3cm')" x="2cm" y="2cm" width="8cm" height="6cm" rx="50" ry="50" fill="blue" stroke="blue"/> </svg> |
このように簡単なスクリプトであればイベント属性の値に直接書き込むことができます。一方、複雑な処理を行わせたい場合には<script>部分に処理を定義した関数を書き、それを呼び出す必要があります。たとえば、「サンプルファイル1」で、クリックするたびに色を変更したり元に戻したりしたい場合、次のように書きます。
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="12cm" height="10cm"> <script type="text/ecmascript"> <![CDATA[ function click_colorsize(evt) { var color = evt.target; var currentcolor = color.getAttribute("fill"); if (currentcolor == "blue") color.setAttribute("fill", "red"); else color.setAttribute("fill", "blue"); } ]]> </script> <rect onclick="click_colorsize(evt)" x="2cm" y="2cm" width="8cm" height="6cm" rx="50" ry="50" fill="blue" stroke="blue"/> </svg> |
②同じ形のグラフィックを作成する
①と同じような要領で、クリックするたびに同じ形の矩形を少しずつずらして作成してゆくサンプルを書いてみましょう。
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg id="rect" width="400" height="200"> <script> <![CDATA[ var n=0; function clone_obj(evt) { svgdoc=evt.getTarget().getOwnerDocument();n=n+1; obj=svgdoc.getElementById("original"); var newnode = obj.cloneNode(false); newnode.setAttribute ("x",20+10*n/2); newnode.setAttribute ("y",20+10*n/2); var contents = svgdoc.getElementById ('rect'); newnode = contents.appendChild (newnode); } ]]> </script> <rect id="original" onclick="clone_obj(evt)" x="20" y="20" width="180" height="80" rx="50" ry="50" fill="blue" stroke="yellow"/> </svg> |
上のサンプルでは、以下のDOMメソッドが使われています。
getElementById()・・・・・id属性によって特定の要素を取り出す
cloneNode()・・・・・・・・ノードをコピーする
setAttribute()・・・・・・・新しく生成されたオブジェクトに属性を結びつける
appendChild()・・・・・・・newChildを子ノードの最後に加える
③グラフィックを回転させる
次に、クリックするたびにグラフィックを少しずつ右回転させてみましょう。
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="600" height="300"> <script> <![CDATA[ var angle=0; function trans_obj(evt) { svgdoc=evt.getTarget().getOwnerDocument(); angle=angle+0.5; objet=svgdoc.getElementById("rect"); transm="matrix("+Math.cos(angle)+" "+Math.sin(angle)+""+(-1*Math.sin(angle))+" "+Math.cos(angle)+"300 150)"; objet.setAttribute ("transform",transm); } ]]> </script> <rect id="rect" onclick="trans_obj(evt)" x="-75" y="-50" width="150" height="100" fill="blue" stroke="yellow" transform="matrix(1 0 0 1 300 150)"/> </svg> |
このサンプルファイルは、クリックするたびに(300,150)を中心にして回転します。"angle=angle+0.5"でクリックするたびに角度を増やしてゆき、その角度に応じた値をtransform属性のそれぞれの値に設定してゆきます。
matrix(cos(a) sin(a) -sin(a) cos(a) 300 150)は、座標軸を(300,150)を中心にaだけ回転させることを表します。
④カーソルの移動に合わせてグラフィックを移動する
最後に、カーソル位置の移動に合わせてグラフィックも移動してゆくサンプルを考えてみましょう。
<?xml version="1.0"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd"> <svg width="600" height="400" onload="getRect()" onmousemove="movedXY(evt)"> <script> <![CDATA[ function getRect() { move = document.getElementById("movec"); } function moveCursor(currentx,currenty) { move.setAttribute("x", currentx); move.setAttribute("y", currenty); } function movedXY(e) { var currentx = e.getClientX(); var currenty = e.getClientY(); setTimeout('moveCursor('+currentx+','+currenty+')',10); } ]]> </script> <rect width="100%" height="100%" style="opacity:0;"/> <rect id="movec" fill="blue" width="20" height="20" /> </svg> |
SVGは、単なるベクタ・グラフィック記述言語であるにとどまらず、DOMやJavaScriptと組み合わせて使うことでダイナミックで対話的な処理を可能にします。新しいWebアプリケーション開発を可能にする、Webグラフィック標準となることが期待されています。