【p5.js】箱を画面に敷き詰める

2023/05/18に公開

目的

クリエイティブコーディングに興味が出てきたので遊んでみました。

まずはp5.jsに慣れようということでシンプルな箱を画面に敷き詰めたそれっぽい絵を書いてみます。

コードはTypeScript(4.8.4)です。

ゴールイメージ

2次元平面に箱を1つ書くための関数を用意する

1つのrect関数と2つのquad関数を利用して正面が赤、上面が緑、側面が青の箱を書きました。

  const sideLength = 30;
  const XdepthLength = 15;
  const YdepthLength = 10;

  function box(x: number, y: number) {
    // 正面
    p.push();
    p.fill('red');
    p.rect(x, y, sideLength, sideLength);
    p.pop();

    // 側面
    p.push();
    p.fill('blue');
    p.quad(
      x + sideLength,
      y,
      x + sideLength + XdepthLength,
      y - YdepthLength,
      x + sideLength + XdepthLength,
      y + sideLength - YdepthLength,
      x + sideLength,
      y + sideLength
    );
    p.pop();

    // 緑
    p.push();
    p.fill('green');
    p.quad(
      x + XdepthLength,
      y - YdepthLength,
      x + sideLength + XdepthLength,
      y - YdepthLength,
      x + sideLength,
      y,
      x,
      y
    );
    p.pop();
  }

上記の関数をdraw関数の中から呼んであげると下記のような箱が描画されました。

箱

画面に敷き詰める

上記で作成したbox関数をループ処理から呼ぶことで画面に敷き詰めました。
アニメーション表現をするわけではないのでnoLoop関数setupの中で実行しています。
ループ処理の条件式はスマートにできそうですが今回は脳筋で17×17としています。

import p5 from 'p5';

const sketch = (p: p5) => {
  const canvasWidth = 400;
  const canvasHeight = 400;
  const sideLength = 30;
  const XdepthLength = 15;
  const YdepthLength = 10;

  p.setup = () => {
    p.createCanvas(canvasWidth, canvasHeight);
    p.background(100);
    p.noLoop();
  };

  p.draw = () => {
    const startX = 0;
    const startY = p.height + 100;

    for (let i = 0; i < 17; i++) {
      for (let j = 0; j < 17; j++) {
        const x = startX + (sideLength + XdepthLength) * i - sideLength * j;
        const y = startY - YdepthLength * i - sideLength * j;

        box(x, y);
      }
    }
  };

  function box(x: number, y: number) {
    p.push();
    p.fill('red');
    p.rect(x, y, sideLength, sideLength);
    p.pop();

    p.push();
    p.fill('blue');
    p.quad(
      x + sideLength,
      y,
      x + sideLength + XdepthLength,
      y - YdepthLength,
      x + sideLength + XdepthLength,
      y + sideLength - YdepthLength,
      x + sideLength,
      y + sideLength
    );
    p.pop();

    p.push();
    p.fill('green');
    p.quad(
      x + XdepthLength,
      y - YdepthLength,
      x + sideLength + XdepthLength,
      y - YdepthLength,
      x + sideLength,
      y,
      x,
      y
    );
    p.pop();
  }
};

new p5(sketch);

ゴールイメージ

成果物はシンプルですが書いていて楽しかったです。
今後は色をアニメーションチックに変化させたりなど試してみようと思います。

コードはstackblitzに置いています。

Discussion