p5.jsの続きです。前回は「Generative Design with p5.js」の「P.2. 形」の「02」「03」を見ました。今回は画像編「P.3. 文字」の「P_3_1_1_01」を見ていきます。それでは行きましょう!
【目次】
- 文字 P_3_1_1_01
- JSコード全体
- 全体構成
- グローバル変数
- setup()メソッドの中身
- draw()メソッドの中身
- keyReleased()メソッドの中身
- keyTyped()メソッドの中身
- 最後に
※参考:前回記事
【p5.js】Generative Design with p5.js「形 P_2_0_02、03」のコードを読み解く - クモのようにコツコツと
※参考:p5.jsを習得するためにやったことまとめ
qiita.com
文字 P_3_1_1_01
書籍「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_3_1_1_01
赤く点滅するバーがだんだん伸びる。早くタイピングすると小さい文字が出て、遅くタイピングすると大きい文字が出る。
※参考:p5.js Web Editor
JSコード全体
// P_3_1_1_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. /** * typewriter. time reactive. * * MOUSE * position y : adjust spacing (line height) * * KEYS * a-z : text input (keyboard) * backspace/delete : delete last typed letter * ctrl : save png */ 'use strict'; var textTyped = 'Type slow and fast!'; var fontSizes = [textTyped.length]; var minFontSize = 15; var maxFontSize = 800; var newFontSize = 0; var pMillis = 0; var maxTimeDelta = 5000.0; var spacing = 2; // line height var tracking = 0; // between letters var font; function setup() { createCanvas(800, 600); font = 'Arial'; noCursor(); noStroke(); // init fontSizes for (var i = 0; i < textTyped.length; i++) { fontSizes[i] = minFontSize; } } function draw() { background(255); textAlign(LEFT); fill(0); spacing = map(mouseY, 0, height, 0, 120); translate(0, 200 + spacing); var x = 0; var y = 0; var fontSize = 20; for (var i = 0; i < textTyped.length; i++) { // get fontsize for the actual letter from the array fontSize = fontSizes[i]; textFont(font, fontSize); var letter = textTyped.charAt(i); var letterWidth = textWidth(letter) + tracking; if (x + letterWidth > width) { // start new line and add line height x = 0; y += spacing; } // draw letter text(letter, x, y); // update x-coordinate for next letter x += letterWidth; } // blinking cursor after text var timeDelta = millis() - pMillis; newFontSize = map(timeDelta, 0, maxTimeDelta, minFontSize, maxFontSize); newFontSize = min(newFontSize, maxFontSize); fill(200, 30, 40); if (int(frameCount / 10) % 2 == 0) fill(255); rect(x, y, newFontSize / 2, newFontSize / 20); } function keyReleased() { // export png if (keyCode == CONTROL) saveCanvas(gd.timestamp(), 'png'); } function keyTyped() { if (keyCode >= 32) { textTyped += key; fontSizes.push(newFontSize); } else if (keyCode == BACKSPACE || keyCode == DELETE) { if (textTyped.length > 0) { textTyped = textTyped.substring(0, max(0, textTyped.length - 1)); fontSizes.pop(); } } // reset timer pMillis = millis(); }
冒頭コメントの前半はクレジット。 後半の概要の訳。
タイプライター。 時間反応。 マウス 位置y:間隔を調整します(行の高さ) キー a-z:テキスト入力(キーボード) バックスペース/削除:最後に入力した文字を削除します ctrl:pngを保存
全体構成
// グローバル変数 var textTyped = 'Type slow and fast!'; // 他 function setup() { // ページ読み込み時の処理 } function draw() { // 一定時間ごとに繰り返し実行 } function keyReleased() { // キーが離れた時の処理 } function keyTyped() { // 文字キーを押した時の処理 }
keyTyped()
メソッドは文字以外のキーは無視するようだ。
The keyTyped() function is called once every time a key is pressed, but action keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored.
keyTyped()関数は、キーが押されるたびに1回呼び出されますが、Backspace、Delete、Ctrl、Shift、Altなどのアクションキーは無視されます。
グローバル変数
今回は冒頭のグローバル変数の設定が多い。改行が入って3グループに分かれている。
最初のグループ
var textTyped = 'Type slow and fast!'; var fontSizes = [textTyped.length]; var minFontSize = 15; var maxFontSize = 800; var newFontSize = 0;
- 変数
textTyped
は文字列「Type slow and fast!'」 - 変数
fontSizes
は配列でtextTyped
の文字数(length
)が入る - 変数
minFontSize
、maxFontSize
、newFontSize
は数値。
textTyped
の文字数は19なので配列fontSizes
には19が入る。
次のグループ
var pMillis = 0; var maxTimeDelta = 5000.0;
- 変数
pMillis
、maxTimeDelta
共に数値
最後のグループ
var spacing = 2; // line height var tracking = 0; // between letters var font;
- 変数
spacing
(線の高さ)、tracking
(文字間)は数値 - 変数
font
は宣言のみで値はまだ無い
setup()メソッドの中身
ページ読み込み時の処理
function setup() { createCanvas(800, 600); font = 'Arial'; noCursor(); noStroke(); // init fontSizes for (var i = 0; i < textTyped.length; i++) { fontSizes[i] = minFontSize; } }
createCanvas()
メソッドで幅800px、高さ600pxのキャンバスを作成font
をArial
にnoCursor()
メソッドでカーソルを非表示noStroke()
メソッドで線を無しに- for文で
textTyped
の数量分ループ - 配列
fontSizes
のi
番目にminFontSize
を入れる
minFontSize
は「15」なので配列fontSizes
には「15」が19個(textTyped
の文字数)入る。
draw()メソッドの中身
draw()メソッド全体
一定時間ごとに繰り返し実行
function draw() { background(255); textAlign(LEFT); fill(0); spacing = map(mouseY, 0, height, 0, 120); translate(0, 200 + spacing); var x = 0; var y = 0; var fontSize = 20; for (var i = 0; i < textTyped.length; i++) { // get fontsize for the actual letter from the array fontSize = fontSizes[i]; textFont(font, fontSize); var letter = textTyped.charAt(i); var letterWidth = textWidth(letter) + tracking; if (x + letterWidth > width) { // start new line and add line height x = 0; y += spacing; } // draw letter text(letter, x, y); // update x-coordinate for next letter x += letterWidth; } // blinking cursor after text var timeDelta = millis() - pMillis; newFontSize = map(timeDelta, 0, maxTimeDelta, minFontSize, maxFontSize); newFontSize = min(newFontSize, maxFontSize); fill(200, 30, 40); if (int(frameCount / 10) % 2 == 0) fill(255); rect(x, y, newFontSize / 2, newFontSize / 20); }
ここが一番ボリュームが多いのでブロックごとに見ていく。
draw()
関数
draw()
関数の中身
function draw() { background(255); textAlign(LEFT); fill(0);
background()
メソッドで背景色をRGB共255(白)にtextAlign()
メソッドの引数LEFT
で文字を左寄せにfill()
メソッドの引数0
で塗りをRGB共0(黒)に
変数spacingでマッピング
spacing = map(mouseY, 0, height, 0, 120);
spacing
の値をmap()
メソッドに。引数は左からmouseY
,0
,height
,0
,120
translate()
メソッドの引数
map()
はマッピングで前回も出てきた。
※参考:【p5.js】Generative Design with p5.js「形 P_2_0_02、03」のコードを読み解く - クモのようにコツコツと
「mouseY
(マウスの縦位置)のうち0
〜height
(キャンバス高さ)までの範囲を0
〜120
までの範囲にマッピングする」という意味。
translate()メソッド実行
translate(0, 200 + spacing);
translate()
メソッドを実行。引数は左から0
,200 + spacing
translate()
メソッドも前回に出てきた。オブジェクトの移動量の設定をするメソッド。開始点が0で終了点は200に文字間を足した値。
for文
for文(全体)
次にfor文
var x = 0; var y = 0; var fontSize = 20; for (var i = 0; i < textTyped.length; i++) { // get fontsize for the actual letter from the array fontSize = fontSizes[i]; textFont(font, fontSize); var letter = textTyped.charAt(i); var letterWidth = textWidth(letter) + tracking; if (x + letterWidth > width) { // start new line and add line height x = 0; y += spacing; } // draw letter text(letter, x, y); // update x-coordinate for next letter x += letterWidth; }
ここもボリュームが多いので部分ごとに見ていく。
変数設定
まずfor文に使われる変数が3つ設定されている。
var x = 0; var y = 0; var fontSize = 20;
- 変数
x
、y
、fontSize
共に値は数値
for文条件
まずfor文の条件
for (var i = 0; i < textTyped.length; i++) { // 処理 }
- 変数
i
の初期値は0 textTyped
の文字数length
分ループするi
に1ずつ加算する
配列から文字サイズを取得
// get fontsize for the actual letter from the array fontSize = fontSizes[i]; textFont(font, fontSize); var letter = textTyped.charAt(i); var letterWidth = textWidth(letter) + tracking;
- コメント訳:配列から実際の文字のフォントサイズを取得します
fontSize
をに配列fontSize
のi
番目にtextFont()
メソッドを実行。引数は左からfont
,fontSize
- 変数
letter
をtextTyped.charAt()
メソッド(引数はi
)の結果に。 - 変数
letterWidth
はtextWidth()
メソッド(引数はletter
)と文字間tracking
の合計
textFont()
メソッドはフォントの設定で、第1引数はfont
のフォントであるArial
、第2引数はfontSize
で上で定義されている配列fontSizes
のi
番目のサイズが入る。
charAt()
はJSの組み込みメソッドで文字を左から1文字ずつ取得する。
※参考:String.prototype.charAt() - JavaScript | MDN
変数letterWidth
(文字幅)はletter
の文字幅(textWidth()
)と文字間(tracking
)の合計
新しい行を開始
if (x + letterWidth > width) { // start new line and add line height x = 0; y += spacing; }
- もし
x
とletterWidth
の合計がwidth
より多ければ - コメント訳:新しい行を開始して行の高さを追加する
x
を0にy
にspacing
を追加する
これでで新しい行(左から0、文字間文下に下がった位置)になる。
テキスト描画
// draw letter text(letter, x, y); // update x-coordinate for next letter x += letterWidth;
- コメント訳:手紙を描く
text()
メソッドを実行。引数は左からletter
,x
,y
- コメント訳:次の文字のx座標を更新する
x
にletterWidth
を追加
text()
メソッドはテキストの描画。引数の意味は下記
text(str, x, y, [x2], [y2])
配列letter
の文字をx
、y
の位置に描画する
カーソルの点滅
変数設定
// blinking cursor after text var timeDelta = millis() - pMillis; newFontSize = map(timeDelta, 0, maxTimeDelta, minFontSize, maxFontSize); newFontSize = min(newFontSize, maxFontSize);
- コメント訳:テキストの後のカーソルの点滅
- 変数
timeDelta
はmillis()
からpMillis
を引いた数字 newFontSize
はmap()
メソッドでtimeDelta
の0
〜maxTimeDelta
をminFontSize
〜maxFontSize
にマッピングした値newFontSize
はmin()
メソッドでnewFontSize
とmaxFontSize
のうち小さい方の値
Returns the number of milliseconds (thousandths of a second) since starting the sketch (when setup() is called).
(setup()が呼び出されたとき)スケッチを開始してからのミリ秒数(1000分の1秒)を返します。
min()
メソッドは最小値を返すメソッド。newFontSize
とmaxFontSize
のうち、小さい方を返す。
Determines the smallest value in a sequence of numbers, and then returns that value.
一連の数値の最小値を決定し、その値を返します。
処理設定部分
fill(200, 30, 40); if (int(frameCount / 10) % 2 == 0) fill(255); rect(x, y, newFontSize / 2, newFontSize / 20); }
fill()
メソッド実行、引数は左から200
,30
,40
- もし
frameCount
を10で割った数の整数(int
)を2で割った数字の余りが0なら塗りfill()
メソッドの引数を255
に rect()
メソッドを実行。引数は左からx
,y
,newFontSize
を2で割った値,newFontSize
を20
で割った値
fill()
メソッドは塗りで画面上の赤いバーの色はここで設定されている。
if文の条件にあるframeCount
はフレーム数。
int
は整数。2で割り切れる数値=偶数の時に塗りが白になって、バーが点滅して見える。
rect()
メソッドは色の記事でも出てきた長方形を作るメソッド。バーの形はここで設定されている。第1〜2引数は位置で第3〜4引数がサイズ。サイズはnewFontSize
を2や20で割った数。
※参考:【p5.js】Generative Design with p5.js「色 P_1_0_02」のコードを読み解く - クモのようにコツコツと
keyReleased()メソッドの中身
キーが離れた時の処理
function keyReleased() { // export png if (keyCode == CONTROL) saveCanvas(gd.timestamp(), 'png'); }
- もし
CONTROL
キーを押したらsaveCanvas()
メソッドでpng
画像を保存
ここはいつもある画像保存設定。
keyTyped()メソッドの中身
文字キーを押した時の処理
function keyTyped() { if (keyCode >= 32) { textTyped += key; fontSizes.push(newFontSize); } else if (keyCode == BACKSPACE || keyCode == DELETE) { if (textTyped.length > 0) { textTyped = textTyped.substring(0, max(0, textTyped.length - 1)); fontSizes.pop(); } } // reset timer pMillis = millis(); }
- もしキーコードが
32
よりも大きいキーかったら
textTyped
にkey
を追加する
fontSizes
でpush()
メソッド実行。引数はnewFontSize
- さもなくば、
BACKSPACE
またはDELETE
キーを押したら
もしtextTyped
の数length
が0より多ければ
textTyped
でtextTyped
のsubstring()
メソッドを実行。 引数は左から0
,max()
メソッドで、max()
の引数は左から0
,textTyped
の数length
マイナス1
fontSizes
のpop()
メソッドを実行 - リセットタイマー処理、
pMillis
をmillis()
メソッドの結果に
キーコード32は「Apps」のようだが、それより前のDelateやEnterなどの制御キー以外を適用させる条件のようだ。
※参考:キーコード一覧
push()
メソッドはその下のpop()
メソッドとセットで使われる。push()
は現在の描画スタイル設定と変換を保存し、pop()
は設定を復元する。
※参考:【p5.js】Generative Design with p5.js「形 P_2_0_02、03」のコードを読み解く - クモのようにコツコツと
substring()
メソッドはJSの組み込み関数で文字を取り出す。
※参考:String.prototype.substring() - JavaScript | MDN
max()
メソッドは数値の最大値を返す
Determines the largest value in a sequence of numbers, and then returns that value.
一連の数値の最大値を決定し、その値を返します。
millis()
メソッドはスケッチを開始してかららの時間(ミリ秒)を返す
Returns the number of milliseconds (thousandths of a second) since starting the sketch (when setup() is called).
(setup()が呼び出されたとき)スケッチを開始してからのミリ秒数(1000分の1秒)を返します。
この関数の処理で、キーで打った文字を画面に反映させたり、キーを打つ時間をバーの大きさに反映させたりしているわけだ。
最後に
今回は結構ボリュームがあるように感じましたが、細かく見てみるとこれまで出てきたメソッドも多く、だんだんp5.jsのコードの見慣れて来ている感じがします!引き続きこの調子でコツコツと進めて行きたく思います。それではまた!
※参考:p5.jsを習得するためにやったことまとめ
qiita.com