p5.jsをWebページの背景にする

p5.jsをwebの背景にする方法

サンプル

クリックすると円を描きます

やり方

JavaScript

function setup() {
  let canvas = createCanvas(300, 300);
  // canvasの位置を指定
  canvas.position(0, 0);
  // canvasを背面に移動
  canvas.style('z-index','-1');
・・・
}

ソース

sketch.js

'use strict';

let obj = [];

function setup() {
  let canvas = createCanvas(300, 300);
  // canvasの位置を指定
  canvas.position(0, 0);
  // canvasを背面に移動
  canvas.style('z-index','-1');
  background(0);
  noFill();
  strokeWeight(5);
  colorMode(HSB);
}

function draw() {
  background(0);
  for(let i = 0; i < obj.length; i++) {
    obj[i].draw();
    if(obj[i].size > width * 2.5) {
      obj.splice(i, 1);
    }
  }
}

function mouseClicked() {
  obj.push(new Shape(mouseX, mouseY));
}

class Shape {
  x;
  y;
  size;
  color;
  speed;

  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.size = 10;
    this.color = color(random(0,360), 100, 100);
    this.speed = parseInt(random(1, 10));
  }

  draw() {
    stroke(this.color);
    ellipse(this.x, this.y, this.size, this.size);
    this.size += this.speed;
  }
}

main.html

<html lang="ja">
<head>
  <meta charset="utf-8" />
  <title>p5.jsを背景にする</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <script src="../../../../lib/p5.js"></script>
  <script src="./sketch.js"></script>
</head>
<body>
  <button onclick="alert('ボタンクリック');">ボタンサンプル</button>
  <input type='test' value='あいうえお'/>
</body>
</html>

参考

https://freyjasrm.com/2020/01/06/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AE%E8%83%8C%E6%99%AF%E7%94%BB%E5%83%8F%E3%81%ABp5-js%E3%82%92%E4%BD%BF%E3%81%86%E6%96%B9%E6%B3%95/

p5.js – マトリックスレイン公開

マトリックスのあれ、いったん完成ということにして、自作ツールの方に公開しました。
https://www.fukakuutsukushikiasia.com/%e8%87%aa%e4%bd%9c%e3%83%84%e3%83%bc%e3%83%ab

前回からの変更点は以下の通りです。
・先頭の文字を白に
・文字を半角カナ、数字、小文字のアルファベットをランダムで表示

ソースはこちら

'use strict';

let cols = [];
const MIN_FRAME = 1;
const MAX_FRAME = 10;
let frameIdx = MIN_FRAME;
let chars;

function setup() {
  createCanvas(windowWidth * 0.9, windowHeight * 0.9);
  background(0);
  noStroke();
  textAlign(LEFT);
  frameRate(13);
  init();

  const kana = "ヲァィゥェォャュョッアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン";
  const alphabet = "abcdefghijklmnopqrstuvwxyz"; //"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const number = "012345679";
  chars = (kana + alphabet + number).split("");
}

function init() {
  noLoop();
  cols = [];
  let x = 0;
  while( x < width ) {
    const size = parseInt(random(5, 25));
    cols.push(new Colmun(x, size));
    x += size;
  }
  background(0);
  loop();
}

function mouseClicked() {
  init();
}

function draw() {
  if( ++frameIdx > MAX_FRAME ) {
    frameIdx = MIN_FRAME;
  }

  cols.forEach(col => {
    col.draw();
  });
}

class Colmun {
  posX;
  posY;
  posYPre;
  char;
  charSize;
  speed = parseInt(random(1, 5));

  constructor(x, size) {
    this.posX = x;
    this.charSize = size;
    this.posY = 0;
    this.posYPre = -1 * size;
  }

  draw() {
    if(frameIdx % this.speed !== 0) {
      return;
    }
    if(this.posY >= height + this.charSize) {
      this.posY = 0;
    }
    // 半透明の黒い四角で文字を徐々に消す
    fill(0, 0, 0, 20);
    const adjustment = 0; //this.charSize / 2; 文字をCENTERにしたときは左にずらす
    rect(this.posX - adjustment, 0, this.charSize, height);

    /* 文字を描画 */
    textSize(this.charSize);

    // 前回の文字色をlimeで上書き
    fill('lime');
    text(this.char, this.posX, this.posYPre);
    // 先頭の文字は白
    this.char = chars[parseInt(random(0, chars.length - 1))];
    fill('white');
    text(this.char, this.posX, this.posY);

    this.posYPre = this.posY;
    this.posY += this.charSize;
  }
}

p5.js – マトリックスレイン習作02

マトリックスレイン習作01に修正を加えました。
・文字を半角に
・横幅いっぱいに文字を表示
・各列の文字のサイズと落ちるスピードをランダムに変更
・クリックで再描画

ソースはこちら

'use strict';

let cols = [];
const MIN_FRAME = 1;
const MAX_FRAME = 10;
let frameIdx = MIN_FRAME;

function setup() {
  createCanvas(300, 300);
  background(0);
  noStroke();
  textAlign(LEFT);
  frameRate(15);
  init();
}

