SVGのグラデーションとJavaScriptとの連携

2012年5月17日(木)
土井 毅(著)山田祥寛(監修)

グラデーション効果の応用例

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

著者
土井 毅(著)山田祥寛(監修)
WINGSプロジェクト

有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表:山田祥寛)。おもな活動は、Web開発分野の書籍/雑誌/Web記事の執筆。ほかに海外記事の翻訳、講演なども幅広く手がける。2011年3月時点での登録メンバは36名で、現在もプロジェクトメンバーを募集中。執筆に興味のある方は、どしどしご応募頂きたい。著書多数。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています