embedding inline svg

HTMLに直接SVG埋め込んでごにょごにょしたくてハマったのでメモ。

HTML5の仕様上インラインSVGは認められているものの、現状対応してるのはIE9とFirefox4のみらしい。その他のブラウザはHTML内で以下のように記述してもSVGは描画されない。

<html xmlns="http://www.w3.org/1999/xhtml">
<body>
	<svg width="100" height="100" viewBox="0 0 100 100">
		<rect x="0" y="0" width="50" height="50" />
	</svg>
</body>
</html>

解決方法は3通り、
1. objectタグで埋め込み
2. XHTMLに記述する
3. JavaScriptで記述する

今回はダイナミックに図形を書き換えたいので1はNG。拡張子がxhtmlに変わるのがキモイので2もNG。よって今回は3のjsによるアプローチを試した。

HTMLは先ほどと同じ。SVGをラップするdivタグを用意。

<html>
<body>
	<div id="svg"></div>
</body>
</html>

まずHTMLとSVGの名前空間を分離するためにSVG用の名前空間を用意。

var svgNS ="http://www.w3.org/2000/svg";

createElementNSで先ほど用意したSVG用の名前空間にsvgタグを作る。

var svg = document.createElementNS(svgNS, "svg");

各要素をセットする。

svg.setAttribute("width", 100);
svg.setAttribute("height", 100);
svg.setAttribute("viewBox", "0 0 100 100");

ラッパーdivを捕捉して先ほど作ったSVGタグを追加する。

var wrapper = document.getElementById(wrapperId);
wrapper.appendChild(svg);

これでsvgの用意はok。あとはSVGの名前空間の方に要素を追加、操作すればいい。
例:円を描画。

var circle = document.createElementNS(svgNS, 'circle');
circle.setAttribute('cx',50);
circle.setAttribute('cy',50);
circle.setAttribute('r',50);
svg.appendChild(circle);

結論、クソめんどいからSVGをまるっとラップしたショートカットクラスが欲しい。
あった。