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との連携サンプル





