【この教材について】
2019.2.10現在の作動確認
◎ PC版 Google Chrome 72.0.3626.96
◎ Android版 Google Chrome
◎ Microsoft Edge 42.17134.1.0
◎ Firefox Quantum 65.0
◎ Internet Explorer 11
× windows版 Safari (←setLineDash()を認識しない)

 この教材は,HTML5+javascriptで可能となったcanvasによるグラフィックスについて,プログラマー向けに無駄なく正確な解説を行うことを目的としたものではありません.中高生レベルの読者向けに,多少とも厳密さを犠牲にしてでも,例と図を中心として,平易で分かり易い解説となることを目指しています.
 また,技術革新の著しい分野ですので,最新の正確な情報を確かめたい場合には,次のサイトを参考にしてください.
[日本語]
MDN Web docs mozilla canvas チュートリアル
とほほのWWW入門 Canvas 2Dリファレンス
[英語]…日本語訳がまだない箇所を確かめたいときなど
W3C HTML Canvas 2D Context
MDN Web docs mozilla Canvas tutorial

1. 座標系の平行移動

【書式】
コンテキスト.translate(x, y)
【働き】
現在の座標で点(x, y)となっている場所に,新しい座標系の原点を移動します.
•既に描画されている図形には影響しません.translate()以後に行われる描画に影響します.
•translate()を何度も使う場合,初めの座標系ではなく,直前の座標系での点(x,y)に移動することに注意.
- 図1 -
図1では,コンテキスト.strokeRect(10, 10, 100, 50);により長方形を描いた後,コンテキスト.translate(30,20);によって原点を(30,20)に平行移動してから,もう一度同じコンテキスト.strokeRect(10, 10, 100, 50);により長方形を描いたものです.
 これにより,初めに描いた図形に影響することなく,右に30ピクセル,下に20ピクセルだけ平行移動した図形が重ね書きされています.

- 図2 -
図2では,図1の結果にさらに, コンテキスト.translate(30,20);とコンテキスト.strokeRect(10, 10, 100, 50);を使ったものです.
 2回目のコンテキスト.translate(30,20);は,1回目のコンテキスト.translate(30,20);の結果に対して,さらにtranslate()で平行移動しているので,最初の原点から見れば点(60,40)の点を原点とした図を描いていることになります.

2. 座標系の回転移動

【書式】
コンテキスト.rotate(angle)
【働き】
現在の原点を中心として,ラジアンの単位でangleの角だけ座標系を回転させます.
•角度の正の向きは,x軸の正の向きから,y軸の正の向きに(直角となる小さい方の向き.3直角となる大きい方の向きではない.)向かう向き.その逆が負の向き.
•つねにその時点での原点の周りの回転となる.
•rotate()を何度も使う場合,初めの座標系ではなく,直前の座標系に対してさらに回転したものとなる.
- 図3 -
図3では,初めに コンテキスト.strokeRect(50, 10, 30, 20);により,(50, 10)を左上端とする横幅30,縦幅20の長方形を黒で描いています.
 次に,座標軸を(右回りに)30°回転させてから,同じ長方形を青色で書いています.(度degreeの単位の角度をラジアンradianの単位に直すには,radian = degree * Math.PI / 180;とします.簡単な関数を定義してもよいし,毎回この演算を行ってもよい)
 さらに,座標軸を30°回転させてから,同じ長方形を緑色で書いています.(初めの長方形からは60°回転したものになっています.)
 最後に,座標軸を−20°回転させてから,同じ長方形を赤色で書いています.負の角の回転は,ここでは左回りになります.
- 図4 -
図4の赤丸は,初めの座標が(60, 60)の点です.rotate()は原点の周りの回転のみ可能なので,このような原点以外の点を中心として図形を回転させるには,手順を考えて工夫する必要があります.
 初めに長方形rect(x1, y1, w1 h1)があるとき,原点を(60, 60)に移動translate(60, 60)すると,元の長方形の新しい座標はrect(x1−60, y1−60, w1,h1)になります.次に,この長方形を rotate(120 * Math.PI / 180)すると,赤丸の周りに120°回転した長方形が描けます.

3. canvasの状態の保存と復元

【書式】
コンテキスト.save()
【働き】
canvasの状態をメモリに保存する
【書式】
コンテキスト.restore()
【働き】
canvasの状態を復元する
- 図5 -
 座標系の変換[ translate(),rotate()や後で述べるscale() ]を行ったとき,元の状態に戻すには逆順に逆の変換を行えばよいが,複雑な変換を組み合わせて行っていくと復元は煩わしい作業になります.このようなとき,save()とrestore()を使うと,canvasの状態の保存と復元ができます.  図5において,赤丸の点を中心として長方形を120°回転した図を描いてから,さらに,青丸の点を中心として,元の長方形を90°回転したいとき
canvasの初めの状態を,コンテキスト.save()により保存しておき,120°回転の操作を行ってから,コンテキスト.restore()により,初めの座標系に戻してから,2つ目の作業を行えばよい.
 ただし,このsave()やrestore()は,スタックと呼ばれるメモリの使い方で行われ,何回も行ったときは,後から入れたものが先に出てきます.
コンテキスト.save();// no.1
座標系の変換 // (A)
コンテキスト.save();// no.2
座標系の変換 // (B)
コンテキスト.restore();//No.2に戻る
コンテキスト.restore();//No.1に戻る

4. 上下左右の拡大縮小

【書式】
コンテキスト.scale(s, t)
【働き】
x方向の尺度をs倍にし,y方向の尺度をt倍にする
•sやtに負の数を使うと,左右や上下が逆になります.
- 図6 -
図6のような,横150ピクセル×縦100ピクセルのcanvasに,方眼で描いた−1〜1の目盛りを付けて,数学座標としてグラフを描く場合,
コンテキスト.translate(50, 50);
コンテキスト.scale(50, -50);
のように,原点を(50,50)に移動して,縦横を50倍に(縦は上下逆に)すると,テキストを書くときに様々な不都合があります.例えばfontサイズが1ピクセルの文字を書くと,赤で示した0という文字のように,50倍も大きな文字になります.そこで,この座標変換後にそのまま文字を描くとすると,fontサイズとして,0.2pxのような小数値を書かなければならないことになります.
≪fontサイズを小数指定したときの問題点≫
(1) W3C仕様のレファレンスに沿って記述しても,小数値のfontサイズを書くと,実際にはブラウザごとに全然異なるfontサイズで表示されるようです.
(2) 例えば,0.5pxでは文字が表示できても,0.4pxでは表示できないことがある.
 以上のように,座標変換してから,fontサイズを小数で指定するのは難しく,save()とrestore()を使って,座標変換される以前の座標系に戻して,fontサイズを整数値で指定したのが,図6のx, y, 0です.
 ただし,fontの指定は
コンテキスト.font = "[font-style font-variant font-weight] font-size[/line-height] font-family";
の形で,[ ]の部分はオプション([ ]は実際には書かない),青字の部分は必須として書きます.
図6のx, y, 0は,コンテキスト.font = 'italic 16px "Times New Roman"';と書いています.

○== メニューに戻る ==