スタートアップ SVG

第3回 少し高度なSVG

この記事を読むのに必要な時間:およそ 6 分

前回はSVGの基本的な書き方を解説しました。今回は前回触れなかった座標変換・テキスト関連に,グラデーションを解説していきます。

座標とグループ化

SVGにはg要素という複数の要素をまとめるための要素があります。このg要素によってグループ化した要素に同じ色を適用したり,座標変換(後述)をすることなどができます。

グループ化のサンプルコード(SVG)

<g fill="#33ff33">
  <rect x="40" y="40" width="30" height="30" />
  <polygon points="0,0 43.3,25 0,50"/>
</g>

グループ化のサンプルコード(SVGDOM)

// g(group)要素を作成
var g = document.createElementNS(SVG, 'g');
g.style.fill = '#3333ff';

var rect = document.createElementNS(SVG,'rect');
rect.setAttribute('width', 30);
rect.setAttribute('height', 30);
rect.setAttribute('x', 40);
rect.setAttribute('y', 40);

var triangle = document.createElementNS(SVG,'polygon');
triangle.setAttribute('points', '0,0 43.3,25 0,50');

g.appendChild(rect);
g.appendChild(triangle);

Raphaelではsetを使うことでグループ化に近い処理が可能です。ただし,構築されるDOMを確認するとg要素は作られていないため,中身は異なることに注意が必要です。

グループ化のサンプルコード(Raphael)

var st = paper.set();
st.push(
        paper.rect(40, 40, 30, 30),
        paper.path("M0,0 L43.3,25 L0,50 z")
);
st.attr({fill: "#ff3333"});
st.attr({stroke: "none"});
グループ化のサンプル
(SVG)
グループ化のサンプル
(SVGDOM)
グループ化のサンプル
(Raphael)

このg要素にはx, y座標もありませんし,widthやheightなども持っていませんが,その代わりに,transform属性によって位置や形状を操作することができます。

transformのサンプルコード(SVG)

<g fill="#33ff33" transform="translate(60,10) rotate(60)">
  <rect x="40" y="40" width="30" height="30" />
  <polygon points="0,0 43.3,25 0,50"/>
</g>

transformのサンプルコード(SVGDOM)

// g(group)要素を作成
var g = document.createElementNS(SVG,'g');
g.setAttribute('fill', '#3333ff');
g.setAttribute('transform', 'translate(60,10) rotate(60)');

Raphaelでは次のように,rotate,translate,scaleといったメソッドが用意されています。しかし,前述の通り,setはg要素に対応しているわけではないため,描画はSVG版と異なってしまいます。

transformのサンプルコード(Raphael)

var st = paper.set();
st.push(
    paper.rect(40, 40, 30, 30),
    paper.path("M0,0 L43.3,25 L0,50 z")
);
st.attr({fill: "#ff3333"});
st.attr({stroke: "none"});
st.rotate(60);
st.translate(60, 10);
transformのサンプル
(SVG)
transformのサンプル
(SVGDOM)
transformのサンプル
(Raphael)

transform属性にはtranslate(移動)⁠scale(拡大・縮小)⁠skewX(x方向の傾き)⁠skewY(y方向の傾き)⁠rotate(回転)に加えてmatrix(行列)を指定できます。translateはx軸,y軸をそれぞれ指定でき,y軸は省略できます。scaleは引数1つで比率を保ったままの拡大縮小,引数2つでx軸とy軸を個別に伸縮できます。skewX,skewYはそれぞれ引数を1つだけ持てます。matrixは移動・拡縮・傾き・回転を1つの行列で表現できます。matrixの引数は6つあり,

  • matrix(x軸の伸縮, y軸の傾き, x軸の傾き, y軸の伸縮, x軸の移動, y軸の移動)

に対応します。matrixで回転させたい場合は,次のようにsin,cos関数から伸縮と傾きを求める必要があります。

matrixによる回転と移動

var rad = Math.PI*2/360*60;
g.setAttribute('transform', 'matrix('+Math.cos(rad)+' '+Math.sin(rad)+' -'+Math.sin(rad)+' '+Math.cos(rad)+' 60 10)');

なお,transformにおいて注意しなければいけないのが,

 transform="translate(60,10) rotate(60)"

 transform="rotate(60) translate(60,10)"

で結果が異なるという点です。移動後の回転と,回転後の移動では中心点との関係が変わるためです。transformは右側から順に適用されるので,上記のサンプルは次のように書いた場合と同じ描画になっています。可読性を優先してこのように要素を分けてもよいでしょう。

transformのサンプルコード(SVG)

<g fill="#33ff33" transform="rotate(60)">
  <g transform="translate(60,10)">
    <rect x="40" y="40" width="30" height="30" />
    <polygon points="0,0 43.3,25 0,50"/>
  </g>
</g>

著者プロフィール

太田昌吾(おおたしょうご,ハンドルネーム:os0x)

1983年生まれ。JavaScriptをメインに,HTML/CSSにFlashなどのクライアントサイドを得意とするウェブエンジニア。2009年12月より、Google Chrome ExtensionsのAPI Expertとして活動を開始。

URLhttp://d.hatena.ne.jp/os0x/

コメント

コメントの記入