パスを使って図形を描画するには?
解説
コンテキストに対してパス(線をつなげて得られる形状)を設定し、そのパスを使って、Canvasにいろいろな図形を描くことができます。
【線の描画】
線を描画するには、次のようにします。
context.beginPath(); // パスを始める
context.moveTo(10,20); // 始点を決める
context.lineTo(150,60); // 線を引く
context.stroke(); // 実際に描画する
Canvasに線を描画するには、あらかじめ設定したパスに沿って、stroke()メソッドで線を描画します。
パスを設定するには、beginPath()メソッドでパスの開始を宣言し、moveTo()メソッドで始点を決め、そこから各地点の座標を決めていきます。
上の例を実行すると、(10,20)から(150,60)に線が引かれます。
線をつなげて描くには、次のように複数のlineTo()メソッドを書きます。
context.beginPath();
context.moveTo(10,20);
context.lineTo(150,60);
context.lineTo(200,120);
context.stroke();
線を閉じて(終点と始点をつなげて)多角形にするには、パスの設定の最後にclosePath()メソッドを書きます。
context.beginPath();
context.moveTo(10,20);
context.lineTo(150,60);
context.lineTo(200,120);
context.closePath();
context.stroke();
moveTo()メソッドを複数指定すると、複数の線を描画することができます。次の例では、2回目のmoveTo()メソッド以降は別の線として描画されます。
context.beginPath();
context.moveTo(10,20);
context.lineTo(150,60);
context.moveTo(180,60);
context.lineTo(150,120);
context.stroke();
【四角形の描画】
パスの中で四角形を描画するには、rect()メソッドを使います。
次のように書くと、左上隅の座標が(10, 20)、幅が30、高さが40の四角形を描くことができます。
context.beginPath();
context.rect(10,20,30,40);
context.stroke();
rect()メソッドでは、次の例のように、それ以前の線はいったん切られます。rect()メソッド以降の線は左上隅からつながって描かれます。
context.beginPath();
context.moveTo(0,0);
context.lineTo(40,10);
context.rect(10,20,30,40);
context.lineTo(25,40);
context.stroke();
【塗りつぶし】
線を引くのではなく、中身を塗りつぶすには、stroke()メソッドの代わりにfill()メソッドを使います。
なお、下の例ではclosePath()メソッドでパスを閉じていますが、これを呼び出さなくてもパスが閉じたものとして塗りつぶされます。
context.beginPath();
context.moveTo(10,20);
context.lineTo(150,60);
context.lineTo(180,120);
context.closePath();
context.fill(); // 塗りつぶす
stroke()メソッドとfill()メソッドを同時に使うことも可能です。
次の例では、線を赤、、塗りつぶしを青にしています。
context.beginPath();
context.moveTo(10,20);
context.lineTo(150,60);
context.lineTo(180,120);
context.closePath();
context.strokeStyle = "red"; // 線の色を指定する
context.fillStyle = "blue"; // 塗りつぶしの色を指定する
context.fill();
context.stroke();
【円(円弧)の描画】
円や円弧を描画するには、arc()メソッドを使います。
次の例は、中心が(100, 75)、半径が40の円を描きます。
context.beginPath(); // パスを始める
context.arc(100,75,40,0,Math.PI*2,true);
context.stroke(); // 実際に描画する
arc()メソッドの引数は、次のようになっています。
context.arc(x, y, radius, startAngle, endAngle, anticlockwise);
x、y | 円または円弧の中心の座標 |
radius | 円または円弧の半径 |
startAngle | 開始角度 |
endAngle | 終了角度 |
anticlockwise | 描画の向き(falseなら時計回り、trueなら反時計回り) |
角度は、円の右端から始まり、時計回りが正の方向です。
角度の単位は0°~360°の「度」ではなく、0~2πのラジアンで表します。
ラジアンでは、1周を2πで表します。πの値を得るにはMathオブジェクトのPIという定数が使えます。
たとえば、次のように対応します。
度 | ラジアン |
0° | 0 |
30° | Math.PI/6 |
45° | Math.PI/4 |
60° | Math.PI/3 |
90° | Math.PI/2 |
180° | Math.PI |
270° | Math.PI*1.5 |
360° | Math.PI*2 |
一般的には、「(ラジアン) = (度)×π÷180」で表せます。
anticlockwiseの値によって、どちら向きに描画していくのかが決まります。
次の例は、45°から135°の間の円弧を描きます。
context.beginPath();
context.arc(100,75,40, Math.PI/4, Math.PI*3/4, false);
context.stroke();
stroke()メソッドの代わりにfill()メソッドを使うと、弧と弦で囲まれた領域を塗りつぶします。
context.beginPath();
context.arc(100,75,40,Math.PI/4,Math.PI*3/4,false);
context.fill();
扇型を描くには、lineTo()メソッドと組み合わせて次のようにします。
context.beginPath();
context.arc(100,75,40,Math.PI/4,Math.PI*3/4,false);
context.lineTo(100,75);
context.closePath();
context.fill();
【曲線の描画】
円弧のバリエーションとして、arcTo()というメソッドがあります。
これは次のような引数を取ります。
context.arcTo(x1, y1, x2, y2, radius);
地点1を(x1,y1)、地点2を(x2,y2)とすると、arcTo()は、
「地点1に向かいながら、地点2へradiusを半径として曲がっていく円弧」
を描きます。
たとえば、次の例では、始点(60,30)から、地点1(60,70)へ向かい、半径15で地点2(90,70)へ向かう円弧が描かれます。
なお、地点1と地点2の位置をわかりやすくするため、追加で小さな四角形を描いています。
context.beginPath();
context.moveTo(60,30); // 始点
context.arcTo(60,70,90,70,15);
context.stroke();
context.strokeRect(60,70,2,2); // 地点1
context.strokeRect(90,70,2,2); // 地点2
また、同じようなメソッドで、円弧ではなく2次曲線を描くquadraticCurveTo()というメソッドもあります。
次の例では、始点(60,30)から、地点1(60,70)に向かいつつ、地点2(90,70)につながる2次曲線が描かれます。
arcTo()の場合は円弧のため、地点2につながる保証はありませんが、quadraticCurveTo()はつながります。
なお、いずれの場合も、始点-地点1と、地点1-地点2の2つの直線は、曲線の接線になっています。
context.beginPath();
context.moveTo(60,30); // 始点
context.quadraticCurveTo(60,70,90,70);
context.stroke();
context.strokeRect(60,70,2,2); // 地点1
context.strokeRect(90,70,2,2); // 地点2
【ベジエ曲線の描画】
もっと自由な曲線を描きたいときは、bezierCurveTo()メソッドを使うことができます。
bezierCurveTo()メソッドは、6つの引数を取ります。書式は次のようになります。
context.bezierCurveTo(cp1x,cp1y, cp2x,cp2y, x,y)
(cp1x,cp1y)は地点1、(cp2x,cp2y)は地点2、(x,y)は終点を表しています。
bezierCurveTo()メソッドは、始点と地点1とを結ぶ直線と、地点2と終点を結ぶ直線が、
それぞれ始点、終点の接線になるような曲線を描きます。
このような曲線のことをベジエ曲線といいます。
次にbezierCurveTo()メソッドの使用例を示します。
context.beginPath();
context.moveTo(60,30); // 始点
context.bezierCurveTo(70,80, 90,100, 120,60);
context.stroke();
context.strokeRect(70,80,2,2); // 地点1
context.strokeRect(90,100,2,2); // 地点2
地点2と終点を結ぶ直線には向きがあります。
もし、地点2と終点の座標を入れ替えると、次のようになります。
context.beginPath();
context.moveTo(60,30); // 始点
context.bezierCurveTo(70,80, 120,60, 90,100);
context.stroke();
context.strokeRect(70,80,2,2); // 地点1
context.strokeRect(120,60,2,2); // 地点2
関連項目
Canvasとは