Object.create(null)

TypeError: Cannot convert object to primitive value

DOM オブジェクトを canvas に描画する方法について

方法1: SVG の foreignObject を使って HTML を埋め込む

参考: Drawing DOM objects into a canvas - Web APIs | MDN

SVG<foreignObject> という要素内に描画したい HTML 要素を埋め込み, それを ctx.drawImage() とかで canvas に描画するという流れ.

利点は, 描画するものが SVG として得られているので, canvas への描画時に拡大縮小などが自由に行える. Retina display のように高 DPI のディスプレイでは window.devicePixelRatio を元に拡大率を指定すると描画がぼやけなくて綺麗.

欠点は, 上の記事で

The resulting canvas should be origin clean, meaning you can call toBlob(function(blob){…}) to return a blob for the canvas, or toDataURL() to return a Base64-encoded data: URI.

とあるように origin clean であって欲しいのだけれど (Firefox では実際そうなる), Chromium では tainted になってしまって, 上に挙げられているものや ctx.getImageData() などが使えなくなってしまう. このため, 後から描画結果を加工したりすることは, Chromium ではできない.

方法2: html2canvas

html2canvas

HTML を独自に canvas に描画してくれるライブラリ.

これを使うと Chromium でも自由に描画結果を加工できるようになる.

欠点は, あまり柔軟に設定が行えず, 拡大率も設定できなさそうなので, 高 DPI のディスプレイでは描画結果がぼやけたようになってしまう.

また document に所属している要素しか描画できない (じゃあdocument に追加するけど不可視にすればいいじゃんと思うかもしれないけれど, スタイルもよしなに適用してくれるので, 不可視の要素はきちんと不可視になってしまう), そのせいか描画される要素の位置によって描画結果が異なる (ちゃんと確認していないので, おそらく) などの問題もある.