p5.jsが楽しい。

参考にするのは「The Coding Train」というYouTubeチャンネル。Processingやp5.jsの中の人だと思う方が楽しそうにコーディングしてるのね。

現在は130本以上の動画があがっていて、「ふと」目にとまった動画を模写(or 移植)するようにしてる。最初は真似ることが大切だから。

先人の知識や経験に感謝。

今回「ふと」響いた動画は以下の2本。Processing(Java)からの移植だったのでJavaScriptの基礎を学ぶいい機会になりました。

3D Terrain Generation

ソースコード

sketch.js(クリックすると見れます)
const scl = 30;
const w = 1800;
const h = 1500;
let cols, rows;
let terrain = [];
let flying = 0;
let cam;
let delta = 0.01;

function setup() {
  createCanvas(innerWidth, innerHeight, WEBGL);
  cols = w / scl;
  rows = h / scl;

  frameRate(20);

  // 地形データ用配列の初期化
  terrain = new Array(cols);
  for (let i = 0; i < cols; i++) {
    terrain[i] = new Array(rows).fill(0);
  }

  // カメラの設定(傾きあり)
  cam = createCamera();
  cam.tilt(-0.7);
}

function draw() {
  // 地形データ用配列に位置情報をセット
  flying -= 0.5;
  let yoff = flying;
  for (let y = 0; y < rows; y++) {
    let xoff = 0;
    for (let x = 0; x < cols; x++) {
      terrain[x][y] = map(noise(xoff, yoff), 0, 1, -100, 100);
      xoff += 0.2;
    }
    yoff += 0.2;
  }

  // 地形を描画
  background(0);
  stroke(255);
  noFill();

  rotateX(PI/3);
  translate(-w/2, -h/2);
  for (let y = 0; y < rows-1; y++) {
    beginShape(TRIANGLE_STRIP);
    for (let x = 0; x < cols; x++) {
      vertex(x*scl, y*scl, terrain[x][y]);
      vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
    }
    endShape();
  }

  // カメラの傾きを調整
  cam.tilt(delta);
  if (frameCount % 90 === 0) {
    delta *= -1;
  }
}
sketch.html(クリックすると見れます)
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>p5.js demo | Takashi Q. Hanamura Photograpy</title>
    <style>
        body {
            margin: 0;
            height: 0;
            overflow: hidden;
        }

        canvas {
            width: 100vw;
            height: 100vh;
            background: black;
        }
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
    <script src="sketch.js"></script>
</head>

<body>
</body>

</html>

動作画面

別ウィンドウで見る(Safariがおすすめ)

わかったこと

(1)作り方がわかってきた

動作させたいことを最小単位に分割すればわかりやすいし、作りやすいよね。

つまり、複雑な動きをさせるときも、一つ一つ分解して単純化すればわかりやすい。単純化したものを組み上げていくことで複雑な動き(描画)にすることができるはず。

作り方(考え方)がわかってきた。

会社員のときにシステム開発をしていたことと同じだね。おかげで基本的なことを思い出せた。昔のカンも戻ってきてると思う。

(2)ブラウザによる動作速度の違い

動作確認はSafari / Chrome / Firefoxでやりましたが、Safariが一番低負荷で高速に描画されるのが面白かった。

Chrome / FirefoxではMBPのファンが唸ってしまいます。

Heart Curve

ソースコード

sketch.js(クリックすると見れます)
let heartVector = [];
let angle = 0;

function setup() {
  createCanvas(innerWidth, innerHeight);
}

function draw() {
  background(0);
  translate(width/2, height/2);

  let r = 10;
  let x = r * 16 * pow(sin(angle), 3);
  let y = -r * (13 * cos(angle) - 5 * cos(2*angle) - 2 * cos(3*angle) - cos(4*angle));
  heartVector.push(createVector(x, y));
  angle += 0.05;

  noFill();
  stroke(255);
  strokeWeight(4);
  fill(150, 0, 100);
  beginShape();
  for (i of heartVector) {
    vertex(i.x, i.y);
  }
  endShape();

  if (angle >= TWO_PI) {
    noLoop();
    console.log("Finish");
  }
}

※sketch.htmlは3D Terrain Generationと同様

動作画面

ハートが描かれます。見れない場合はリロードしてくださいね。

別ウィンドウで見る(Safariがおすすめ)

わかったこと

(1)JSの基礎不足

3D Terrain Generationでも感じたけど、僕はJSの配列やデータ型について理解が不足しているね。

ループ処理もなんか複雑。

JavaScriptは年々進化していると聞きます。ループ処理も昔からの「for」のほか「[…Array]」 という書き方もあって、使い分けがわかりにくい。

そんなこんなで以下の記事を参考にしながら、Heart Curveでは「for 〜 of 〜」を使うことで想定した動作をさせることができた。

思わず「よっしゃ!」って叫んじゃったよ(笑)

今のところ、JSの基礎を知るには公式(?)の情報から入っていったほうがいいのかも、と理解しました。

(2)数学を思い出せてきてる

三角関数やベクトルの概念を少しずつ思い出せてきてる!

深まるのが楽しい

できないことができるようになる。
わからなかったことがわかる。

僕はここに楽しさを感じてしまうんだよね。

いずれ素敵な作品を魅せるためにコツコツと筋トレしているよ。

この記事を書いた人

花村貴史|Takashi Hanamura

◆Photographer|木漏れ日や水、空が魅せるきらきらが好き|写真を通じて「やさしい世界」を伝えてゆく ◆Software Engineer|Private: Go/C++/WebGL|Work: SAP/SAC

写真素材note発売中

継続課金マガジンで販売しています。ブログに載せるもOK、壁紙に設定するもOK、使い方は自由です。フリー素材も良いけれど、人と被りたくないという方に人気です。

人物写真|Photo Session

お話しながらのポートレイト撮影です。「今」そして「これから」のあなたにフォーカスして撮影します。SNSやサイト用のプロフィール写真に。

イベント写真|Photo Shooting

「友達と楽しんでいる」「セミナーで講演している」「パーティーを主催している」など、皆さんが大切な時間を過ごしている瞬間をスナップします。