93 lines, no comments ยท 1,113 tokens, written in 17 seconds for $0.011


 1  let particles = [];
 2  let paused = false;
 3  let time = 0;
 4  const COUNT = 1000;
 5  
 6  function setup() {
 7    createCanvas(windowWidth, windowHeight);
 8    pixelDensity(min(displayDensity(), 2));
 9    colorMode(HSB, 360, 100, 100, 1);
10    resetSketch();
11  }
12  
13  function resetSketch() {
14    background(230, 65, 5);
15    noiseSeed(floor(random(100000)));
16    time = 0;
17    particles = Array.from({ length: COUNT }, () => ({
18      x: random(width),
19      y: random(height),
20      vx: 0,
21      vy: 0,
22      speed: random(1.1, 2.8),
23      hue: random(165, 285)
24    }));
25  }
26  
27  function draw() {
28    if (paused) return;
29  
30    noStroke();
31    fill(230, 65, 5, 0.065);
32    rect(0, 0, width, height);
33  
34    const dt = min(deltaTime / 16.667, 2);
35    time += 0.002 * dt;
36    strokeWeight(1.15);
37  
38    for (const p of particles) {
39      const oldX = p.x;
40      const oldY = p.y;
41      const angle = noise(p.x * 0.0025, p.y * 0.0025, time) * TWO_PI * 3;
42      let fx = cos(angle) * p.speed;
43      let fy = sin(angle) * p.speed;
44  
45      if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
46        const dx = mouseX - p.x;
47        const dy = mouseY - p.y;
48        const distance = sqrt(dx * dx + dy * dy);
49        if (distance > 1 && distance < 210) {
50          const influence = (1 - distance / 210) * 5;
51          if (mouseIsPressed) {
52            fx += dx / distance * influence;
53            fy += dy / distance * influence;
54          } else {
55            fx += -dy / distance * influence;
56            fy += dx / distance * influence;
57          }
58        }
59      }
60  
61      p.vx = lerp(p.vx, fx, 0.09 * dt);
62      p.vy = lerp(p.vy, fy, 0.09 * dt);
63      p.x += p.vx * dt;
64      p.y += p.vy * dt;
65  
66      let wrapped = false;
67      if (p.x < 0) { p.x = width; wrapped = true; }
68      if (p.x > width) { p.x = 0; wrapped = true; }
69      if (p.y < 0) { p.y = height; wrapped = true; }
70      if (p.y > height) { p.y = 0; wrapped = true; }
71  
72      if (!wrapped) {
73        const hue = (p.hue + 28 * sin(time + p.y * 0.003) + 360) % 360;
74        stroke(hue, 65, 100, 0.48);
75        line(oldX, oldY, p.x, p.y);
76      }
77    }
78  }
79  
80  function keyPressed() {
81    if (key === ' ') {
82      paused = !paused;
83      return false;
84    }
85    if (key === 'r' || key === 'R') resetSketch();
86    if (key === 's' || key === 'S') saveCanvas('luminous-currents', 'png');
87  }
88  
89  function windowResized() {
90    resizeCanvas(windowWidth, windowHeight);
91    resetSketch();
92  }
93