#author("2021-06-05T18:26:49+09:00;2021-06-05T16:24:20+09:00","default:inoue.ko","inoue.ko") *p5.js Sample http://p5js.org/ ~ __[[p5.js]]__ を用いたプログラムサンプルを紹介しています。 ~ ***CONTENTS #contents2_1 &aname(patternA); ~ ~ **基本サンプル [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_animation1/]] 黒バックの描画領域が現れて白い正方形が右へ動きます。プロジェクトフォルダに、以下3つのファイルを投入してお試し下さい。 ~ ***index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="p5.min.js"></script> <script src="script.js"></script> <title>Sample Site</title> </head> <body> </body> </html> ~ ***script.js //外部変数 var x=0; // 初期設定 function setup() { // CANVASを生成して <body> へ埋め込み createCanvas(640, 480); frameRate(60); } // アニメーションループ function draw() { background(0); rect(x, 200, 40, 40); x++; if(x>width) x=0; } ~ ***p5.min.js p5.js の基本ライブラリの投入が必要です。 ~ ~ **マウスに反応するサンプル ブラウザ上にマウスの動きの軌跡を描きます。index.html は基本サンプルと同一です(省略します)。script.js のみ、以下と置き換えてお試し下さい。 ~ ***script.js //外部変数 var cnt=0; // 初期設定 function setup() { createCanvas(640, 480); colorMode(HSB,100); noStroke(); } // アニメーションループ function draw() { fill(99,10); rect(0,0,width,height); fill((cnt++)%100,50,99); ellipse(mouseX,mouseY,64,64); } ~ ~ **簡単なアニメーション [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_animation2/]] ボールがウインドウの壁で反射して動きます。index.html は基本サンプルと同一です(省略します)。script.js のみ、以下と置き換えてお試し下さい。 ~ ***script.js var vx=vy=5.0; function setup(){ createCanvas(windowWidth, windowHeight); x=windowWidth/2; y=windowHeight/2; colorMode(RGB); frameRate(60); } function draw(){ fill(0,0,0); //Black rect(0,0,width,height); x = x + vx; y = y + vy; if(x < 0 || windowWidth<x ) vx = vx * -1; if(y < 0 || windowHeight<y ) vy = vy * -1; fill(255,0,0); //Red ellipse(x,y,40,40); } &aname(patternB); ~ ~ **X, Y 2重ループ 2重ループで平面パターンを描きます。マウスの位置が右へいくほど基本図形の半径が大きくなります。 このサンプルでは、描画エリア(CANVAS要素)を div id="container"に割り当てるとともに、ページ上でのレイアウトを CSS で制御しています。 -DEMO:https://koichi-inoue.github.io/p5_Sample01/ -CODE:https://github.com/koichi-inoue/p5_Sample01 ~ ***index.html #gistit(koichi-inoue/p5_Sample01/blob/main/index.html,,400) ~ ***style.css #gistit(koichi-inoue/p5_Sample01/blob/main/style.css,,400) ~ ***script.js #gistit(koichi-inoue/p5_Sample01/blob/main/script.js,,400) ~ ~ **配列変数を使った応用 [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_animation3/]] 配列変数を使って複数のボールを制御する例です。マウスのクリックで、ボールが追加されます。index.html は基本サンプルと同一です。script.js のみ、以下と置き換えてお試し下さい。 ~ ***index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="p5.min.js"></script> <script src="script.js"></script> <title>Sample Site</title> </head> <body> </body> </html> ~ ***script.js var N = 0; var r = new Array(1000); var c = new Array(1000); var x = new Array(1000); var y = new Array(1000); var vx= new Array(1000); var vy= new Array(1000); function setup(){ createCanvas(windowWidth, windowHeight); colorMode(HSB,100); noStroke(); frameRate(60); } function draw(){ fill(0,0,0,10); rect(0,0,width,height); for(i=0; i<N; i++){ x[i] += vx[i]; y[i] += vy[i]; if(x[i] < 0 || x[i] > width) vx[i] *= -1; if(y[i] < 0 || y[i] > height) vy[i] *= -1; fill(c[i],50,100); ellipse(x[i],y[i],r[i],r[i]); } } function mousePressed() { if( N >= 999 ) return; x[N] = mouseX; y[N] = mouseY; vx[N] = random(20)-10; vy[N] = random(20)-10; r[N] = random(5,50); c[N] = random(100); N++; } -この例では、var x = new Array(1000); という書き方で配列を準備していますが、以下のように「空の配列をつくる」という準備の仕方でも動作します。 var x = []; -以下のソースを付け加えると、スペースキーを押した瞬間に全てのボールが画面中心に集合します。 function keyTyped() { if (key === ' ') { for(i=0; i<N; i++){ x[i]= width/2; y[i]= height/2; } } } &aname(circle); ~ ~ **三角関数の利用(基礎) [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_circle/]] 以下のプログラムは、三角関数による振動現象を表現します。単純に円を描くプログラムですが、fx や fy の初期値を変えるとリサージュ図形になります。index.html は基本サンプルと同一です。script.js のみ、以下と置き換えてお試し下さい。 ~ ***index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="p5.min.js"></script> <script src="script.js"></script> <title>Sample Site</title> </head> <body> </body> </html> ~ ***script.js var th = 0.0; var fx = 1.0; var fy = 1.0; function setup() { createCanvas(windowWidth, windowHeight); angleMode(DEGREES); frameRate(60); noStroke(); fill(0,0,0); } function draw() { var A = 0.4*height; //半径 var x = A * cos(fx*th) + width/2; //横振動 var y = A * sin(fy*th) + height/2; //縦振動 ellipse(x,y,8,8); th += 2; } ~ -''解説'' 三角関数 cos(t) や sin(t) は入力値 x の増加にともなって出力 y が振動します。360°(2π)で1回振動。秒間 f x 360° のスピードであれば、f 回振動します。 --以下の処理を t を増加させながら描画を繰り返すと正円が描かれます。 x = A*cos(t); y = A*sin(t); point(x,y); この t の部分を x , y それぞれ 2t, 3t などとして振動数を変えると、横と縦の振動が合成されて様々な図形を描きます。これをリサージュ図形といいます。 --また、以下のように、振幅A自体を振動させると「正葉線」になります。 a = A*sin(8t); x = a*cos(t); y = a*sin(t); point(x,y); ~ ~ **三角関数の利用(少し応用) [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_lissajous/]] 上の例を応用したものです。マウスをクリックすると、その位置によって、 -マウスの ''X'' 座標が大きい(画面右)ほど、横方向の振動数が上がります。 -マウスの ''Y'' 座標が大きい(画面下)ほど、縦方向の振動数が上がります。 index.html は基本サンプルと同一です。script.js のみ、以下と置き換えてお試し下さい。 ~ ***index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="p5.min.js"></script> <script src="script.js"></script> <title>Sample Site</title> </head> <body> </body> </html> ~ ***script.js var th=0.0; var c=0; var fx0 = 1.0; var fy0 = 1.0; var fx1 = 1.0; var fy1 = 1.0; function setup() { createCanvas(windowWidth, windowHeight); colorMode(HSB,100); angleMode(RADIANS); frameRate(60); } function draw() { noStroke(); fill(0,0,0,2); rect(0,0,width,height); var a = 0.4*height; x0 = a * cos(fx0*th) + width/2; y0 = a * sin(fy0*th) + height/2; x1 = a * cos(fx1*th + PI) + width/2; y1 = a * sin(fy1*th + PI) + height/2; c++; stroke( c%100, 100, 100 ); line(x0,y0,x1,y1); ellipse(x0,y0,8,8); ellipse(x1,y1,20,20); th+=0.03; } function mousePressed() { fx1 = mouseX/width * 5; fy1 = mouseY/height * 5; } ~ ~ **関数の利用 [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_function/]] ランダムなRGB値で塗りを設定する関数を使っています。普通にJavaScriptでプログラムを書くのと同様です。index.html は基本サンプルと同一です。script.js のみ、以下と置き換えてお試し下さい。 ~ ***index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="p5.min.js"></script> <script src="script.js"></script> <title>Sample Site</title> </head> <body> </body> </html> ~ ***script.js function setup() { createCanvas(windowWidth, windowHeight); colorMode(RGB); noStroke(); ellipseMode(CORNER); frameRate(3); } function draw() { var step = 32; for( var y=0; y<height; y+=step ){ for( var x=0; x<width; x+=step ){ randomColor(); ellipse(x,y,step,step); } } } function randomColor(){ r = random(256); g = random(256); b = random(256); fill(r,g,b); } ~ ~ **動画のフィルタリング [[→ DEMO>https://design.kyusan-u.ac.jp/SampleSite/p5js_video/]] //参考:[[Sardines.ogg / James Kilfiger>http://commons.wikimedia.org/wiki/File:Sardines.ogg]] 動画を表示するだけであれば、HTML5のvideoタグでも実現できますが、p5.jsを使うと、フィルタ処理などが簡単にできるようになります。この事例では、カラーの動画をリアルタイムでモノクロ化しています。 このサンプルでは、描画エリア(CANVAS要素)を div id="container"に割り当てるとともに、ページ上でのレイアウトを CSS で制御しています。 ~ ***index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <script src="p5/p5.min.js"></script> <script src="p5/addons/p5.dom.min.js"></script> <script src="p5/addons/p5.sound.min.js"></script> <script src="script.js"></script> <link rel="stylesheet" href="style.css" > <title>Sample Site</title> </head> <body> <div id="container"></div> </body> </html> ~ ***style.css #container { width:640px; margin:200px auto; } ~ ***script.js //外部変数 var video; // 初期設定 function setup() { // CANVASオブジェクトを取得 var cv = createCanvas(640, 400); // CANVASの親要素として container を指定 cv.parent("container"); video=createVideo("sample.webm"); video.hide(); video.play(); video.loop(); } // アニメーションループ function draw() { image(video,0,0,width,height); // videoをキャバスに転送 filter(GRAY); } ~ ***必要なライブラリ このサンプルでは、以下のものが必要になります。Completeパッケージに含まれていますので、ダウンロードして投入して下さい。 -p5.min.js -p5.dom.min.js -p5.sound.min.js ~ ~ **Webカメラ映像のキャプチャー -Webカメラをキャプチャーして、ピクセル単位に処理する例です。 -この事例では、あなたのPCのWebカメラを起動します(カメラが必要です)。 -ブラウザが、カメラを起動許可を求めてきますので、「許可」して下さい。 -カメラの映像を他へ転送するような通信操作はしていません。カメラの映像はあなたのブラウザにしか表示されませんので、ご安心下さい。 &color(red){ChromeまたはFirefoxでご覧下さい。}; -CODE:https://github.com/koichi-inoue/VideoCapture -DEMO:https://koichi-inoue.github.io/VideoCapture/ 以下、script.js における画像処理の部分の概説です。 capture.loadPixels(); //瞬間の画像を画素配列に取得 for (var y=0; y<height; y+=8) { for (var x=0; x<width; x+=8) { var i = y * width + x; var b = capture.pixels[i*4+2]; var radius = 8*scale * (255 - b)/255; ellipse(x*scale, y*scale, radius, radius); } } } 1画素4バイトで、4つのデータが別々に配列に格納されるので、例えば、''i'' 番目の画素のRGBα情報は以下の場所でアクセス可能です。 -pixels[ i*4 + 0 ]:R値( 0 - 255) -pixels[ i*4 + 1 ]:G値( 0 - 255) -pixels[ i*4 + 2 ]:B値( 0 - 255)← このサンプルではこの値のみ参照 -pixels[ i*4 + 3 ]:α値( 0 - 255) ~ ~ **Webカメラ映像を録画・保存 -Webカメラをキャプチャーした録画・保存の機能を提供します。 -PCにWebカメラがあることと、カメラの起動を許可することが必要です。 -SAVE を押すと録画した映像が webm ファイルとしてDL保存されます。 &color(red){ChromeまたはFirefoxでご覧下さい。}; -DEMO:https://koichi-inoue.github.io/VideoRecorder -CODE:https://github.com/koichi-inoue/VideoRecorder ~ ~ **音声のキャプチャー -閲覧者のPCに接続されたマイク(内臓マイク)の音声を反映します。 -PCにマイクがあることと、マイクの起動を許可することが必要です。 -マイクから取得した音声は、操作中のブラウザに反映されるだけで、他へ転送するような操作はしていませんのでご安心ください。 &color(red){ChromeまたはFirefoxでご覧下さい。}; -DEMO:https://koichi-inoue.github.io/SoundCapture/ -CODE:https://github.com/koichi-inoue/SoundCapture ~ ~ **音声を録画・保存 -上記と同様のプログラムに、録音、再生、保存の機能を加えています。 -PCにマイクがあることと、マイクの起動を許可することが必要です。 -SAVE を押すと録音した音声がWAVファイルとしてダウンロードされます。 &color(red){ChromeまたはFirefoxでご覧下さい。}; -DEMO:https://koichi-inoue.github.io/SoundRecorder/ -CODE:https://github.com/koichi-inoue/SoundRecorder ~ ~ ~