function init() {
  noLoop();
  cols = [];
  let x = 0;
  while( x < width ) {
    const size = parseInt(random(5, 25));
    cols.push(new Colmun(x, size));
    x += size;
  }
  background(0);
  loop();
}

function mouseClicked() {
  init();
}

function draw() {
  if( ++frameIdx > MAX_FRAME ) {
    frameIdx = MIN_FRAME;
  }

  cols.forEach(col => {
    col.draw();
  });
}

class Colmun {
  posX;
  posY = 0;
  charSize = 15;
  chars = ['ナ', 'マ', 'ス', 'テ'];
  charIdx = 0;
  speed = parseInt(random(1, 5));

  constructor(x, size) {
    this.posX = x;
    this.charSize = size;
  }

  draw() {
    if(frameIdx % this.speed !== 0) {
      return;
    }
    if(this.posY >= height + this.charSize) {
      this.posY = 0;
    }
    // 半透明の黒い四角で文字のフェードアウトを実現
    fill(0, 0, 0, 50);
    rect(this.posX, 0, this.charSize, height);
    // 文字を描画
    fill('lime');
    textSize(this.charSize);
    text(this.chars[this.charIdx], this.posX, this.posY);
    this.posY += this.charSize;
    if(++this.charIdx >= this.chars.length) {
      this.charIdx = 0;
    }
  }
}

p5.js – マトリックスレイン習作01

マトリックスのオープニングみたいなもの(マトリックレインというらしい)を作ってみようと思います。まずは落ちていく文字から。
徐々にバージョンアップしていく予定です。

ソースはこちら

'use strict';

let posY = 0; // 文字の位置
let posX;
let fontSize = 15; // フォントサイズ/移動距離
let strings = ['ナ', 'マ', 'ス', 'テ'];
let stringIdx = 0;

function setup() {
  createCanvas(300, 300);
  background(0);
  noStroke();
  textSize(fontSize);
  textAlign(CENTER);
  frameRate(10);
  posX = width / 2;
}

function draw() {
  fill(0, 50);
  rect(0, 0, width, height);

  if(posY >= height + fontSize) {
    posY = 0;
  }
  fill('lime');
  text(strings[stringIdx], posX, posY);
  posY += fontSize;
  if(++stringIdx >= strings.length) {
    stringIdx = 0;
  }
}

p5.js – ネオン管

ネオン管のようなものが描けないかと思い、作ってみました。

マウスの上下で線の太さ、左右で鮮やかさ、クリックで色相が変わります。

それっぽくするには、もう少し工夫が必要ですかね。

ソースです。

'use strict';

let hue = 0;

function setup() {
  createCanvas(300, 300);
  noFill();
  background(0);
  colorMode(HSB);
}

function draw() {
  background(0);

  const maxWeight = Math.abs(height / 2 - mouseY) * 2;
  for( let i = maxWeight; i >= 1; i-- ) {
    let brightness = map(i, 1, maxWeight, 100, 50);
    let saturation = map(mouseX, 0, width, 0, 100);
    let alpha = map(i, 1, maxWeight, 1.0, 0.5);
    let weight = map(i, 1, maxWeight, 1, maxWeight);
    stroke(hue, saturation, brightness, alpha);
    strokeWeight(weight);
    line(0, height/2, width, height/2);
  }

}

function mouseClicked() {
  hue = random(0, 360);
}

p5.js – ランダム関数(random)とパーリンノイズ(noise)の比較

ランダム(random)関数とパーリンノイズ(noise)の比較です。

カラーモードはHSBで、どちらも S=90, B=90 固定です。

Hの値をランダムに変えてます。Hの値を算出するにあたり、XY軸の値をnoise関数に指定したいと考えてました。参考になりそうなものは無いかと調べていたらズバリなサイトがありました。

https://infosmith.biz/blog/it/p5js-noise

 

以下ソースです。

冗長なのが恥ずかしいのですが、晒します。

main.html

<html lang="ja">
<head>
    <script src="../../../../lib/p5.js"></script>
    <script src="./main.js"></script>
</head>
<body>
    <p>ランダム(random)関数</p>
    <div id="canvas1"></div>
    <br/>
    <p>パーリンノイズ(noise)関数</p>
    <div id="canvas2"></div>
</body>
</html>

main.js

'use strict';

const CANVAS_SIZE = 300;
const FRAME_RATE = 2;
const RECT_SIZE = 5;
const NOISE_STEP = 0.02;
const NOISE_MODERATOR = 500;

const randomRectColor = function(p) {
  p.setup = function() {
    p.createCanvas(CANVAS_SIZE, CANVAS_SIZE);
    p.colorMode(p.HSB);
    p.noStroke();
    p.frameRate(FRAME_RATE);
  };

  p.draw = function() {
    p.background(0);
    for (let x = 0; x < p.height; x += RECT_SIZE) {
      for (let y = 0; y < p.width; y += RECT_SIZE) {
        p.fill(p.random(0, 360), 90, 90);
        p.rect(x, y, RECT_SIZE, RECT_SIZE);
      }
    }
  };
};

