htmlでの画像上への文字オーバレイ(canvas利用)

#HTML5で画像上に文字をオーバレイしたい
私はそもそも、主業務はフロントエンドエンジニアではないのですが、
ちょっとこういった機能を使いたいケースが出てきて、
今風に書くとそんなことができるようになった事を知ったので試してみました。

##やりたいこと
これ(floormap.png)を
![floormap.png](https://qiita-image-store.s3.amazonaws.com/0/144657/d706fa78-efb2-4003-299f-dab47b3fa407.png)

HTML5とJavaScriptの標準的な機能だけでこうしたい
![canvas.png](https://qiita-image-store.s3.amazonaws.com/0/144657/aee14f6a-3bbe-240a-6377-188c3d0325cb.png)

##やったこと
とりあえず動きをサクッとみるために組んだだけなので作りとしては大概に汚いです。
ソース(html1本)で実現してるので、画像をコピってソースをコピったらすぐ動くとは思いますが。

```html
<!doctype html>
<html lang="ja">
<meta charset="utf-8"/>
<title></title>
<head></head>
<body>
<canvas id="cv" width="400" height="200"></canvas>

<script>
//RoundBox関数
function $RoundBox($ctx, x, y, h, w, color) {
	this.$ctx = $ctx;												//Canvasのコンテキスト
	this.x = x || 0;												//矩形左上始点 横位置(X)
	this.y = y || 0;												//矩形左上始点 縦位置(Y)
	this.h = h || 0;												//高さ
	this.w = w || 0;												//幅
	this.color = color || "rgb(0, 0, 0)";							//色

	$ctx.beginPath();												//パスを開始
	$ctx.moveTo( this.x          , this.y               );			//開始座標
	$ctx.lineTo( this.x + this.w , this.y               );
	$ctx.arc   ( this.x + this.w , this.y +  this.h / 2 , this.h / 2 , 3/2*Math.PI, 1/2*Math.PI, false);
	$ctx.lineTo( this.x          , this.y +  this.h     );
	$ctx.arc   ( this.x          , this.y +  this.h / 2 , this.h / 2 , 1/2*Math.PI, 3/2*Math.PI, false);

	$ctx.fillStyle = this.color;
	$ctx.fill();													//塗りつぶし
	$ctx.stroke();													//線描画
	$ctx.closePath();
}

//Triangle関数
function $Triangle($ctx, x, y, h, w, color) {
	this.$ctx = $ctx;												//Canvasのコンテキスト
	this.x = x || 0;												//矩形左上始点 横位置(X)
	this.y = y || 0;												//矩形左上始点 縦位置(Y)
	this.h = h || 0;												//高さ
	this.w = w || 0;												//幅
	this.color = color || "rgb(0, 0, 0)";							//色

	$ctx.beginPath();												//パスを開始
	$ctx.moveTo( this.x + this.w / 2 , this.y           );			//開始座標
	$ctx.lineTo( this.x + this.w     , this.y +  this.h );
	$ctx.lineTo( this.x              , this.y +  this.h );
	$ctx.lineTo( this.x + this.w / 2 , this.y           );

	$ctx.fillStyle = this.color;
	$ctx.fill();
	$ctx.stroke();													//線描画
	$ctx.closePath();
}


function init(){
	// 画像の表示イベント
	var img = new Image();
	img.src = "floormap.png";
	img.onload = function(){
		// 画像を表示
		ctx.drawImage(img,0,0,400,200);
		
		//テキスト描画のスタイルを指定する
		ctx.textAlign    = "left";
		ctx.textBaseline = "top";

		$RoundBox(ctx,  60,  50, 20, 20, "#FDEADA")
		$Triangle(ctx, 100,  45, 30, 30, "#FDEADA")
		$RoundBox(ctx, 290,  50, 20, 20, "#FDEADA")
		$Triangle(ctx, 330, 105, 30, 30, "#FDEADA")

		ctx.font         = "bold 18px 'ＭＳ ゴシック'";
		ctx.fillStyle    = "blue";
		ctx.fillText("田中",  70,  78, 40);
		ctx.fillText("山田", 300,  78, 40);
		ctx.fillText("鈴木", 300, 140, 40);

		ctx.font         = "bold 12px 'ＭＳ ゴシック'";
		ctx.fillStyle    = "black";
		ctx.fillText("101",  60,  55, 20);
		ctx.fillText("201", 105,  63, 20);
		ctx.fillText("102", 290,  55, 20);
		ctx.fillText("202", 335, 123, 20);
	}
}

//動かしてみよう
var ctx;
document.body.onload = function(){
	ctx = document.querySelector("#cv").getContext("2d");
	init();
}
</script>

</body>
</html>
```

##動作結果
IEはいける
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144657/f5d0a7f9-8a6f-986f-ea27-087eff9fe197.png)

Edgeもばっちり
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144657/da3dca05-ea90-22fa-fd88-ce7613a8670d.png)

chromeもいける
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144657/4dfb4d1e-b147-0be5-e877-253c91a546e6.png)

Firefoxでもきっちり動いた
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144657/bae86117-7216-15ab-8830-f62f9571419a.png)

##考慮点と余談
一度、画像を描画してからでないとオーバーレイで描画できないらしいのと、
図形を軒並み描いてからでないと文字がどうも上に乗らないようです。

また、さすがにこの規模だとソース分離したほうがいいのかどうかは微妙な線ですね。
例示で書いたのは座席表想定ですが、帳票とかもうまく組むと結構柔軟な感じのものがHTMLだけで作れてしまいそうな気がします。

標準HTMLとJavaScriptだけでこのレベルの動作が確保されてて、ブラウザを問わずに耳を揃えて動くのは凄いですね…

##参考URL
http://computer-technology.hateblo.jp/entry/20131030/p1
https://sterfield.co.jp/designer/canvas%E3%81%AE%E8%A4%87%E6%95%B0%E3%81%AE%E5%9B%B3%E5%BD%A2%E3%82%92prototype%E3%81%A7%E5%90%8C%E6%99%82%E3%81%AB%E6%89%B1%E3%81%86/

参考になりました。感謝。