スタートページ>
Javascript>
CANVAS
CANVASの基本(2)図形描画の基本機能
canvasの概念およびピクセル情報に関しては、「CANVASの基本(1)」で扱いましたが、実際の図形描画では、標準装備されている機能を使うことが必要です。ここでは、代表的な機能を列挙します。
基本図形
[実行]をクリックしてください。
この直後に、幅400ピクセル、高さ200ピクセルのCANVAS「canvas1」が定義されています。
<canvas id="canvas1" width="400" height="200"></canvas>
これらの図形を描画するJavascriptを以下に示します。
長方形の描画(黒い外枠)
- ソースリスト
function rect() {
var canvas = document.getElementById("canvas1"); ・・・A
var ctx = canvas.getContext("2d"); ・・・B
ctx.rect(0, 0, 400, 200); ・・・C
ctx.strokeStyle = "black"; ・・・D
ctx.lineWidth = 1; ・・・E
ctx.stroke(); ・・・F
}
- AとBは、body部で記述した<canvs~>とJavascriptを結び付ける機能です。「CANVASの基本(1)」で示したので割愛します。以下の図形描画でのこの2行が必要ですが、割愛しています。
- ここでは、CANVASの外枠(長方形)を描画しています。
Cで長方形を定義し、Fで描画をします。
- Cの一般形:rect(x,y, w,h)
左上点 (x,y) と右下点 (x+w, y+h) を対角線とする長方形
(x,y)~(w,h) ではないことに注意
- Dは線の色、Eは線の太さ(ピクセル単位)です。
Dを指定しないと black、Eを指定しないと 1 になります。
これらの指定は、後続する図形描画にも引き継がれるので、その都度指定するほうが安全です。
- Fの stroke を個々の図形で与えずに、最後に記述して全体を一挙に描画することもできます。
直線の描画(赤い太線)
- ソースリスト
ctx.beginPath(); ・・・G
ctx.moveTo(50, 20); ・・・H
ctx.lineTo(200,80); ・・・I
ctx.closePath(); ・・・J
ctx.strokeStyle = "red";
ctx.lineWidth = 5;
ctx.stroke();
- 線を引くときには、GとJで囲みます。
- Hで起点、Iで終点を与えて直線を引きます。
多角形の描画(三角形)
- ソースリスト
ctx.beginPath();
ctx.moveTo(80, 50); ・・・K
ctx.lineTo(180,100); ・・・L
ctx.lineTo(130,120); ・・・M
ctx.closePath(); ・・・N
ctx.strokeStyle = "blue";
ctx.lineWidth = 3;
ctx.stroke();
ctx.fillStyle = "yellow"; ・・・O
ctx.fill(); ・・・P
- Kが起点となり、Lを終点とする直線が引かれますが、このときポインタはLになっています。
それで、Mを与えると、LからMへ直線が引かれます。
- このように、lineTo を並べることにより、多様な折れ線を引くことができます。
- 最後にNで closePath とすると、最初の起点Kに直線が引かれ多角形になります。
MとNとの間に ctx.lineTo(80,50); を加えればより明確になりますが、それを省略できるのです。
- OとPで、多角形の内部に色をつけています。Pがないと色が表示できません。
円弧の描画(円)
- ソースリスト
ctx.beginPath();
ctx.arc(100, 150, 20, 0, 2*Math.PI, false); ・・・Q
ctx.closePath();
ctx.strokeStyle = "purple";
ctx.lineWidth = 5;
ctx.stroke();
ctx.fillStyle = "lime";
ctx.fill();
- Qの一般形
arc(x,y, radius, startAngle, endAngle, anticlockwise)
- x,y:円の中心座標
- radius:円の半径(ピクセル)
- startAngle, endAngle:円弧の開始角度と終了角度
X軸(横軸)の正方向(右端)から「時計回り」にラジアンで与えます。
右端:0°= 0、 真下:90°= Math.PI/2、真上:-90°= -Math.PI/2
下半円:180°= Math.PI, 全円:360°= Math.PI*2
- anticlockwise:「時計回り」なら false、「反時計回り」なら true
true ならば、上のラジアンは正負が逆になります。
画像の表示
- ソースリスト(誤)
var img = new Image(); ・・・R
img.src = "canvas-image.jpeg"; ・・・S
ctx.drawImage(img, 250, 20); ・・・T
- RとSで取り込む画像のURLを定義し、Tで表示位置を指定して表示します。
- Tの一般形
drawImage(img, x,y)
drawImage(img, x,y, w,h)
drawImage(img, ix,iy, iw,ih, x,y, w,h)
img:Rでの img をそのまま記述します。
x,y:表示位置(左上端)
w,h:表示での width と hight。元画像が拡大/縮小されて表示
ix,iy, iw,ih:元画像での表示する部分の範囲指定
でも、これでは「最初は画像が表示されず、もう一度クリックすると表示される」という状態になります。それは、上のTでは、最初のクリック時点では、「画像が読み込まれないうちに表示させる」ことになるからです。再度クリックしたときは、以前のクリックで画像が読み込まれているので、表示できたのです。
このような「カッコ悪い」のを避けるために、次のように修正します。
- ソースリスト(正)
var img = new Image();
img.src = "canvas-image.jpeg?" + new Date().getTime(); ・・・S
img.onload = function() { ┐imgがonloadされたら、{ }の部分を実行
ctx.drawImage(img, 250, 20); │・・・T
} ┘
- ここのTのimg.onloadは、「画像が読み込まれたら~」の意味です。すなわち、画像が読み込まれるまで待ってからdrawImageを行うのです。これにより、最初のクリックで画像が表示されるようになります。
- Sでの赤字部分の変更は、必須ではありませんが思わぬトラブルを避けるためのものです。
最初に画像がロードされた時であれば、Tのloadイベントが発生しますが、いったん画像がロードされるとキャッシュされ、それ以降はloadイベントが発生しなくなります。例えば、Canvasのページを表示した後、別のページに移動して、再度、Canvasのページに戻った場合、loadイベントが発生しないので、画像が表示されないことになります。
それを避けるための、画像ファイルにその時点の時刻をつけた(赤字)を追加した名称にして、キャッシュしてある画像ではなく、新しい画像だということにしてloadイベントを発生させるのです。
文字列の描画
- ソースリスト
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
ctx.font = "10px 'MS 明朝'"; ・・・U
ctx.strokeText("☆(300,150)", 300, 140); ・・・V
ctx.textAlign = "center"; ・・・W
ctx.strokeText("(300,☆150)", 300, 160);
ctx.textAlign = "right"; ・・・W
ctx.strokeText("(300,150)☆", 300, 180);
- Vにより文字列が表示されます。
- 指定がなければ、文字列の左端の表示座標になります。
Wを指定することにより、中央あるいは右端の座標とすることができます。
ここでは☆の位置がそれにあたります。
- Uにより、文字のフォントを指定できます。
色指定について
ctx.strokeStyleやctx.fillStyleなどの色指定には、二つの形式があります。