109 lines, no comments ยท 1,321 tokens, written in 11 seconds for $0.014


  1  let particles = [];
  2  const numParticles = 1200;
  3  let noiseScale = 0.008;
  4  let zOffset = 0;
  5  let hueShift = 0;
  6  
  7  function setup() {
  8    createCanvas(windowWidth, windowHeight);
  9    colorMode(HSB, 360, 100, 100, 100);
 10    background(10, 10, 15);
 11    for (let i = 0; i < numParticles; i++) {
 12      particles.push(new Particle());
 13    }
 14  }
 15  
 16  function draw() {
 17    background(10, 10, 15, 6);
 18  
 19    hueShift += 0.15;
 20  
 21    for (let p of particles) {
 22      p.follow();
 23      p.update();
 24      p.edges();
 25      p.show();
 26    }
 27  
 28    zOffset += 0.003;
 29  }
 30  
 31  class Particle {
 32    constructor() {
 33      this.pos = createVector(random(width), random(height));
 34      this.vel = createVector(0, 0);
 35      this.acc = createVector(0, 0);
 36      this.maxSpeed = random(2, 4);
 37      this.prevPos = this.pos.copy();
 38      this.hue = random(360);
 39      this.lifespan = random(200, 500);
 40      this.age = 0;
 41    }
 42  
 43    follow() {
 44      let angle = noise(
 45        this.pos.x * noiseScale,
 46        this.pos.y * noiseScale,
 47        zOffset
 48      ) * TWO_PI * 4;
 49      let force = p5.Vector.fromAngle(angle);
 50      force.setMag(0.15);
 51      this.acc.add(force);
 52    }
 53  
 54    update() {
 55      this.vel.add(this.acc);
 56      this.vel.limit(this.maxSpeed);
 57      this.pos.add(this.vel);
 58      this.acc.mult(0);
 59      this.age++;
 60      if (this.age > this.lifespan) {
 61        this.respawn();
 62      }
 63    }
 64  
 65    respawn() {
 66      this.pos = createVector(random(width), random(height));
 67      this.prevPos = this.pos.copy();
 68      this.age = 0;
 69      this.lifespan = random(200, 500);
 70      this.hue = (this.hue + random(30, 90)) % 360;
 71    }
 72  
 73    edges() {
 74      if (this.pos.x > width) {
 75        this.pos.x = 0;
 76        this.prevPos = this.pos.copy();
 77      }
 78      if (this.pos.x < 0) {
 79        this.pos.x = width;
 80        this.prevPos = this.pos.copy();
 81      }
 82      if (this.pos.y > height) {
 83        this.pos.y = 0;
 84        this.prevPos = this.pos.copy();
 85      }
 86      if (this.pos.y < 0) {
 87        this.pos.y = height;
 88        this.prevPos = this.pos.copy();
 89      }
 90    }
 91  
 92    show() {
 93      let displayHue = (this.hue + hueShift) % 360;
 94      stroke(displayHue, 70, 90, 50);
 95      strokeWeight(1.2);
 96      line(this.prevPos.x, this.prevPos.y, this.pos.x, this.pos.y);
 97      this.prevPos = this.pos.copy();
 98    }
 99  }
100  
101  function windowResized() {
102    resizeCanvas(windowWidth, windowHeight);
103    background(10, 10, 15);
104  }
105  
106  function mousePressed() {
107    noiseScale = random(0.003, 0.015);
108  }
109