111 lines, no comments ยท 1,169 tokens, written in 22 seconds for $0.012


  1  let particles = [];
  2  const numParticles = 1800;
  3  const noiseScale = 0.004;
  4  let zOff = 0;
  5  
  6  function setup() {
  7    createCanvas(windowWidth, windowHeight);
  8    colorMode(HSB, 360, 100, 100, 100);
  9    background(240, 30, 5);
 10    
 11    for (let i = 0; i < numParticles; i++) {
 12      particles.push(new Particle());
 13    }
 14  }
 15  
 16  function draw() {
 17    blendMode(BLEND);
 18    noStroke();
 19    fill(240, 30, 5, 6);
 20    rect(0, 0, width, height);
 21    
 22    blendMode(ADD);
 23    
 24    for (let p of particles) {
 25      p.follow();
 26      p.update();
 27      p.show();
 28      p.edges();
 29    }
 30    
 31    zOff += 0.002;
 32  }
 33  
 34  class Particle {
 35    constructor() {
 36      this.pos = createVector(random(width), random(height));
 37      this.vel = createVector(0, 0);
 38      this.acc = createVector(0, 0);
 39      this.maxSpeed = random(1.5, 3.5);
 40      this.prevPos = this.pos.copy();
 41      this.hueOffset = random(-30, 30);
 42    }
 43  
 44    follow() {
 45      let angle = noise(this.pos.x * noiseScale, this.pos.y * noiseScale, zOff) * TWO_PI * 4;
 46      let force = p5.Vector.fromAngle(angle);
 47      force.mult(0.3);
 48      this.applyForce(force);
 49      
 50      if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
 51        let mouse = createVector(mouseX, mouseY);
 52        let dir = p5.Vector.sub(this.pos, mouse);
 53        let d = dir.mag();
 54        if (d < 150) {
 55          dir.normalize();
 56          let swirl = createVector(-dir.y, dir.x);
 57          swirl.mult(map(d, 0, 150, 2, 0));
 58          this.applyForce(swirl);
 59        }
 60      }
 61    }
 62  
 63    applyForce(force) {
 64      this.acc.add(force);
 65    }
 66  
 67    update() {
 68      this.vel.add(this.acc);
 69      this.vel.limit(this.maxSpeed);
 70      this.pos.add(this.vel);
 71      this.acc.mult(0);
 72    }
 73  
 74    show() {
 75      let baseHue = (frameCount * 0.2 + (this.pos.x + this.pos.y) * 0.05 + this.hueOffset) % 360;
 76      if (baseHue < 0) baseHue += 360;
 77      
 78      stroke(baseHue, 80, 90, 20);
 79      strokeWeight(1.5);
 80      line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y);
 81      this.updatePrev();
 82    }
 83  
 84    updatePrev() {
 85      this.prevPos.x = this.pos.x;
 86      this.prevPos.y = this.pos.y;
 87    }
 88  
 89    edges() {
 90      if (this.pos.x > width) { this.pos.x = 0; this.updatePrev(); }
 91      if (this.pos.x < 0) { this.pos.x = width; this.updatePrev(); }
 92      if (this.pos.y > height) { this.pos.y = 0; this.updatePrev(); }
 93      if (this.pos.y < 0) { this.pos.y = height; this.updatePrev(); }
 94    }
 95  }
 96  
 97  function windowResized() {
 98    resizeCanvas(windowWidth, windowHeight);
 99    blendMode(BLEND);
100    background(240, 30, 5);
101  }
102  
103  function mousePressed() {
104    noiseSeed(millis());
105    blendMode(BLEND);
106    background(240, 30, 5);
107    for (let p of particles) {
108      p.pos.set(random(width), random(height));
109      p.updatePrev();
110    }
111  }