94 lines, no comments ยท 1,382 tokens, written in 10 seconds for $0.0053


 1  let particles = [];
 2  const NUM_PARTICLES = 600;
 3  let noiseScale = 0.005;
 4  let noiseZ = 0;
 5  let baseHue = 180;
 6  
 7  function setup() {
 8    createCanvas(windowWidth, windowHeight);
 9    colorMode(HSB, 360, 100, 100, 100);
10    background(0);
11    for (let i = 0; i < NUM_PARTICLES; i++) {
12      particles.push(new Particle());
13    }
14  }
15  
16  function draw() {
17    background(0, 0, 0, 8);
18    noiseZ += 0.002;
19    baseHue = (baseHue + 0.2) % 360;
20  
21    for (let i = 0; i < particles.length; i++) {
22      particles[i].update();
23      particles[i].display();
24      particles[i].checkEdges();
25    }
26  }
27  
28  class Particle {
29    constructor() {
30      this.pos = createVector(random(width), random(height));
31      this.prevPos = this.pos.copy();
32      this.vel = createVector(0, 0);
33      this.acc = createVector(0, 0);
34      this.maxSpeed = random(2, 4.5);
35      this.hueOffset = random(-40, 40);
36      this.weight = random(1, 2.5);
37      this.lifespan = random(50, 150);
38      this.age = 0;
39    }
40  
41    update() {
42      this.prevPos = this.pos.copy();
43      let angle = noise(this.pos.x * noiseScale, this.pos.y * noiseScale, noiseZ) * TWO_PI * 4;
44      let force = p5.Vector.fromAngle(angle).mult(0.5);
45  
46      if (mouseIsPressed || (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height)) {
47        let mouse = createVector(mouseX, mouseY);
48        let dir = p5.Vector.sub(this.pos, mouse);
49        let dist = dir.mag();
50        if (dist < 200 && dist > 1) {
51          dir.normalize();
52          let pushForce = map(dist, 0, 200, mouseIsPressed ? -3 : 2, 0);
53          force.add(dir.mult(pushForce));
54        }
55      }
56  
57      this.acc.add(force);
58      this.vel.add(this.acc);
59      this.vel.limit(this.maxSpeed);
60      this.pos.add(this.vel);
61      this.acc.mult(0);
62      this.age++;
63  
64      if (this.age > this.lifespan) {
65        this.reset();
66      }
67    }
68  
69    display() {
70      let currentHue = (baseHue + this.hueOffset + 360) % 360;
71      stroke(currentHue, 80, 100, 60);
72      strokeWeight(this.weight);
73      line(this.prevPos.x, this.prevPos.y, this.pos.x, this.pos.y);
74    }
75  
76    checkEdges() {
77      if (this.pos.x < 0 || this.pos.x > width || this.pos.y < 0 || this.pos.y > height) {
78        this.reset();
79      }
80    }
81  
82    reset() {
83      this.pos = createVector(random(width), random(height));
84      this.prevPos = this.pos.copy();
85      this.vel.mult(0);
86      this.age = 0;
87      this.lifespan = random(100, 250);
88    }
89  }
90  
91  function windowResized() {
92    resizeCanvas(windowWidth, windowHeight);
93    background(0);
94  }