File size: 1,845 Bytes
33d188f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const densityInput = document.getElementById("density");
const curlInput = document.getElementById("curl");
const speedInput = document.getElementById("speed");
const regenBtn = document.getElementById("regen");

function resize() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}
window.addEventListener("resize", resize);
resize();

let seed = Math.random() * 1000;
let particles = [];

function randNoise(x, y) {
  return Math.sin(x * 0.002 + seed) +
         Math.cos(y * 0.002 + seed);
}

function createParticles() {
  particles = [];
  for (let i = 0; i < densityInput.value; i++) {
    particles.push({
      x: Math.random() * canvas.width,
      y: Math.random() * canvas.height,
      life: Math.random() * 200
    });
  }
}

function flowAngle(x, y) {
  return randNoise(x, y) * curlInput.value;
}

function draw() {
  ctx.fillStyle = "rgba(0, 0, 0, 0.08)";
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  for (const p of particles) {
    const angle = flowAngle(p.x, p.y);
    const vx = Math.cos(angle) * speedInput.value;
    const vy = Math.sin(angle) * speedInput.value;

    ctx.strokeStyle = `hsla(${(p.life * 3) % 360}, 100%, 60%, 0.8)`;
    ctx.beginPath();
    ctx.moveTo(p.x, p.y);

    p.x += vx;
    p.y += vy;

    ctx.lineTo(p.x, p.y);
    ctx.stroke();

    p.life--;

    if (
      p.life <= 0 ||
      p.x < 0 || p.x > canvas.width ||
      p.y < 0 || p.y > canvas.height
    ) {
      p.x = Math.random() * canvas.width;
      p.y = Math.random() * canvas.height;
      p.life = 200;
    }
  }

  requestAnimationFrame(draw);
}

regenBtn.onclick = () => {
  seed = Math.random() * 1000;
  createParticles();
  ctx.clearRect(0, 0, canvas.width, canvas.height);
};

createParticles();
draw();