Inline SVGを使うにあたってつまづいたところ

Tetsuro Aoki 269views 更新:2015年10月30日

HTML5で描画というとCanvasタグが有名ですがHTML内に直接SVGを記述できるInline SVGも魅力的です。
個人的には描画範囲内でクリックイベントなんかを取りたい時はInline SVGの方が断然使い勝手がいいと思います(CanvasでもできるけどAPIの実装状況が結構怪しい)。
そんなInline SVGですが実際に触ってみたら結構つまづくポイントがあったので簡単にまとめたいと思います。

動的に生成した要素が表示されない

例えば以下みたいなことをしても表示されません。
ディベロッパツールなんかで見ると確かに要素は入ってはいるのですが・・・

var line = $.('<line></line>, {
  x1: 0,
  y1: 0,
  x2: 100,
  y2: 100,
  'stroke-width': 5,
  stroke: 'rgb(255, 0, 0)'
});

$('#svg').append(line);

この場合、createElementNSという関数で要素を生成しなくてはいけないようです。
属性はsetAttributeでつけます。

var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
svg.setAttribute('x1', 0);
svg.setAttribute('y1', 0);
svg.setAttribute('x2', 100);
svg.setAttribute('y2', 100);

$('#svg')[0].appendChild(line);

z-indexを指定できない(SVGタグ編)

基本的にSVGにCSSは効きません。
でもz-indexなんかはどうしても適用させたいときがあります。
そんなときはSVG自体をdivで囲んでdivにcssを適用させます。

<img id="img" src="sample.jpg">
<div id="svgContainer">
  <svg></svg>
</div>
#img {
  z-index: 1;
}

#svgContainer {
  z-index: 2;
}

z-indexを指定できない(SVG要素編)

SVG内の要素(lineとかpathとか)は基本的に後に記述されたものが上に表示されます。
なのでJS側で動的に生成した要素を、すでに描画されている要素の下に後から追加したいときなんかは結構面倒なことになります。
CSSが効かないのでz-indexは使えません。JS側でsvgタグの子要素を探索して適切な位置にノードを挿入、という感じになるでしょうか。
あるいはいくつかの要素をまとめてレイヤのようにz-indexを制御したい場合はg要素が使えます。

<svg>
  <g id="layer1">
    <line />
  </g>
  <g id="layer2">
    <path />
  </g>
</svg>

こんな感じでg要素に対してappendChildすれば特に前後関係を気にせず要素の追加が行えます。

ログイン / 新規登録してコメントする

このソースコードをストックして後で利用したり、作業に利用したソースコードをまとめることができます。

こちらもお役に立つかもしれません