JavaScriptのCanvas APIのsave()restore()メソッドを使い、キャンバスの状態を復元する方法を解説します。

下準備

まずは下準備から。htmlの<body></body>内に以下のcanvas要素を配置します。

<canvas id="canvas"></canvas>

jsにてコンテキストを取得します。

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas

画像ではキャンバスの範囲がわかりやすいようにcssにて背景色を設定してあります。

save()、restore()メソッドでキャンバスの状態を復元

これまで図形の描画を行う際、色や線の太さなどを変更する方法を見てきました。一度設定すると以降描画する図形に反映されますが、save()restore()メソッドを使うことでキャンバスの状態(設定)を元に戻すことができます。

まずは2つの矩形を描画します。

ctx.fillRect(10, 10, 100, 20);
ctx.fillRect(10, 40, 100, 20);
2つの矩形を描画

ここで上の図形を初期色の黒ではなく、緑で描画したいとします。最初の図形の描画の前に以下のコードを追加します。

ctx.fillStyle = 'green';
2つの緑の矩形

当然このように2つ目の図形まで色が変わってしまいます。そこで、上の図形の描画部分を以下のようにsave()restore()で囲むように変更します。

ctx.save();
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 100, 20);
ctx.restore();

ctx.fillRect(10, 40, 100, 20);
緑の矩形と黒の矩形

目的の結果になりました。save()は現状のキャンバスの設定を記憶します。restore()を実行すると、前回記憶したキャンバスの設定に戻します。fillStyleプロパティを緑に変更する前にsave()を実行しているため、既定値である黒の状態が記憶されたためこのような挙動となります。

この方法で記憶、復元することのできる値は、strokeStylefillStyleglobalAlphalineWidthlineCaplineJoinlineDashOffsetなどのプロパティや、setLineDash()で設定した値などのこれまでに見てきたものや、今後紹介する座標変換(translaterotatescale)、フォントや影の設定などがあります。変更したこれらの値を1つずつ既定値に戻すより、save()restore()を使うことでまとめてリセットできるため効率が上がります。

save()、restore()は入れ子にできる

save()restore()は入れ子(ネスト)にすることができます。save()を実行するたびキャンバスの状態が記憶され、restore()を実行するたび最後の記憶から順に復元するためです。以下に例を示します。下準備の後、以下のコードを追加します。

ctx.save();
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 100, 20);

ctx.save();
ctx.fillStyle = 'pink';
ctx.fillRect(10, 40, 100, 20);
ctx.restore();

ctx.fillRect(10, 70, 100, 20);
ctx.restore();

ctx.fillRect(10, 100, 100, 20);
上から、緑、ピンク、緑、黒の矩形

プログラムの流れの主要な部分を言語化すると、fillStyleが既定値の黒の時点で最初の記憶がされ、緑の時点で次の記憶がされます。ピンクで描画した後に緑の記憶が復元されると同時に記憶が消え、緑で描画した後に残った黒の記憶が復元されます。