84 lines, 5 of them comments ยท 903 tokens, written in 13 seconds for $0.024


 1  let particles = [];
 2  
 3  function setup() {
 4    createCanvas(windowWidth, windowHeight);
 5    colorMode(HSB, 360, 100, 100, 100);
 6    background(0);
 7  }
 8  
 9  function draw() {
10    background(0, 0, 0, 5);
11    
12    // Add new particles near mouse
13    if (frameCount % 2 === 0) {
14      for (let i = 0; i < 3; i++) {
15        particles.push(new Particle(mouseX + random(-20, 20), mouseY + random(-20, 20)));
16      }
17    }
18    
19    // Update and display particles
20    for (let i = particles.length - 1; i >= 0; i--) {
21      particles[i].update();
22      particles[i].display();
23      
24      if (particles[i].isDead()) {
25        particles.splice(i, 1);
26      }
27    }
28    
29    // Limit particles
30    if (particles.length > 500) {
31      particles.splice(0, particles.length - 500);
32    }
33  }
34  
35  function mousePressed() {
36    for (let i = 0; i < 50; i++) {
37      let p = new Particle(mouseX, mouseY);
38      p.vel.mult(3);
39      particles.push(p);
40    }
41  }
42  
43  function windowResized() {
44    resizeCanvas(windowWidth, windowHeight);
45    background(0);
46  }
47  
48  class Particle {
49    constructor(x, y) {
50      this.pos = createVector(x, y);
51      this.vel = p5.Vector.random2D().mult(random(1, 3));
52      this.acc = createVector(0, 0);
53      this.life = 255;
54      this.decay = random(1, 4);
55      this.size = random(2, 8);
56      this.hue = (frameCount * 0.5 + random(30)) % 360;
57    }
58    
59    update() {
60      // Add slight noise-based movement
61      let angle = noise(this.pos.x * 0.005, this.pos.y * 0.005, frameCount * 0.01) * TWO_PI * 2;
62      this.acc = p5.Vector.fromAngle(angle).mult(0.1);
63      
64      this.vel.add(this.acc);
65      this.vel.limit(4);
66      this.pos.add(this.vel);
67      this.life -= this.decay;
68    }
69    
70    display() {
71      noStroke();
72      let alpha = map(this.life, 0, 255, 0, 80);
73      fill(this.hue, 80, 100, alpha);
74      ellipse(this.pos.x, this.pos.y, this.size);
75      
76      // Inner glow
77      fill(this.hue, 30, 100, alpha * 0.5);
78      ellipse(this.pos.x, this.pos.y, this.size * 0.5);
79    }
80    
81    isDead() {
82      return this.life <= 0;
83    }
84  }