キャンバス canvas の高速化手法 その2


キャンバスを使った二次元グラフィックを提供する際に、利用者のマシンの性能や利用しているブラウザによっては、パフォーマンスに影響が出ることがあります。
この改善のための手法をいくつか紹介します。

オフスクリーンキャンバスを活用した事前レンダリング

キャンバスの高速化手法の第二弾です。
今回はオフスクリーンキャンバスを活用しての高速化になります。

オフスクリーンキャンバスとは

名前の通りで、そのままではスクリーンに表示されないキャンバスの事です。
オフスクリーンキャンバスの有効な使い方は、繰り返し行うような描画処理をキャンバス上で行うのではなく、オフスクリーンキャンバスに描画しておいて、それをキャンバスにコピーする方法です。

それではオフスクリーンキャンバスの作り方と使い方を見てみましょう。

オフスクリーンキャンバスの作り方 1

《script》

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
canvas.offscreenCanvas = document.createElement("canvas");
canvas.offscreenCanvas.width = canvas.width;
canvas.offscreenCanvas.height = canvas.height;
var ctxOS = canvas.offscreenCanvas.getContext('2d');

上の例では ctxOS がオフスクリーンキャンバスのコンテキストになります。

まず有効なキャンバスに対して document.createElement() メソッドで canvas.offscreenCanvas を定義し、さらに幅と高さを定義しています。
ここでの幅と高さは基のキャンバスと同じ設定にしていますが、利用するサイズが明確であればそのサイズに指定できます。
最後に定義されたオフスクリーンキャンバスのコンテキストを取得して、準備完了になります。
元のキャンバスのコンテキスト ctx は、この時点では特に利用しませんが、後で使うので一緒に記載しておきました。

オフスクリーンキャンバスの作り方 2

《script》

var offscreen = new OffscreenCanvas(100, 100);
var ctxOS = offscreen.getContext('2d');

こちらの例でも ctxOS がオフスクリーンキャンバスのコンテキストになります。

まず new でオフスクリーンキャンバスを生成し、同時に幅と高さを定義しています。
ここでの幅と高さは仮に100×100としていますが、利用するキャンバスと同じに指定してもかまいません。
最後に定義されたオフスクリーンキャンバスのコンテキストを取得して、準備完了になります。
この方法では基になるキャンバスが指定されませんが、実際の使用感は作り方2の方法とほとんど変わりません。

オフスクリーンキャンバスの使用例

では実際にオフスクリーンキャンバスを利用して描画をしてみましょう。
ここでは作り方2の方法でオフスクリーンキャンバスを生成します。

《script》

var canvas;
var ctx;
var offscreen;
var ctxOS;
var interval;
var i = 0;
function init() {
	canvas = document.getElementById("canvas");
	ctx = canvas.getContext('2d');
	offscreen = new OffscreenCanvas(100, 100);
	ctxOS = offscreen.getContext('2d');
	ctxOS.fillStyle = "blue";
	ctxOS.fillRect(10, 10, 70, 70);
	ctxOS.globalAlpha = 0.5;
	ctxOS.fillStyle = "red";
	ctxOS.fillRect(20, 20, 70, 70);
	ctxOS.globalAlpha = 1.0;
	interval = setInterval(drawTimer, 1000);
}
function drawTimer() {
	if (i == 4) {
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		i = 0;
	}
	else {
		const tableX = [0, 100, 0, 100];
		const tableY = [0, 0, 100, 100];
		ctx.drawImage(offscreen, tableX[i], tableY[i], 100, 100);
		i++;
	}
}

《実行結果》

canvas

この例の簡単な説明です。

ここまでがキャンバスの高速化手法 その2 になります。
画像描画に拡大縮小や回転を伴い場合、浮動小数点を使わなければならない場合などに活用してください。