p5.jsの続きです。前回は「Generative Design with p5.js」の文字編の「01」を見ました。今回は画像編「P.4. 画像」の「01」を見ていきます。それでは行きましょう!
【目次】
※参考:【p5.js】Generative Design with p5.js「文字 P_3_0_01」のコードを読み解く - クモのようにコツコツと
※p5.jsを習得するためにやったことまとめ
qiita.com
完成品
書籍「Generative Design with p5.js」より
Generative Design with p5.js - [p5.js版ジェネラティブデザイン] ―ウェブでのクリエイティブ・コーディング
- 作者:Benedikt Gross,Hartmut Bohnacker,Julia Laub
- 発売日: 2018/06/22
- メディア: 単行本
ソースコード一覧
※参考:Generative Design with p5.js[p5.js版ジェネラティブデザイン] ―ウェブでのクリエイティブ・コーディング
「画像 P_4_0_01」のコード
最初は1枚の画像が表示されている。キャンバス上にカーソルを置くと画像サイズが変わり、分割して並ぶ表示になる。カーソルを右に動かすと画像の幅が縮まり、下に動かすと画像の高さが縮まる。
JSコード全体
// P_4_0_01 // // Generative Gestaltung – Creative Coding im Web // ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018 // Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni // with contributions by Joey Lee and Niels Poldervaart // Copyright 2018 // // http://www.generative-gestaltung.de // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * draw a grid of streched copies of an image * * MOUSE * position x : tile count horizontally * position y : tile count vertically * * KEYS * s : save png */ 'use strict'; var img; function preload() { img = loadImage('data/image.jpg'); } function setup() { createCanvas(650, 450); } function draw() { var tileCountX = mouseX / 3 + 1; var tileCountY = mouseY / 3 + 1; var stepX = width / tileCountX; var stepY = height / tileCountY; for (var gridY = 0; gridY < height; gridY += stepY) { for (var gridX = 0; gridX < width; gridX += stepX) { image(img, gridX, gridY, stepX, stepY); } } } function keyReleased() { if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png'); }
前半のコメント部分はクレジット。
その次の概要部分の訳。
画像の引き伸ばされたコピーのグリッドを描画
マウス
位置x:水平方向のタイル数
位置y:垂直方向のタイル数キー
s:保存png
全体構成
まずは大枠部分
var img; function preload() { // ページ読み込み前の処理() } function setup() { // ページ読み込み時の処理 } function draw() { // 一定時間ごとに繰り返し実行 } function keyReleased() { // キーが離れた時の処理 }
冒頭にグローバル変数でimg
が宣言されている。値はまだない。
var img;
setup()
メソッドはページ読み込みの前に行われる処理で、ここの処理が終わるまでsetup()
の中に非同期な処理が書かれていても実行されない。
Called directly before setup(), the preload() function is used to handle asynchronous loading of external files in a blocking way. If a preload function is defined, setup() will wait until any load calls within have finished.
setup()の直前に呼び出されるpreload()関数は、外部ファイルの非同期ロードをブロックする方法で処理するために使用されます。 プリロード関数が定義されている場合、setup()は内部のロード呼び出しが完了するまで待機します。
それ以外のメソッドはこれまでも出てきたもの。
※参考:【ビジュアルコーディング】p5.jsを習得するためにやった事 まとめ(随時更新) - Qiita
preload()の中身
ページ読み込み前の処理
function preload() { img = loadImage('data/image.jpg'); }
- 変数
img
にてloadImage()
メソッドで画像image.jpg
を読み込む
loadImage()
メソッドは画像を読み込んで「p5.Image」にする。
Loads an image from a path and creates a p5.Image from it.
パスから画像を読み込み、そこからp5.Imageを作成します。
では「p5.Image」とは何か?
Creates a new p5.Image. A p5.Image is a canvas backed representation of an image.
新しいp5.Imageを作成します。 p5.Imageは、キャンバスに裏打ちされた画像の表現です。
「裏打ち」ってなんだ(笑)canvas要素の画像に変換すると言った意味のようだ。
なるほど、事前にこの作業を行ってからsetup()
の処理を実行するわけだ。
setup()の中身
ページ読み込み時の処理
function setup() { createCanvas(650, 450); }
- 幅650px、高さ450pxのキャンバスを作る
setup()
メソッドはとても簡素な内容。
draw()の中身
draw()の中身(全体)
一定時間ごとに繰り返し実行
function draw() { var tileCountX = mouseX / 3 + 1; var tileCountY = mouseY / 3 + 1; var stepX = width / tileCountX; var stepY = height / tileCountY; for (var gridY = 0; gridY < height; gridY += stepY) { for (var gridX = 0; gridX < width; gridX += stepX) { image(img, gridX, gridY, stepX, stepY); } } }
ここが今回のメインになるので部分ごとにみていく。
変数設定
まず変数をいくつか設定している。
var tileCountX = mouseX / 3 + 1; var tileCountY = mouseY / 3 + 1; var stepX = width / tileCountX; var stepY = height / tileCountY;
- 変数
tileCountX
はマウスの横位置を3で割って1を足す - 変数
tileCountY
はマウスの縦位置を3で割って1を足す - 変数
stepX
は全体幅をtileCountX
で割る - 変数
stepY
は全体高さをtileCountY
で割る
マウスを上下左右に動かすと画像サイズが変わる動きの元になる値だな。tileCountX
とtileCountY
に1
を足すのは最小値を0にしないためだな。そしてマウスの横位置が全体の1/3くらいの場所にあったらそれがさらに3に割られて1/9のサイズになる。
多重ループ(外側の条件)
次からは多重ループになっている。外側から見ていく。
for (var gridY = 0; gridY < height; gridY += stepY) { // 処理 }
- 条件1:変数
gridY
の初期値は0
- 条件2:
gridY
を全体高さの値に達するまで繰り返す - 条件3:
gridY
にstepY
を加算する
最初に画像の高さに関わるループの条件。1回ごとに冒頭の変数で設定されたstepY
を全体高さに達するまで足していく。
多重ループ(内側の条件)
次、内側のループを見る
for (var gridY = 0; gridY < height; gridY += stepY) { for (var gridX = 0; gridX < width; gridX += stepX) { // 処理 } }
- 条件1:変数
gridX
の初期値は0
- 条件2:
gridX
を全体幅の値に達するまで繰り返す - 条件3:
gridX
にstepX
を加算する
画像の幅に関わるループの条件。1回ごとに冒頭の変数で設定されたstepX
を全体幅に達するまで足していく。
多重ループ(処理部分)
最後にループの中身の処理部分を見る。
for (var gridY = 0; gridY < height; gridY += stepY) { for (var gridX = 0; gridX < width; gridX += stepX) { image(img, gridX, gridY, stepX, stepY); } }
image()
メソッドを実行。引数は左からimg
、gridX
、gridY
、stepX
、stepY
image()
メソッドは画像編で初めて出てきた。画像をp5.jsキャンバスに描画するメソッド。
image(img, x, y, [width], [height])
引数の意味
img
は表示する画像x
は左上からの横位置y
は左上からの縦位置width
は画像の幅(オプション)height
は画像の高さ(オプション)
img
の画像がループで追加される。その位置とサイズがここで決まる。gridX
とgridY
は画像の位置になる。stepX
とstepY
は画像のサイズになる。
一連の処理がマウスの動き合わせてリアルタイムに行われる。それによって格子状の画像配置になるわけだ!
keyReleased()の中身
キーが離れた時の処理
function keyReleased() { if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png'); }
- もし「s」または「S」のキーボードだったらpngの画像を保存する
keyReleased()
メソッドもいつもの画像保存の内容だ。
最後に
ということで、Generative Designの最後の1章「画像」編にも入りました。章によって使われるメソッドは異なるんですが、最初に進めた「色編」の「3」より他の章の「1」の方が内容がシンプルに感じました。各章、内容が進むに従ってだんだん高度な内容になっていくと思われます。
ということで引き続き「色」「動き」「文字」「画像」の4章を並行して読み解いて行きたく思います。(色は3番目まで進んでいるので、しばらくは他の3章がそこに追いつくまで進めます)
それではまた!
※p5.jsを習得するためにやったことまとめ
qiita.com