p5.jsを使って、図形を描いたり、ボタンを表示してみよう

Monaca Educationでは、新しくアプリケーションを作成するとき、p5.jsのテンプレートを選んで、プロジェクトを作成できます。そうして作ったプロジェクトでは、5.jsを使って、簡単に図形を描画するアプリケーションを作成できます。

この記事では、p5.jsを使って図形を描き、画面にボタンを表示するアプリケーションを作ります。

Monaca Educationでp5.jsを使う方法

新規プロジェクト作成でp5.jsを選択して下さい。

p5.jsとは

p5.js(https://p5js.org/)は、無料で使える、オープンソースのJavaScriptライブラリです。Processingというビジュアルアートを作成するためのプログラム言語・環境があり、それをWebブラウザで実行できるよう、JavaScriptライブラリにしたものです。

p5.jsを使うことで、JavaScriptプログラムから簡単に絵や図を描くことができます。画像や動画、音声データを扱うこともできます。

p5.jsについて調べるには

p5.jsの公式サイトのドキュメントは、とても充実しています。簡単に始める方法( https://p5js.org/get-started/ )はもちろん、Webブラウザでアクセスして機能を試すページ( https://editor.p5js.org/ )も用意されています。
残念ながら公式サイトには日本語のサポートはありませんが、ChromeブラウザのGoogle翻訳プラグインなどを使って翻訳させれば、(やや不自然な文にはなるものの)日本語で読むこともできます。
また、市販書籍『p5.jsプログラミングガイド 改訂版』(松田晃一著、カットシステム)は、p5.jsが持つ豊富な機能を、多数の簡明なサンプルを使いながら説明していて、とても分かりやすいです。

HTML Canvasとp5.js

もともとHTMLには、Canvas(キャンバス)という要素があります。キャンバスを操作するCanvas APIを使ってプログラムを作成することで、画面に図を描くことができます。HTML Canvasはとても強力で、高度な描画ができる一方、習得が少し難しい側面があります。

p5.jsは、HTMLのキャンバスを使って図を描くことができるライブラリです。Canvas APIよりも簡単に作図できるように工夫されています。

p5.jsを扱うためのHTMLファイルを作る

p5.jsでは、p5.jsのためのHTMLをほとんど書かなくても、p5.jsによる図形の描画が動作するように調整されます。単に、図形を描画するだけのアプリケーションであれば、それで問題ありません。

ですが、今回は、以下で説明するHTMLを作成することにします。p5.jsによる図形描画と、他のHTML/CSS/JavaScriptの機能とを組み合わせられるようにするためです。

HTMLの文書の構造の模式図は以下の通りです。短い説明の後に、実際のHTMLがあります。

p5.jsを使って図形を描画するcanvasが中心にあります。このキャンバスを含めるための入れもの(コンテナ)の要素があります。この例では要素<div>です。<div>の
中に<canvas>があるわけです。

サンプルのHTMLには、すぐ下にもう一つタグ<div>を書いています。ここに、ユーザーがアプリを操作するためのGUI部品(ボタンやスライダーなど)を配置することにします。p5.jsは、図形を描くだけでなく、ボタンやスライダーなどのGUI部品を表示させることができます。それらのGUI部品を配置する入れもの(パネル)を用意しているのです。

キャンバスを入れるコンテナと、GUI部品を並べるパネルとを、一つのタグ要素(例ではタグ<article>)に入れて、他と分離しやすいようにしています(「p5.js関係のエリア」)。

p5.jsを用いないコンテンツを含めるために、例では2つ目の<article>要素を使っています。このように別のタグ<article>で領域を作ることは、必須ではありません。今回は、p5.jsによる描画コンテンツに続けて、別のコンテンツのためのHTMLのタグを書く例として示しました。

実際のHTMLファイルの内容は以下の通りです。ただし、タグ<body>以下の内容のみ記載しています。


<body>
   <article style="background-color:dodgerblue">
       p5.jsを使って描画するコンテンツ
       <div id="p5CanvasContainer"
               align="center"
               style="background-color:deepskyblue">
       </div>
       <div id="p5UiPanel" style="background-color:orange">
       </div>
   </article>
   <article style="background-color:lawngreen">
       p5.jsを使わないコンテンツ
   </article>
</body>

キャンバスのコンテナにする要素<div>には、ID属性を使って”p5CanvasContainer”というIDを付けています。
GUI部品を表示するための要素<div>には、ID属性を使って”p5UiPanel”というIDを付けています。

なお、このHTMLでは、見た目で区別できるように、HTMLの属性styleを使ってそれぞれの要素の背景色を決めています。

p5.jsの基本の枠組み

ここで、p5.jsの基本的な動作の枠組みを紹介します。


// 初期化処理(最初に1回だけ実行)
function setup() {
}
// 描画処理(何度も、定期的に繰り返し実行)
function draw() {
}

HTMLやCSS、JavaScriptファイルがダウンロードされ、プログラムの実行が始まると、p5.jsは最初に1回だけ、関数setup()を実行します。

その後、 関数draw()が呼び出されます。関数draw()には、p5.jsが用意している関数を使って、図形を書く処理を書きます。たとえば、次のプログラムは、関数rect()で四角形を、関数triangle()で三角形を描いています。


function draw() {
   // 四角形を描く
   rect(80, 80, 120, 120);
   // 三角形を描く
   triangle(120, 120, 240, 220, 280, 140);
}

関数rect()には、四角形の左上の座標と、横・縦の長さを指定しています。関数triangle()には、三角形の3つの頂点の座標を渡しています。

p5.jsの座標の考え方

少し注意が必要なのは、座標の考え方です。数学で扱う座標では、四つの象限の中心に原点(0,0)があり、原点より左・下はマイナスの値で、右・上はプラスの値としています。しかし、p5.jsやHTML Canvasでは、キャンバスの左上の座標を(0,0)とし、X軸の値も、Y軸の値も、プラスの値しか取らない座標になっています。

関数draw()は、1秒間に何十回も呼び出される

p5.jsは、1秒間に数十回、関数draw()を繰り返し、定期的に呼び出して、画面の再描画を行います。
関数が呼び出されるたびに、描画する点や線、色を変更すると、アニメーションを作ることができます。

つまり、プログラム開始時に実行する関数setup()でプログラムの初期化(=その後の処理の準備)を行い、1秒間に何度も呼び出される関数draw()を使って絵を描く、という書き方になります。

※「1秒間に何回、画面を描きなおすか」を表す数値をフレームレートと呼びます。デフォルトのフレームレートは、動作させているPCの環境によって変わります(1秒間に60回になる環境が多いようです)。フレームレートの値を指定して変更できますが、今回は省略します。興味のある人はp5.jsの公式ドキュメントを調べてみてください(ヒント:関数framerate())。

sketch.js

p5.jsテンプレートを使ってプロジェクトを作成すると、自動でプロジェクト内にsketch.jsファイルが作られます。このsketch.jsに、p5.jsのプログラムを書きます。あらかじめ関数setup()と関数draw()の枠組みは作成済みなので、必要な箇所を書き加えていきます。

プロジェクトのindex.htmlファイルは、p5.jsライブラリと、このsketch.jsをリンクしています。自動的にp5.jsを準備し、sketch.jsに書かれたプログラムを実行します。

サンプルプログラム

サンプルプログラムは、次のような表示をします。画面中央の白い正方形の部分がキャンバスです。sketch.jsの中に書いたp5.jsのプログラムによって、正方形と三角形が描かれています。
また、画面下のオレンジ色の部分に、「クリック!」というボタンが配置されています。

その他の部分は、HTML(index.html)ファイルに書いてあります。

画面下、オレンジ色の部分にある「クリック!」というボタンを押すと、キャンバス上に「クリックされた!」と表示されます。

サンプルプログラムのsketch.js

サンプルプログラムのsketch.jsの内容を見てみます。

まず、関数setup()からです。
最初に、createCanvas(300,300)という行があります。ここで、キャンバスのサイズ(縦・横)を指定して、キャンバスを作っています。作成したキャンバスを変数myCanvasに格納しています。
次の行で、myCanvasのメソッドparent()を使い、キャンバスの親要素を指定します。引数の文字列は、HTML(index.html)に書いておいた要素

<

div>のID属性の値です。つまり、作成したキャンバスを、指定した要素

<

div>の子要素としています。さらに、myCanvasのメソッドstyle()を使い、CSSを指定して、キャンバスの背景色を白にしています。


// setup関数
//  アプリケーション起動時に実行される。
//  画面を初期化する関数
function setup() {
   // キャンバスの作成
   let myCanvas = createCanvas(300,300);
   // キャンバスの親要素の指定
   myCanvas.parent("p5CanvasContainer");
   myCanvas.style("background-color:white");
   // ボタンの作成
   let button1 = createButton("クリック!");
   // ボタンの親要素の指定
   button1.parent("p5UiPanel");
   // ボタンがクリックされたときに
   // 実行する関数を指定
   button1.mousePressed(clicked);
}
 
// draw関数
//  定期的に実行される。
//  画面の描画を行う関数
function draw() {
   // 四角形を描く
   rect(80, 80, 120, 120);
   // 三角形を描く
   triangle(120, 120, 240, 220, 280, 140);
}
 
// clicked関数
//  setup関数の中のbutton1.mousePressed()で指定されている。
//  ボタンbutton1について、マウスがクリックされたら、
//  この関数が呼び出される
function clicked(){
   // 文字を表示する
   text("クリックされた!", 10, 20);
}

次の行以降では、画面に追加するボタンを作成・設定します。
まず、関数createButton()を使い、ボタン<button>を作成します。作成したボタンを変数button1に格納しておき、次の行でメソッドparent()を実行して、親要素を決めます。メソッドparent()の引数に指定している文字列は、HTML(index.html)に書いておいた2つめの<div>要素のID属性です。

最後に、button1.mousePressed(clicked)という行がありますが、この行は「マウスのボタンが押されたら、関数clicked()を呼び出すようにしなさい」という指示をしています。
ここで先回りして、sketch.jsの最後にある、関数clicked()を見ておきましょう。関数text()を使い、「クリックされた!」という文言をキャンバス内に表示します。文言の後ろに書かれている二つの数字は、文字の並びの表示を開始する座標を表しています。

最後に、関数draw()を見ておきましょう。下に、プログラムの関数draw()の箇所だけ抜き出しています。


function draw() {
   // 四角形を描く
   rect(80, 80, 120, 120);
   // 三角形を描く
   triangle(120, 120, 240, 220, 280, 140);
}

関数rect()は、キャンバスに四角形を描く関数です。指定されている数字が4つありますが、1つめは、描きたい四角形の、左上の頂点の、X座標の値です。2つめは、描きたい四角形の、左上の頂点の、Y座標の値です。3つめは、四角形の幅で、4つめは四角形の高さです。

関数triangle()は、キャンバスに三角形を描く関数です。6つの引数を渡しています。順に、三角形の1つめの頂点のX座標、同じくY座標、三角形の2つめの頂点のX座標、Y座標、最後に三角形の3つめの頂点のX座標、Y座標で、6つです。この3点を線で結んで、三角形を描くわけです。

p5.jsは、他にも多数の図形を描くための関数が用意されています。また、今回のサンプルプログラムは黒の線で図形を描いただけですが、色を塗ることもできます。
公式サイトにリファレンスがあり、サンプルも豊富です。描きたい図形について、調べてみるとよいでしょう。

まとめ

Monaca Educationで新しいプロジェクトを作成するとき、p5.jsテンプレートを選択すると、簡単にp5.jsのアプリケーションの開発を始められます。
p5.jsプロジェクトでは、関数setup()に初期化処理を、関数draw()に描画処理を描きます。
関数setup()の初期化処理の中で、キャンバスのサイズや、HTMLの親要素を指定しています。
HTML(index.html)の側に、キャンバスを格納するためのコンテナ(<div>)と、GUI要素(ボタンなど)を配置するためのパネル(<div>)を用意しておくと、画面全体のデザインを整えることができますし、p5.jsを使って描く図形と、p5.jsを使わないコンテンツとを、容易に組み合わせ、調整することができます。