JavaScript - Canvas に図形を描く方法
HTML の canvas 要素を利用すると、JavaScript でグラフィックを描くことができます。基本的なメソッドを学んで、四角形や三角形、円やテキストなど簡単な図形を描画できるようになりましょう。
JavaScript で図形を描画しよう
JavaScript でプログラミングすると、ウェブページにグラフィックを描くことができます。ユーザーの操作によってグラフィックを表現することで、お絵描きアプリやゲーム、アニメーションを作ることができますよ。でも、JavaScript だけでは何も描けません。描画する場所としてのキャンバスが必要です。キャンバスは HTML で用意します。
今回は、キャンバスの設定方法から図形を描くときのメソッドなど、JavaScript で図形を描画するための基本を一緒に学んでいきましょう。
canvas (キャンバス) とは
JavaScript で何かを描きたいときに必要になるのが、HTML の <canvas>
要素です。<canvas>
要素は、描画するエリアを提供します。JavaScript でプログラミングすると、そのエリア内に図形などを描画できるようになります。
HTML:
<canvas></canvas>
<canvas>
要素は、同じページに複数用意して重ねて使ったりすることができます。どの<canvas>
要素に描画するのかを JavaScript から特定しやすいように id
をつけておきましょう。
<canvas id="canvasDemo"></canvas>
古いブラウザーでは <canvas>
要素に対応していないものもあります。<canvas>
要素の代わりに表示するための代替テキストをタグ内に設定しておくと良いでしょう。
<canvas id="canvasDemo">キャンバスの内容を説明するテキスト</canvas>
特にサイズを指定しない場合、キャンバスのデフォルトサイズは幅 300px
・高さ 150px
です。width
属性と height
属性を指定すると、キャンバスを好きなサイズに設定することができます。
<canvas id="canvasDemo" width="600" height="600">キャンバスの内容を説明するテキスト</canvas>
キャンバスの描画エリアは透明です。描画エリアを分かりやすくするために CSS で枠線を設定してみましょう。ここでは、幅 600px
・高さ 600px
の正方形のキャンバスを用意したので、ウェブページには下のように表示されます。
CSS :
#canvasDemo {
border: 5px solid lightgray;
}
JavaScript で描画を始めるための基本コード
<canvas>
要素を用意できたら、JavaScript でプログラミングしていきますよ。具体的に何かを描く前に、描画を始めるための基本コードから見ていきましょう。
JavaScript でキャンバスに描画するためには、まず <canvas>
要素を取得します。
const canvas = document.querySelector('#canvasDemo');
次に、<canvas>
要素 の getContext()
メソッドを使って、描画するためのさまざまなプロパティやメソッドを利用できるようにします。getContext()
の括弧 ()
に 2d
を指定すると、縦と横の平面、つまり二次元で図形を描画できるようになりますよ。
canvas.getContext('2d')
上のように書くことで、二次元の描画用ツール (メソッドやプロパティ) を備えたオブジェクトが返されます。取得したオブジェクトは変数に格納し、実際に描画する際には変数で参照できるようにしておきましょう。変数には好きな名前をつけられますが、context (コンテキスト) を省略した ctx
がよく使われます。
const ctx = canvas.getContext('2d');
JavaScript でキャンバスに描画する準備ができました。
HTML:
<canvas id="canvasDemo" width="600" height="600">キャンバスの内容を説明するテキスト</canvas>
JavaScript:
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
座標で描画する場所を決める
何かを描画するときは、キャンバスのどこに描くかを指定する必要があります。そのために使うのが座標です。
座標は、キャンバスの横の位置を x
、縦の位置を y
で表します。キャンバスの左上の角は、x 座標:0
、y 座標:0
です。
ではこれから、キャンバスに描画するためのさまざまなメソッドを紹介していきます。
長方形 (矩形) を描く
まずは、長方形を描く方法です。長方形とは、4つの角が直角の四角形のことです。
JavaScript には、簡単に長方形を描くためのメソッドが3つあります。長方形を描くときは、左上の角の位置を x
と y
で指定し、width
と height
で横と縦の長さを決めます。
長方形を描くメソッド:
fillRect(x, y, width, height) // 塗りつぶしの長方形を描く
strokeRect(x, y, width, height) // 長方形の輪郭線を描く
clearRect(x, y, width, height) // 指定の範囲を消去する
塗りつぶしの長方形を描く - fillRect()
fillRect()
メソッドでは、長方形のエリアが塗りつぶされた図形を描くことができます。width
と height
を同じ値にすると正方形になりますよ。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 塗りつぶしの正方形を描く
ctx.fillRect(100, 10, 400, 400);
長方形の輪郭線を描く - strokeRect()
strokeRect()
メソッドでは、長方形の輪郭線を描くことができます。長方形の内側は塗りつぶされずに透明です。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
ctx.fillRect(100, 10, 400, 400);
// 長方形の輪郭線を描く
ctx.strokeRect(20, 450, 560, 110);
指定の範囲を消去する - clearRect()
clearRect()
メソッドでは、指定した範囲を長方形に消去します。先ほど描いた塗りつぶしの正方形の一部を消去してみましょう。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
ctx.fillRect(100, 10, 400, 400);
ctx.strokeRect(20, 450, 560, 110);
// 指定の範囲を消去する
ctx.clearRect(200, 100, 200, 200);
次のセクションからは、より複雑な図形を描くことができるパスについて紹介します。
パスとは
JavaScript では、パスで図形を描画することができます。パスとは、点と点を線で結んだ要素のことです。好きな位置に点を配置し、点と点を線で繋ぐことで複雑な図形を描くことができます。
先ほど紹介した長方形を描くメソッドとは違い、パスで描くときは下のようなメソッドをいくつか組み合わせて描画します。
beginPath() // 新しいパスを描き始める
moveTo(x, y) // パスの始点を指定する
lineTo(x, y) // 直線を引く座標を指定する
closePath() // パスの始点へ直線を引いてパスを閉じる
stroke() // パスを線で描く
fill() // パスの内側を塗りつぶす
直線を描く
まずは単純な直線を例にして、パスの基本的な描き方を見ていきましょう。
新しいパスを描き始める - beginPath()
パスで新たな図形を描き始めるときは、最初に beginPath()
メソッドを呼び出します。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 新しいパスを描き始める
ctx.beginPath();
パスの始点を指定する - moveTo()
どの位置からパスを描き始めるのか、moveTo()
メソッドで x 座標と y 座標を指定します。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
ctx.beginPath();
// パスの始点を指定する
ctx.moveTo(100, 100);
直線を引く座標を指定する - lineTo()
どこへ直線を引くのか、lineTo()
メソッドで x 座標と y 座標を指定します。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 100);
// 直線を引く座標を指定する
ctx.lineTo(500, 500);
パスを線で描く - stroke()
パスを描く位置が決まったら、stroke()
メソッドを呼び出して線で描画します。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(500, 500);
// パスを線で描く
ctx.stroke();
三角形を描く
では次に、直線を描く方法を応用して三角形を描いてみましょう。
パスの始点へ直線を引いてパスを閉じる - closePath()
線で三角形を描くときは、stroke()
で線を描画する前に、closePath()
メソッドを呼び出します。closePath()
は、パスの始点へ直線を引いてパスを閉じます。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 三角形を描く
ctx.beginPath();
ctx.moveTo(20, 100);
ctx.lineTo(20, 500);
ctx.lineTo(280, 300);
//始点へ直線を引く
ctx.closePath();
ctx.stroke();
パスの内側を塗りつぶす - fill()
塗りつぶされた三角形を描くときは、closePath()
を呼び出す必要はありません。stroke()
ではなく、パスの内側を塗りつぶす fill()
メソッドを使うことで、パスは自動的に閉じられます。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 三角形を描く
ctx.beginPath();
ctx.moveTo(580, 100);
ctx.lineTo(580, 500);
ctx.lineTo(320, 300);
// パスの内側を塗りつぶす
ctx.fill();
円や円弧を描く - arc()
円や円弧を描くときは、arc()
メソッドを使います。
構文:
arc(x, y, 半径, 開始角度, 終了角度, 方向)
- x, y:円 (円弧) の中心となる x 座標と y 座標です。
- 半径:円 (円弧) の半径です。
- 開始角度:円 (円弧) の始まりの角度です。完全な円を描くときは
0
から始めます。 - 終了角度:円 (円弧) の終わりの角度です。完全な円を描くときは
2 * Math.PI
とします。 - 方向:(省略可) 描く方向を指定します。デフォルトは
false
で時計回りに描きます。true
を指定すると反時計回りに描きます。
中心を x 座標 300
、y 座標 300
とし、半径 200
の円を描くときは下のようなコードになります。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 円を線で描く
ctx.beginPath();
ctx.arc(300, 300, 200, 0, 2 * Math.PI);
ctx.stroke();
半円を描くときは、終了角度を Math.PI
とします。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 半円を線で描く
ctx.beginPath();
ctx.arc(300, 300, 200, 0, Math.PI);
ctx.stroke();
方向を true
にすると、開始角度から終了角度へ反時計回りに描画されます。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 反時計回りに線で描く
ctx.beginPath();
ctx.arc(300, 300, 200, 0, Math.PI, true);
ctx.stroke();
stroke()
ではなく fill()
メソッドを使って、円や円弧を塗りつぶしてみましょう。開始角度と終了角度によって、いろいろな形を表すことができますよ。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// ①塗りつぶしの円
ctx.beginPath();
ctx.arc(120, 120, 80, 0, 2 * Math.PI);
ctx.fill();
// ②半円
ctx.beginPath();
ctx.arc(300, 300, 80, 0.5 * Math.PI, 1.5 * Math.PI);
ctx.fill();
// ③少し欠けた円
ctx.beginPath();
ctx.arc(480, 480, 80, 1.2 * Math.PI, 0.8 * Math.PI);
ctx.fill();
顔の絵を描く
円や円弧をいくつか組み合わせると、下のような顔の絵を描くことができます。
顔のコード:
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// 線で描く
ctx.beginPath();
ctx.arc(300, 300, 200, 0, Math.PI*2, true); //顔の輪郭
ctx.moveTo(420, 300);
ctx.arc(300, 300, 120, 0, Math.PI); //口
ctx.stroke();
// 左眉
ctx.beginPath();
ctx.arc(200, 200, 30, 1.8*Math.PI, 1.2*Math.PI, true);
ctx.stroke();
// 右眉
ctx.beginPath();
ctx.arc(400, 200, 30, 1.8*Math.PI, 1.2*Math.PI, true);
ctx.stroke();
// 塗りつぶしで描く
ctx.beginPath();
ctx.arc(200, 230, 20, 0, Math.PI*2); //左目
ctx.arc(400, 230, 20, 0, Math.PI*2); //右目
ctx.fill();
文字を描く - fillText(), strokeText()
文字を描くために使うのは、fillText()
メソッド、または strokeText()
メソッドです。fillText()
では塗りつぶした文字を、strokeText()
では文字の輪郭線を描画します。
文字を描くメソッド:
fillText(文字列, x, y, 最大幅)
strokeText(文字列, x, y, 最大幅)
文字を描画し始める位置を x 座標と y 座標で決めます。最大幅は文字列を収める横幅です。横幅を特に指定しない場合は省略可能です。
fillText()
、strokeText()
を使った例を見てみましょう。font
プロパティを使うと、フォントの種類や大きさを指定することができますよ。デフォルトのフォントは 10px
、sans-serif
です。
const canvas = document.querySelector('#canvasDemo');
const ctx = canvas.getContext('2d');
// ①テキストを描画する(デフォルトスタイル)
ctx.fillText('ABCDEF', 100, 70);
// ②フォントスタイルを指定
ctx.font = 'bold 80px sans-serif';
ctx.fillText('GHIJKL', 100, 230);
// ③フォントスタイルを指定
ctx.font = '80px serif';
ctx.fillText('MNOPQR', 100, 370);
// ④フォントスタイル、最大幅を指定
ctx.font = '80px serif';
ctx.strokeText('STUVWX', 100, 520, 200);
まとめ
今回は、JavaScript でグラフィックを描く方法として、HTML の <canvas>
要素と図形を描画するメソッドについて紹介しました。
キャンバスを使うと JavaScript でグラフィックを表現することができ、アニメーションやゲームを作ることができるようになります。まずは、今回紹介したメソッドを使って基本的な図形を描いてみることから始めてみてください。
最後まで読んでいただき、ありがとうございます。この記事をシェアしてくれると嬉しいです!
こちらもチェック! X (Twitter) @pyxofy・LinkedIn・Mastodon・Facebook