const noiseRectColor = function(p) {
  let zoff = 0.0;

  p.setup = function() {
    p.createCanvas(CANVAS_SIZE, CANVAS_SIZE);
    p.colorMode(p.HSB);
    p.noStroke();
    p.frameRate(FRAME_RATE);
  };

  p.draw = function() {
    p.background(0);
    for (let x = 0; x < p.width; x += RECT_SIZE) {
      for (let y = 0; y < p.height; y += RECT_SIZE) {
        // noise関数に各セルのXとYを固定し、Zで色を変化させる
        // Hueは0~360だが、noise(0~1)に360を掛けても赤がでない
        let h = p.noise(x/NOISE_MODERATOR, y/NOISE_MODERATOR, zoff) * 450;
        p.fill(h, 90, 90);
        p.rect(x, y, RECT_SIZE, RECT_SIZE);
      }
    }
    zoff += NOISE_STEP;
  };
};

new p5(randomRectColor, "canvas1");
new p5(noiseRectColor, "canvas2");

p5.js – ハエのように動き回る図形

図形のカラーモードはHSBで、X軸が色相、Y軸が明るさになっています。

単なるランダムでXY軸を決めると飛び飛びになってしまうため、パーリンノイズを使っています。


以下ソースです。説明はコメントに記載してあります。

'use strict';

let xoff = 0.0;

function setup() {
    const canvasSize = 300;
    createCanvas(canvasSize, canvasSize);
    background(200);
    colorMode(HSB, 360, 100, 100);
}

function draw() {
  // x, y座標を算出
  const x = noise(xoff) * width * 1.2 - (width * 0.1);
  const y = noise(xoff+5) * height * 1.2 - (height * 0.1);
  xoff += 0.01;

  // X軸 : Hue = 0~360度
  let h = map(x, 0, width, 0, 360);
  // Y軸 : Brightness = 15~100 (0だと真っ黒なので少し明るくする)
  let b = map(y, 0, height, 15, 100);
  
  // 塗りつぶす色
  fill(h, 100, b);

  // 図形描画
  ellipse(x, y, 30, 30);
}

p5.js – 多角形/回転/拡大・縮小/透明度

以下ソースです。スクリプト内にコメントを追加しているので、それが解説になっています。

main.html

<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/p5@1.2.0/lib/p5.min.js"></script>
    <script src="./main.js"></script>
</head>
<body>
</body>
</html>

main.js

'use strict';

let corner = 3;             // 図形の角数
let stepCorner = 1;         // 角数の増減数
let radius = 0;             // 図形の半径
let stepSize = 3;           // 図形の拡大・縮小サイズ
let maxSize;                // 図形の最大サイズ(半径)
let hue = 0;                // カラーモードHSBのHue
const stepHue = 20;         // Hueの増加角度
let rotate = 0;             // 図形を何度傾けるか
const stepRotate = 3;       // 図形の回転角度

function setup() {
    const canvasSize = 300;
    createCanvas(canvasSize, canvasSize);
    // カラーモードをHSBにする
    colorMode(HSB);
    // 図形を表示領域の2倍の大きさまで描画する
    maxSize = width;
}

function draw() {
    background(0);
    setFillColor();
    drawPolygon();

    // 回転の角度 : 360度を超えたら0度にする
    rotate += stepRotate;
    if(rotate >= 360 ) {
        rotate = 0;
    }

    // 半径の増減
    radius += stepSize;
    if (radius > maxSize || radius < 0) {
        // 図形が最大値もしくは最小値になったら、拡大・縮小を反転させる
        stepSize *= -1;

        // 図形の拡大・縮小切り替わりのタイミングで色を変更する
        hue += stepHue;
        // HSBのHueは0~360度を繰り返す
        if (hue >= 360) { hue = 0; }

        // 図形の角を増減させる
        corner += stepCorner;
        // 図形は3角形~8角形を行ったり来たりする
        if( corner <= 3 || corner >= 8 ) {
            stepCorner *= -1;
        }
    }
}

function setFillColor() {
    // 透明度は半径に反比例:大きくなると薄くなる
    const alpha = map(radius, 0, maxSize, 1, 0);
    fill(hue, 100, 100, alpha);
}


function drawPolygon() {
    // 座標軸を一時保存
    push();
    // 初期状態だと(x=0, y=0)が左上なので中央に移動する
    translate(width/2, height/2);
    // 多角形の描画
    beginShape();
    for (let i = 0; i < corner; i++) {
        // 角度にrotateをプラスして回転させる
        let angle = map(i, 0, corner, 0, 360) + rotate;
        // 中心からの半径と角度でXY座標を求める
        let x = sin(radians(angle)) * radius;
        let y = cos(radians(angle)) * radius;
        // beginShape~endShapeの間にポイントすると線をつなげてくれる
        vertex(x, y);
    }
    endShape(CLOSE);
    // push で保存していた座標軸を元に戻す
    pop();
}

JavaScript埋め込みテスト

クリックすると線を描きます

以下のように直接HTMLを記述しています。完全に個人的なメモです。

<iframe src="/dannoura/ap01/blog/2021/01/14-001/main.html" frameborder="0" style="border:0; width: 350px; height: 350px;">
</iframe>