88 lines, no comments ยท 2,396 tokens, written in 17 seconds for $0.0091


 1  let particles = [];
 2  const numParticles = 800;
 3  let noiseScale = 0.004;
 4  let noiseZ = 0;
 5  
 6  function setup() {
 7    createCanvas(windowWidth, windowHeight);
 8    colorMode(HSB, 360, 100, 100, 100);
 9    background(230, 40, 6);
10    for (let i = 0; i < numParticles; i++) {
11      particles.push(new Particle());
12    }
13  }
14  
15  function draw() {
16    background(230, 40, 6, 10);
17  
18    noiseZ += 0.003;
19    let mousePos = createVector(mouseX, mouseY);
20  
21    for (let p of particles) {
22      p.update(mousePos);
23      p.display();
24    }
25  }
26  
27  class Particle {
28    constructor() {
29      this.reset();
30    }
31  
32    reset() {
33      this.pos = createVector(random(width), random(height));
34      this.prevPos = this.pos.copy();
35      this.vel = createVector(0, 0);
36      this.acc = createVector(0, 0);
37      this.maxSpeed = random(1.8, 3.8);
38      this.hueOffset = random(0, 80);
39      this.weight = random(1, 2.5);
40    }
41  
42    update(mousePos) {
43      this.prevPos = this.pos.copy();
44  
45      let n = noise(this.pos.x * noiseScale, this.pos.y * noiseScale, noiseZ);
46      let angle = n * TWO_PI * 3;
47      let flow = p5.Vector.fromAngle(angle).mult(0.6);
48  
49      this.acc.add(flow);
50  
51      let d = dist(this.pos.x, this.pos.y, mousePos.x, mousePos.y);
52      if (mouseIsPressed && d < 200) {
53        let force = p5.Vector.sub(this.pos, mousePos);
54        force.setMag(map(d, 0, 200, 4, 0));
55        this.acc.add(force);
56      } else if (d < 120) {
57        let force = p5.Vector.sub(this.pos, mousePos);
58        force.setMag(map(d, 0, 120, 1.8, 0));
59        this.acc.add(force);
60      }
61  
62      this.vel.add(this.acc);
63      this.vel.limit(this.maxSpeed);
64      this.pos.add(this.vel);
65      this.acc.mult(0);
66  
67      if (this.pos.x < 0 || this.pos.x > width || this.pos.y < 0 || this.pos.y > height) {
68        this.pos.set(random(width), random(height));
69        this.prevPos = this.pos.copy();
70      }
71    }
72  
73    display() {
74      let speed = this.vel.mag();
75      let h = (frameCount * 0.3 + this.pos.x * 0.08 + this.pos.y * 0.08 + this.hueOffset) % 360;
76      let b = map(speed, 0, this.maxSpeed, 70, 100);
77      let alpha = map(speed, 0, this.maxSpeed, 35, 90);
78  
79      stroke(h, 85, b, alpha);
80      strokeWeight(this.weight);
81      line(this.prevPos.x, this.prevPos.y, this.pos.x, this.pos.y);
82    }
83  }
84  
85  function windowResized() {
86    resizeCanvas(windowWidth, windowHeight);
87    background(230, 40, 6);
88  }