79 lines, 6 of them comments ยท 765 tokens, written in 4 seconds for $0.0030


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