84 lines, no comments ยท 1,045 tokens, written in 14 seconds for $0.027


 1  let particles = [];
 2  let hueOffset = 0;
 3  
 4  function setup() {
 5    createCanvas(windowWidth, windowHeight);
 6    colorMode(HSB, 360, 100, 100, 100);
 7    background(0, 0, 10);
 8  }
 9  
10  function draw() {
11    background(0, 0, 10, 5);
12    hueOffset += 0.5;
13    
14    if (mouseIsPressed || frameCount % 3 === 0) {
15      let x = mouseIsPressed ? mouseX : random(width);
16      let y = mouseIsPressed ? mouseY : random(height);
17      for (let i = 0; i < 5; i++) {
18        particles.push(new Particle(x, y));
19      }
20    }
21    
22    for (let i = particles.length - 1; i >= 0; i--) {
23      particles[i].update();
24      particles[i].display();
25      if (particles[i].isDead()) {
26        particles.splice(i, 1);
27      }
28    }
29    
30    if (particles.length > 2000) {
31      particles.splice(0, 500);
32    }
33  }
34  
35  class Particle {
36    constructor(x, y) {
37      this.pos = createVector(x, y);
38      this.angle = random(TWO_PI);
39      this.speed = random(1, 4);
40      this.vel = createVector(cos(this.angle) * this.speed, sin(this.angle) * this.speed);
41      this.acc = createVector(0, 0);
42      this.life = 255;
43      this.decay = random(1, 4);
44      this.size = random(3, 12);
45      this.hue = (hueOffset + random(60)) % 360;
46      this.sat = random(60, 100);
47      this.rotSpeed = random(-0.1, 0.1);
48      this.noiseOff = random(1000);
49    }
50    
51    update() {
52      let n = noise(this.pos.x * 0.005, this.pos.y * 0.005, frameCount * 0.01 + this.noiseOff);
53      let noiseAngle = n * TWO_PI * 4;
54      this.acc = createVector(cos(noiseAngle), sin(noiseAngle));
55      this.acc.mult(0.2);
56      this.vel.add(this.acc);
57      this.vel.limit(5);
58      this.pos.add(this.vel);
59      this.life -= this.decay;
60      this.angle += this.rotSpeed;
61    }
62    
63    display() {
64      push();
65      translate(this.pos.x, this.pos.y);
66      rotate(this.angle);
67      noStroke();
68      let alpha = map(this.life, 0, 255, 0, 100);
69      fill(this.hue, this.sat, 90, alpha);
70      ellipse(0, 0, this.size, this.size * 1.5);
71      fill((this.hue + 30) % 360, this.sat, 100, alpha * 0.5);
72      ellipse(0, 0, this.size * 0.5, this.size * 0.75);
73      pop();
74    }
75    
76    isDead() {
77      return this.life <= 0 || this.pos.x < -50 || this.pos.x > width + 50 || this.pos.y < -50 || this.pos.y > height + 50;
78    }
79  }
80  
81  function windowResized() {
82    resizeCanvas(windowWidth, windowHeight);
83    background(0, 0, 10);
84  }