SVGのグラデーションとJavaScriptとの連携
グラデーション効果の応用例
SVGのグラデーションを使えば、以下のようなグラデーション付きのボタンなどを、画像ファイルなしで作成することができます。
グラデーションを使ったボタン(svg-gradient-button.html)
<svg> <defs> ↓グレーから黒の線形グラデーション定義 (x2,y2) = (0%,100%)なので方向は上から下 <linearGradient id="liner" x2="0%" y2="100%"> <stop offset="25%" stop-color="#aaaaaa"/> <stop offset="75%" stop-color="#222222"/> </linearGradient> </defs> <rect x="20" y="150" width="150" height="50" rx="10" ry="10" fill="url(#liner)" /> ↑グラデーションを使って角丸の四角形を描画 <text x="70" y="185" font-family="Impact" font-size="32" fill="white">Top</text> ↑text要素で文字列を表示 <rect x="230" y="150" width="150" height="50" rx="10" ry="10" fill="url(#liner)" /> <text x="247" y="185" font-family="Impact" font-size="24" fill="white">What's new</text> </svg>
図5:グラデーションを使ったボタン(クリックで拡大) |
SVGで作成することで、色やフォント、ボタンの中の文字列を少し変更する、といった場合にも、画像ファイルを再作成する必要がなくなり、スムーズな修正が行えます(*)。
(*)なお、CSS3にもグラデーション機能(gradientプロパティ)があるため、同じように画像なしでグラデーション付きのボタンなどを作成できます。
SVGをJavaScriptから操作する
続いてSVGをJavaScriptから操作する方法について解説します。SVGの要素がHTML内に埋め込まれるインラインSVGでは、通常のDOM操作と同じような流れでSVGの要素の属性を書き換えたり、新しいSVGの要素を追加したりすることで、SVGに変更を加えることができます。
以下は、ボタンを押すとSVGの描画要素の背景色が変わったり、新しい図形が増えたりするサンプルです。
SVGの表示サンプル(svg-javascript.html)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <title>SVG</title> <script> //既存のSVGの要素の属性値を変更する関数 function changeColor(){ //普通通りid属性でcircle要素を取得 var circle1 = document.getElementById('circle1'); //setAttributeメソッドでfill属性の値を青に変更 circle1.setAttribute("fill","#0000ff"); } //新しいSVGの要素を作成する関数 function addRect(){ //id属性でsvg要素を取得 var svgElement = document.getElementById('svg'); //新しいSVGの要素(rect)を作成。createElementNSメソッドを使うことに注意 var newRect = document.createElementNS("http://www.w3.org/2000/svg", 'rect'); //SVGの各種属性を設定していく newRect.setAttribute("x",100); newRect.setAttribute("y",50); newRect.setAttribute("width",50); newRect.setAttribute("height",40); newRect.setAttribute("fill","#00ff00"); //作成したrect要素をsvg要素の下に追加(=描画される) svgElement.appendChild(newRect); } </script> </head> <body> <svg id="svg"> <circle id="circle1" cx="100" cy="100" r="25" fill="#ffff00" stroke="#ff0000" /> <polygon points="50,50 100,50 100,100 50,50" fill="#ff0000" stroke="#ff0000" /> </svg> <button onclick="javascript:changeColor()" >Change circle color</button> <button onclick="javascript:addRect()" >Add rectangle</button> </body> </html>
ここでは、2つのボタンを用意し、それぞれ既存のSVGの要素の属性値を変更するchangeColor関数と新しいSVGの要素を作成するaddRect関数を呼ぶようにしています。
changeColor関数では、既存のSVGの要素を通常通りDOMのgetElementByIdメソッドを使って取得し、setAttributeメソッドで属性値を書き換えています。ここでは塗りつぶしのfill属性値を青に変更しています。実行結果は以下の通りです。
図6:変更前のSVG(クリックで拡大) |
図7:[Change circle color]ボタンを押すと円の塗りつぶし色が変化する(クリックで拡大) |
addRect関数では、新しいSVGの要素としてrect要素を作成しています。注目したいのは、通常のDOM操作で要素を作成する時に使用するdocument.createElementメソッドではなく、document.createElementNSメソッドを使用している点です。
これは、SVGがもともとHTMLの一部ではなく、別の仕様であることに関係しています。HTMLもSVGもベースとなっているのはXML(eXtensible Markup Language)ですが、XMLでは、様々な仕様で要素や属性の名前がぶつかってしまわないよう、名前空間という機能を提供しています。例えば、SVGにもハイパーリンクを表すa要素がありますが、これはHTMLのa要素とは別のものとして扱われます。
さて、ここで使用しているcreateElementNSの末尾のNSは名前空間(NameSpace)を表しており、最初の引数の"http://www.w3.org/2000/svg"はURLではなく、SVGの名前空間を表しています。つまりこのcreateElementNSでは「ここでrect要素を作成しますよ。といっても、このrect要素はHTMLに所属するのではなく、SVGに所属する要素ですよ」と指定しているわけです。
複雑なのはこの部分だけで、後は先ほどと同じようにsetAttributeメソッドで属性値を適宜設定した後、appendChildメソッドを使ってsvg要素の子要素として追加しています。これにより、以下のようにrect要素による四角形が描画されます。
図8:[Add rectangle]ボタンを押すと新しい四角形が追加される(クリックで拡大) |
このように、HTMLに埋め込まれたインラインSVGをJavaScriptから扱う場合、通常のDOM操作でHTMLを扱うのと同じような流れとなります。HTMLを処理する場合と同様に、jQueryなどのJavaScriptライブラリを活用することで、コード量を削減できるでしょう。ただし、SVGの要素を作成する場合は、jQueryなどが提供するHTMLの要素を作成する機能ではなく、createElementNSメソッドを使ってSVGの名前空間を指定するようにしましょう。
SVGのグラデーション、JavaScriptとの連携サンプル