144 lines, no comments · 1,404 tokens, written in 8 seconds for $0.043


  1  let particles = [];
  2  const COUNT = 650;
  3  
  4  function setup() {
  5    createCanvas(windowWidth, windowHeight);
  6    colorMode(HSB, 360, 100, 100, 100);
  7    background(235, 35, 5);
  8    for (let i = 0; i < COUNT; i++) {
  9      particles.push(new Particle());
 10    }
 11  }
 12  
 13  function draw() {
 14    background(235, 35, 5, 12);
 15  
 16    let t = frameCount * 0.004;
 17    let cx = width / 2;
 18    let cy = height / 2;
 19  
 20    push();
 21    noFill();
 22    strokeWeight(1);
 23    for (let i = 0; i < 5; i++) {
 24      let r = 35 + i * 24 + sin(t * 2 + i) * 7;
 25      stroke((190 + i * 25 + frameCount * 0.3) % 360, 75, 90, 13);
 26      circle(cx, cy, r * 2);
 27    }
 28    pop();
 29  
 30    for (let p of particles) {
 31      p.update(t);
 32      p.display();
 33    }
 34  
 35    noStroke();
 36    for (let i = 5; i > 0; i--) {
 37      fill((190 + frameCount * 0.5) % 360, 80, 100, 5);
 38      circle(cx, cy, i * 19);
 39    }
 40    fill(190, 30, 100, 90);
 41    circle(cx, cy, 8);
 42  
 43    fill(0, 0, 100, 45);
 44    textAlign(CENTER);
 45    textSize(12);
 46    text('MOVE TO DISTORT  •  CLICK TO BURST', width / 2, height - 25);
 47  }
 48  
 49  class Particle {
 50    constructor() {
 51      this.reset();
 52      this.angle = random(TWO_PI);
 53      this.radius = random(30, max(width, height) * 0.65);
 54    }
 55  
 56    reset() {
 57      this.angle = random(TWO_PI);
 58      this.radius = random(10, 60);
 59      this.speed = random(0.003, 0.014);
 60      this.outward = random(0.15, 0.7);
 61      this.size = random(0.8, 3.2);
 62      this.hue = random(165, 310);
 63      this.offset = random(1000);
 64      this.x = width / 2;
 65      this.y = height / 2;
 66      this.px = this.x;
 67      this.py = this.y;
 68    }
 69  
 70    update(t) {
 71      this.px = this.x;
 72      this.py = this.y;
 73  
 74      this.angle += this.speed * (1 + 70 / (this.radius + 30));
 75      this.radius += this.outward;
 76  
 77      let wave = sin(this.angle * 4 + t * 2 + this.offset) * 18;
 78      let r = this.radius + wave;
 79  
 80      let stretch = min(width, height) * 0.1;
 81      this.x = width / 2 + cos(this.angle) * r * 1.25;
 82      this.y = height / 2 + sin(this.angle) * r * 0.75 + sin(this.angle * 2 + t) * stretch * 0.2;
 83  
 84      if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {
 85        let dx = this.x - mouseX;
 86        let dy = this.y - mouseY;
 87        let d = sqrt(dx * dx + dy * dy);
 88        if (d < 180 && d > 1) {
 89          let force = pow(1 - d / 180, 2) * 85;
 90          this.x += dx / d * force;
 91          this.y += dy / d * force;
 92        }
 93      }
 94  
 95      if (this.radius > max(width, height) * 0.8 ||
 96          this.x < -100 || this.x > width + 100 ||
 97          this.y < -100 || this.y > height + 100) {
 98        this.reset();
 99      }
100    }
101  
102    display() {
103      let h = (this.hue + frameCount * 0.13) % 360;
104      let alpha = map(this.radius, 0, max(width, height) * 0.8, 85, 15);
105  
106      stroke(h, 85, 100, alpha * 0.25);
107      strokeWeight(this.size * 4);
108      point(this.x, this.y);
109  
110      stroke(h, 65, 100, alpha);
111      strokeWeight(this.size);
112      line(this.px, this.py, this.x, this.y);
113  
114      noStroke();
115      fill(h, 30, 100, alpha);
116      circle(this.x, this.y, this.size * 0.8);
117    }
118  }
119  
120  function mousePressed() {
121    for (let p of particles) {
122      let dx = p.x - mouseX;
123      let dy = p.y - mouseY;
124      let d = sqrt(dx * dx + dy * dy);
125      if (d < 300) {
126        p.radius += random(20, 120) * (1 - d / 300);
127        p.angle += random(-0.5, 0.5);
128        p.hue = random(170, 330);
129      }
130    }
131  }
132  
133  function touchStarted() {
134    if (touches.length > 0) {
135      mousePressed();
136    }
137    return false;
138  }
139  
140  function windowResized() {
141    resizeCanvas(windowWidth, windowHeight);
142    background(235, 35, 5);
143  }
144