BUNCHO METHOD コードを楽しむプログラミング情報メディア

【レッスン#8】 「グラフィックの描画」を学ぶプログラミング教材

プログラミング教材#8ではJavaScriptでグラフィックを描画する方法を学びます。テキストのみによる表現を抜け出しアクションの幅を広げることができるようになります。

プログラミング教材#8の概要

プログラミング教材#8のサンプルコード①

See the Pen 教材#8canvas by programmingbird (@programmingbird) on CodePen.

3つのボタンをそれぞれ押してみると

RECTボタンを押すと、画面に長方形が表示されます。CIRCLEボタンを押すと、が表示されます。CLEARボタンを押すと画面がクリアされます。コードを見ると3つのボタンそれぞれに「トリガー」が設定されていて、対応する「アクション」としてrect(),circle(),clear()が用意されているようです。この基本構成自体はもう見慣れたものですね。

今回のポイントは「アクション」の中身です。プログラミング教材#7まではどのサンプルコードでも、innerHTMLを使ってHTMLを書き換えることでテキストを画面に表示することをアクションとしていましたが、今回のサンプルコードではアクションでグラフィックを描画しています。

プログラミング教材#8 サンプルコード①の解説

HTML

canvasはJavaScriptの命令や関数ではなくHTMLの要素の一つです。
<canvas id="output" width="300" height="300"></canvas>
サンプルコード①のHTMLの最初の行、この部分でcanvas要素が用意されます。idをつけて、width(横幅)height(高さ)を300pxに設定しています。たったこれだけですが、あとはJavaScriptを使ってこのcanvas上にさまざまな図形を自由に描けるようになりました。

JavaScript // canvasの準備

var canvas = document.querySelector("#output");
var context = canvas.getContext("2d");

JavaScriptの最初の数行はJavaScriptでcanvasを扱うためのお約束のコードのセットです。このまま覚えてしまってOKです。もちろんcanvas,contextはただの変数名ですのでここは好きな名前にしてもらってもOKです。特にcontextはこのあと図形を描く時に何度も使う変数なので、できるだけ短くctxなどという変数名をつける人が多いですね。

JavaScript //「アクション」の設定〜長方形を描く

まずRECTボタンが押されたときに実行されるrect()から。

function rect() {
   context.beginPath()
   context.strokeRect(50, 50, 100, 150);
}

context.beginPath();は新しいパス(図形の辺、線のような意味)を描きはじめる宣言です。直前まで書いていたパスをリセットする意味があるので線を一旦区切りたいときには必ず書いておきましょう。尚、contextはさきほど「//canvasの準備」のところで用意した変数ですので、別の名前にしていたらそれに合わせてください。

次のcontext.strokeRect(50, 50, 100, 150);rect(rectangle=長方形)をstroke(描く)という意味で、4つの数値(パラメータ)は前から順に「長方形の左上のx座標」「長方形の左上のy座標」「長方形の横幅」「長方形の高さ」をpx単位で書きます。実行結果の長方形とよく見比べて確認してみてください。

ちなみに座標について補足すると画面の左上が(0,0)です。今回のサンプルコードでは「//canvasの準備」のところでcanvasの幅と高さを300pxに設定したので、画面の右下が(300,300)になります。

JavaScript //「アクション」の設定〜円を描く

次にCIRCLEボタンを押した時に実行されるcircle()を見てみましょう。

function circle() {
   context.beginPath()
   context.arc(150, 200, 60, 0, Math.PI * 2);
   context.stroke();
}

まずは、context.arc(150, 200, 60, 0, Math.PI * 2);の部分。arcは円や円弧(円の一部)を描ける命令です。5つのパラメータはそれぞれ、「中心のx座標」「中心のy座標」「半径」「円弧の開始角度」「円弧の終了角度」です。今回は円弧でなく円を描きたいので後ろの2つは気にせずにひとまず0,Math.PI*2にしておいてください。

strokeRectと違ってarcはこれだけでは画面には何も描かれません。context.stroke();のところではじめてそこまで準備したパスが画面上に描かれます。

JavaScript //「アクション」の設定〜クリアする

最後にCLEARボタンで実行されるclear()を見てみます。

function clear() {
   context.clearRect(0, 0, 300, 300);
}

context.clearRect(0, 0, 300, 300);これは画面上の指定した部分をクリアする命令です。4つのパラメータは「クリアしたいエリアの左上のx座標」「同じくy座標」「横幅」「高さ」です。画面全体だけでなく一部をクリアすることもできます。

ランダムな長方形や円をたくさん表示

プログラミング教材#8のサンプルコード②

See the Pen 教材#8canvas-2 by programmingbird (@programmingbird) on CodePen.

応用バージョンとして、ボタンを押すたびにサイズや位置が異なる長方形や円を表示させるサンプルコードを用意してみました。RECTやCIRCLEボタンを何回も押して見ると、ちょっとした現代アートのような絵柄ができあがります。

プログラミング教材#8 サンプルコード②の解説

JavaScript //「アクション」の設定

ざっと見ていただければわかるように、コードの基本構成はサンプルコード①とほとんど同じです。違うのは、長方形を描くstrokeRectや円を描くarcのパラメータの部分。サンプルコード①では具体的な数値が入っていたところに、なんだかiRand(300)のように見慣れないものが入っています。これはJavaScriptに用意されている関数ではなくて、オリジナルで定義したユーザー定義関数です。同じコードの中で何回も必要になる処理はユーザー定義関数にしておくことで、コードをすっきりシンプルに描くことができます。グラフィックの描画という今回のテーマからは外れてしまいますが、ユーザー定義関数を使うよい事例なので詳しく見てみましょう。

JavaScript// 上限指定でランダムな整数を作るオリジナル関数

function iRand(n) {
   return Math.floor(Math.random() * n);
}

作りたいのは「上限を指定してランダムな整数を作ってくれる関数」です。座標や半径をランダムに指定したい場合に便利そうですよね。iRandというのは適当につけた関数名です。もちろん好きに変えてくれてもOKです。ポイントはiRand(n) のnの部分。これは引数(ひきすう)と言って、実際に関数を呼び出す場合に特定の数値を渡すことができる仕組みです。

呼び出している部分、例えばrect()の中のiRand(300)を見てみると、カッコの中に300と書いてあるので、iRandが実行されるときn=300になるわけです。

Math.floor(Math.random() * n)でn=300であれば、0〜300未満のランダムな整数が生成されることはプログラミング教材#4 乱数を利用するで学習済みですね。これをreturnによって返すことで、さきほどiRand(300)と書いていた部分は実行するたびに異なる0〜300未満のランダムな整数に置き換わることになります。

もしこのユーザー定義関数を用意しなければ、rect()やcircle()の中身にMath.floor(Math.random() * n)という同じコードが何回も書かれることになり、とても見づらいコードになってしまうでしょう。今回の例のようなユーザー定義関数の活用は、よりきれいなコード、メンテナンスのしやすいコードを書くためにとても重要なのでぜひ覚えておいてください。