111 lines, no comments ยท 1,160 tokens, written in 25 seconds for $0.012


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