124 lines, no comments ยท 1,543 tokens, written in 13 seconds for $0.016


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