74 lines, 2 of them comments ยท 1,058 tokens, written in 14 seconds for $0.0068


 1  let particles = [];
 2  const NUM = 120;
 3  
 4  function setup() {
 5    createCanvas(windowWidth, windowHeight);
 6    colorMode(HSB, 360, 100, 100, 100);
 7    for (let i = 0; i < NUM; i++) {
 8      particles.push(new Particle());
 9    }
10    background(230, 40, 8);
11  }
12  
13  function draw() {
14    background(230, 40, 8, 8);
15    for (let p of particles) {
16      p.update();
17      p.show();
18    }
19  }
20  
21  class Particle {
22    constructor() {
23      this.reset(true);
24    }
25  
26    reset(initial = false) {
27      this.x = random(width);
28      this.y = initial ? random(height) : random(-50, -10);
29      this.vx = random(-0.4, 0.4);
30      this.vy = random(0.3, 1.2);
31      this.size = random(2, 7);
32      this.hue = random(140, 220);
33      this.life = random(80, 200);
34      this.maxLife = this.life;
35    }
36  
37    update() {
38      let angle = noise(this.x * 0.003, this.y * 0.003, frameCount * 0.004) * TAU * 2;
39      this.vx += cos(angle) * 0.05;
40      this.vy += sin(angle) * 0.03;
41  
42      // subtle mouse attraction
43      let dx = mouseX - this.x;
44      let dy = mouseY - this.y;
45      let d = max(dist(mouseX, mouseY, this.x, this.y), 40);
46      this.vx += dx / d * 0.02;
47      this.vy += dy / d * 0.02;
48  
49      this.vx *= 0.98;
50      this.vy *= 0.98;
51      this.x += this.vx;
52      this.y += this.vy;
53      this.life--;
54  
55      if (this.life <= 0 || this.y > height + 20 || this.x < -20 || this.x > width + 20) {
56        this.reset();
57      }
58    }
59  
60    show() {
61      let alpha = map(this.life, 0, this.maxLife, 0, 70);
62      noStroke();
63      fill(this.hue, 70, 100, alpha);
64      circle(this.x, this.y, this.size);
65      // soft glow
66      fill(this.hue, 50, 100, alpha * 0.25);
67      circle(this.x, this.y, this.size * 3);
68    }
69  }
70  
71  function windowResized() {
72    resizeCanvas(windowWidth, windowHeight);
73    background(230, 40, 8);
74  }