72 lines, 18 of them comments ยท 1,150 tokens, written in 32 seconds for $0.0035


 1  // Array to hold all active particles
 2    let particles = [];
 3  
 4    function setup() {
 5      // Create a canvas that fills the window
 6      createCanvas(windowWidth, windowHeight);
 7      
 8      // Use HSB color mode for rainbow effects
 9      // Hue: 0-360, Saturation: 0-100, Brightness: 0-100, Alpha: 0-1
10      colorMode(HSB, 360, 100, 100, 1);
11      noStroke();
12    }
13  
14    function draw() {
15      // Draw a semi-transparent background to create a "trail" effect
16      background(0, 0, 10, 0.2);
17  
18      // Add new particles at the mouse position
19      // We add 5 particles per frame for a denser stream
20      for (let i = 0; i < 5; i++) {
21        particles.push(new Particle(mouseX, mouseY));
22      }
23  
24      // Loop through the array backwards so we can remove items safely
25      for (let i = particles.length - 1; i >= 0; i--) {
26        let p = particles[i];
27        p.update();
28        p.show();
29  
30        // Remove particles that are dead (fully transparent)
31        if (p.isDead()) {
32          particles.splice(i, 1);
33        }
34      }
35    }
36  
37    // Handle window resizing
38    function windowResized() {
39      resizeCanvas(windowWidth, windowHeight);
40    }
41  
42    // --- Particle Class ---
43    class Particle {
44      constructor(x, y) {
45        this.pos = createVector(x, y);
46        
47        // Give random velocity in all directions
48        this.vel = p5.Vector.random2D();
49        this.vel.mult(random(0.5, 3)); // Set speed
50        
51        this.size = random(5, 15);
52        this.hue = random(0, 360); // Random color
53        this.life = 1.0; // Life starts at 100% (1.0)
54        this.decay = random(0.01, 0.03); // How fast it fades
55      }
56  
57      update() {
58        this.pos.add(this.vel);
59        this.life -= this.decay;
60        this.size *= 0.96; // Shrink slightly every frame
61      }
62  
63      show() {
64        // Set color based on current life (alpha)
65        fill(this.hue, 80, 100, this.life);
66        ellipse(this.pos.x, this.pos.y, this.size);
67      }
68  
69      isDead() {
70        return this.life <= 0 || this.size < 0.5;
71      }
72    }