HTML5 SVGでバーコード描画してみる

これは「[HTML5 canvasにバーコードを描画してみる](http://qiita.com/Urushibara01/items/2048cfe4dfdb9203627b)」の続きです。
バーコードの仕様については前の記事に書いています。
##SVGってなんじゃらほい？
最近流行りの、描画用のHTMLタグです。pathタグの d 属性に描画コマンドを書けば表示される仕組み。
ドットではなくベクターなので拡大縮小してもジャギが出ないというイラレチックなアレです。

pathのd属性をパット見ると、むかしのBASICのPLAY構文(MML)にソックリ。
実際、考え方もそっくりで、アルファベット(コマンド) + データという風な作りらしい
参考ページを読んでみるとコマンドがCanvasオブジェクトとほぼ互換だとわかった。
![image](https://qiita-image-store.s3.amazonaws.com/0/102207/e7009eca-4188-41ed-7654-3839ccee9f9e.png)

参考ページ：[svg要素の基本的な使い方まとめ](http://www.h2.dion.ne.jp/~defghi/svgMemo/svgMemo_03.htm)

##CanvasからSVGに変更してみる

```javascript:テストコード
<!DOCTYPE html>
<html>
<head>

<script>

//キャラクタパターン情報(CODE39)
var pattern = {
	'0':0xB65,'1':0xD4B,'2':0xD4D,'3':0xA9B,'4':0xD65,'5':0xACB,'6':0xACD,'7':0xDA5,'8':0xB4B,
	'9':0xB4D,'A':0xD2B,'B':0xD2D,'C':0xA5B,'D':0xD35,'E':0xA6B,'F':0xA6D,'G':0xD95,'H':0xB2B,
	'I':0xB2D,'J':0xB35,'K':0xCAB,'L':0xCAD,'M':0x95B,'N':0xCB5,'O':0x96B,'P':0x96D,'Q':0xCD5,
	'R':0x9AB,'S':0x9AD,'T':0x9B5,'U':0xD53,'V':0xD59,'W':0xAB3,'X':0xD69,'Y':0xAD3,'Z':0xAD9,
	'-':0xDA9,'.':0xB53,' ':0xB59,'$':0xA49,'/':0x949,'+':0x929,'%':0x925,'*':0xB69};

//jQueryで言う $(document).ready() のネイティブコード
document.addEventListener('DOMContentLoaded', function() {

	//バーコード化するデータ(先頭と末尾はスタート・ストップキャラ)
	var code_str = "*12345678*";
	//バーの幅
	var bar_width = 4;

	var command = [];
	var txt_x = [];

	for(var pos = 0; pos < code_str.length; pos++){
		//一文字ずつ読み込み
		var key = code_str.charAt(pos);
		//パターン情報を読み込む
		if(!pattern[key]) continue;
		var pat = pattern[key];

		//キャラクタごとの描画位置
		//文字位置 * (12ビット + キャラクタ間ギャップ) x バー幅
		var left = pos * (12 + 1) * bar_width;
		command[pos] = "";

		//2進数12ビットのパターン情報を1ビットずつ走査してバーを描画
		for(var i=0; i<12; i++){
			//ビットが1ならバー描画
			if( (pat & (1<<i)) > 0 ){
				//バーの X座標
				var x = i * bar_width + left;
					
				//バー描画
				command[pos] += "M" + x + ",0";  //context.moveTo(x, 0)
				command[pos] += "L" + x + ",100" //context.lineTo(x, 100)
			}
		}
		//文字のx座標を定義(textタグ用)
		txt_x[pos] = (left + bar_width * 6);
	}

	//作成したPathコマンドをSVGへ反映
	var view = document.getElementById("svg_view");
	for(let d of command){
		view.insertAdjacentHTML("beforeend", //$("svg_view").append()
		'<path stroke="black" stroke-width="4" fill="none" d="' + d + '"/>');
	}
	//テキストを描画
	var text = document.getElementById("code_chr");
	text.innerHTML = code_str;
	text.setAttribute("x", txt_x.join(" "));
	text.setAttribute("y", 120);

});

</script>

</head>
<body>

<!--SVG Wiew-->
  <svg viewBox="0 0 800 400" id="svg_view">

	<text id="code_chr" style="font-size:22px;"></text>
  
  </svg>

</body>
</html>
```

[動作サンプル](https://embed.plnkr.co/8bcv4l/)

描画結果
![image](https://qiita-image-store.s3.amazonaws.com/0/102207/eda617e0-2031-b2ff-e153-5a692bc94619.png)


Camvasに描画する場合と基本的なことはなにも変更はありません。
文字列の描画方法がCanvasよりも優秀になっていて、文字列を文字ごとに座標を指定する場合も、いちいち分解して描画する必要もありませんでした。

もし帳票印刷をHTMLとCSSベースで行いたい場合はこちらのほうが使いやすいと思います。

##<span class="label label-default">追記</span>あらかじめパターン毎のpathを作成するのも手？
![image](https://qiita-image-store.s3.amazonaws.com/0/102207/e902cc0b-6973-57c7-5bf4-21d882f376e9.png)
作成されたpathタグをChromeのデバッグで見ていたら思った。
ベクターは拡大縮小にも影響はないでしょうから、予めバーコードフォントと同じで、CODE39の43文字ぶんのキャラクターパターンぶんのpathコマンドを配列として持っておくのも手かなと感じました。