文字の描画とスケーリング・反転

作成日 : 2015-03-28
最終更新日 :

テキストを描く

テキスト(文字)は fillText 関数を使えばよい。

テキストの回転は rotate を用いればよい。当初はこの rotate について調べる予定だったが、 ここでは扱わない。テキストの中心に対して回転するということを実現するのは難しいからで、 それはテキストの中心を定めることが難しいからである。

そのかわりスケーリングと反転に関して調査した。なぜこの両者について調べたかというと、 どちらも将棋の盤面を表すのに必要だからだ。 まず、スケーリングは縦書きで「成銀」、「成桂」、「成香」をひとつの升目に収めるのに必要だ。 また、反転は、相手側の駒を表すのに必要だ。

まず、盤の升目を正方形として表示することが必要だ。将棋では縦を「筋」、横を「段」といい、 それぞれアラビア数字と漢数字で区別する。駒の位置を表すには、X筋、Y段の駒Zをこの順番で並べ、 XYZの形で表す。さらに、自分側の駒であれば▲(または☗)、相手側の駒であれば△(または☖)を頭につける。 なお、たいてい、自分側(手前)が先手、相手側(向こう側)が後手である。

まず、マス XY を表す正方形は
ctx.strokeRect(-30 * X + 277, 30 * Y - 5, 30, 30);
で表される。第一引数に表れる定数 277 や第二引数に表れる定数 -5 は、盤上の駒が後述で描画されたとき、 マス XY の中央に入っているように調整したうえでの産物である。

盤上の自分の駒

盤上位置 XY にある自分の駒 Z は、
ctx.fillText('Z', -30 * X + 280, 30 * Y + 20);
で表示できる。ただし、成銀、成桂、成香はこの式では表せない。

盤上の自分の成駒(成銀、成桂、成香)

盤上位置 XY にある自分の駒のうち、成銀、成桂、成香は上記の式では表せない。 そのため、成Z(Zは銀、桂、香) は、スケール変換 ctx.scale を適用したうえで、次のように表示する
ctx.scale(1, 0.5);
ctx.fillText('成', -30 * X + 280 , 60 * Y + 15);
ctx.fillText('Z', -30 * X + 280 , 60 * Y + 40);

Y 軸にスケール因子 0.5 があるので、縦方向に縮ませることができる。Y の係数 60 は、 30 / 0.5 の値である。

盤上の相手の駒

盤上位置 XY にある相手の駒 Z は、
ctx.scale(-1, -1);
ctx.fillText('Z', -30 * X - 305, -30 * Y);
で表示できる。ただし、成銀、成桂、成香は自分の駒と同様に、別の方法が必要となる。

盤上の相手の成駒(成銀、成桂、成香)

盤上位置 XY にある相手の駒のうち、成銀、成桂、成香は上記の式では表せない。 そのため、成Z(Zは銀、桂、香) は、スケール変換 ctx.scale を適用したうえで、次のように表示する
ctx.scale(-1, -0.5);
ctx.fillText('成', -30 * X - 305 , -60 * Y - 20));
ctx.fillText('Z', -30 * X - 305 , -60 * Y + 5);

Y 軸にスケール因子 -0.5 があるので、縦方向に縮ませることができる。

ctx.save() と ctx.restore() について

ctx.save()を実行することでコンテキストを保存し、ctx.restore() で保存したコンテキストを適用させることができる。 私はこの使い方を誤っていた。当初書いたプログラムは次の通りである:

// 誤った使い方
ctx.save();         // 1. 現在のコンテキストをセーブ (scale(1,1) に相当)
ctx.scale(1, 0.5);  // 2. スケール変換
ctx.restore();      // 3. セーブしたコンテキストへの復帰
ctx.scale(-1, -1);  // 4. 再度スケール変換
ctx.restore();      // 5. 当初セーブしたコンテキストへの復帰(?)
ctx.scale(-1, -0.5);// 6. 再度スケール変換

ここで 6. でスケール変換した結果が思った結果になっていなかった。 現象からすると、5. のリストアができていないことが考えられた。 どうやら、restore したら、セーブした情報は失われるようだ。だから、次に restore したいのならば、 かならず save と組にして扱わないといけない。

	// 正しい使い方
	ctx.save();         // 1. 現在のコンテキストをセーブ (scale(1,1) の状態をセーブ)
	ctx.scale(1, 0.5);  // 2. スケール変換
	ctx.restore();      // 3.1セーブしたコンテキストへの復帰(scale(1,1) への復帰)
	ctx.save();         // 3.2このコンテキストへの再セーブ(scale(1,1) の状態をセーブ)
	ctx.scale(-1, -1);  // 4. 再度スケール変換
	ctx.restore();      // 5.1当初セーブしたコンテキストへの復帰(scale(1,1) への復帰)
	ctx.save();         // 5.2このコンテキストへの再セーブ(scale(1,1) の状態をセーブ)
	ctx.scale(-1, -0.5);// 6. 再度スケール変換	

参考ページ

なお、本調査にあたっては、 https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Canvas_tutorial を参考にした。