LoginSignup
2
お題は不問!Qiita Engineer Festa 2023で記事投稿!

ページロード時のアニメーション、Perlin Noise で Flow Fields

Posted at

この記事の概要

ページロード時のアニメーションで何か格好良いものが作れないかなと模索していました。
そこまで凝らずに作れたので、備忘録を兼ねて記事にします。

完成品

リロードする度に模様が変わっています。
有機的で複雑なラインを描いているので、通常の CSS アニメーションよりもリッチに見える気がします。

この記事での環境

依存関係 バージョン
p5 1.6.0
typescript 5.0.2
vite 4.3.9

コードの全体像

import p5 from "p5";

const sketch = (p: p5) => {
  let particles: p5.Vector[] = [];
  const numberOfPoints = 2000;
  const noiseScale = 0.01;

  p.setup = () => {
    p.createCanvas(p.windowWidth, p.windowHeight);
    for (let i = 0; i < numberOfPoints; i++) {
      particles.push(p.createVector(p.random(p.width), p.random(p.height)));
    }
    p.stroke(200);
  };

  p.draw = () => {
    p.background(255, 1);
    for (let i = 0; i < numberOfPoints; i++) {
      let particle = particles[i];
      p.point(particle.x, particle.y);
      let noise = p.noise(particle.x * noiseScale, particle.y * noiseScale);
      particle.x -= 5 * p.cos(noise * p.TAU);
      particle.y -= 5 * p.sin(noise * p.TAU);
    }
  };
};

const containerElement = document.getElementById("p5-container");

if (containerElement !== null) {
  new p5(sketch, containerElement);
} else {
  console.error("Element with ID 'p5-container' not found");
}

インスタンスモード

p5.js はデフォルトではすべての関数がウィンドウオブジェクトにバインドされています。
今回は試しに作っているだけなので良いですが、制作物の規模が大きくなると辛くなると思います。

というわけでインスタンスモードを使用しています。

setup

起動時に 1 度だけ呼び出されます。
キャンバスの作成と、それぞれのパーティクルの初期位置を指定しています。

draw

setup の後に呼び出されて、その後はフレームを描画し続けます。

background(255, 1) では、白い背景を透明度 1% で描き続けることで、パーティクルが尾を引いているように見せています。

noise でランダム性を加えたあとに、 sin と cos で x 方向、 y 方向それぞれに揺らぎを与えながら移動させています。

最後に

リファレンスはこちらです。


最後まで読んでくださってありがとうございます!
Twitterでも情報を発信しているので、良かったらフォローお願いします!

Devトークでお話してくださる方も募集中です!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2