141 lines, 5 of them comments · 1,312 tokens, written in 8 seconds for $0.040


  1  let particles = [];
  2  let palette = [];
  3  let stars = [];
  4  let hueOffset = 0;
  5  
  6  function setup() {
  7    createCanvas(windowWidth, windowHeight);
  8    colorMode(HSB, 360, 100, 100, 100);
  9    background(235, 35, 5);
 10    hueOffset = random(360);
 11  
 12    for (let i = 0; i < 550; i++) {
 13      particles.push(new Particle());
 14    }
 15  
 16    for (let i = 0; i < 180; i++) {
 17      stars.push({
 18        x: random(width),
 19        y: random(height),
 20        size: random(0.5, 2),
 21        phase: random(TWO_PI)
 22      });
 23    }
 24  }
 25  
 26  function draw() {
 27    // Transparent background creates luminous trails.
 28    noStroke();
 29    fill(235, 35, 5, 13);
 30    rect(0, 0, width, height);
 31  
 32    // Twinkling background stars.
 33    for (let s of stars) {
 34      let glow = 25 + 35 * sin(frameCount * 0.025 + s.phase);
 35      fill(210, 20, 100, glow);
 36      circle(s.x, s.y, s.size);
 37    }
 38  
 39    translate(width / 2, height / 2);
 40  
 41    // Central glowing core.
 42    blendMode(ADD);
 43    for (let r = 105; r > 0; r -= 5) {
 44      fill((hueOffset + 190) % 360, 80, 100, 1.4);
 45      circle(0, 0, r * 2);
 46    }
 47    fill(195, 30, 100, 75);
 48    circle(0, 0, 9);
 49  
 50    for (let p of particles) {
 51      p.update();
 52      p.display();
 53    }
 54    blendMode(BLEND);
 55  
 56    // Minimal interaction hint.
 57    resetMatrix();
 58    noStroke();
 59    fill(200, 15, 100, 55);
 60    textAlign(CENTER);
 61    textSize(12);
 62    text('MOVE TO DISTURB  •  CLICK TO SHIFT COLORS', width / 2, height - 24);
 63  }
 64  
 65  class Particle {
 66    constructor() {
 67      this.reset();
 68      this.angle = random(TWO_PI);
 69    }
 70  
 71    reset() {
 72      this.radius = random(30, min(width, height) * 0.48);
 73      this.angle = random(TWO_PI);
 74      this.speed = random(0.001, 0.008);
 75      this.size = random(0.6, 2.8);
 76      this.arm = floor(random(4));
 77      this.offset = randomGaussian(0, 0.22);
 78      this.hue = random(-30, 55);
 79      this.alpha = random(35, 90);
 80      this.twinkle = random(TWO_PI);
 81    }
 82  
 83    update() {
 84      let orbitalSpeed = this.speed * (120 / (this.radius + 45));
 85      this.angle += orbitalSpeed;
 86  
 87      let spiral = this.radius * 0.012;
 88      let a = this.angle + this.arm * TWO_PI / 4 + spiral + this.offset;
 89      let flatten = 0.62;
 90  
 91      this.x = cos(a) * this.radius;
 92      this.y = sin(a) * this.radius * flatten;
 93  
 94      // Gently bend the galaxy around the mouse.
 95      let mx = mouseX - width / 2;
 96      let my = mouseY - height / 2;
 97      let d = dist(this.x, this.y, mx, my);
 98      if (d < 150 && d > 1) {
 99        let force = pow(1 - d / 150, 2) * 35;
100        this.x += (this.x - mx) / d * force;
101        this.y += (this.y - my) / d * force;
102      }
103    }
104  
105    display() {
106      let h = (hueOffset + this.hue + 360) % 360;
107      let shimmer = 0.65 + 0.35 * sin(frameCount * 0.04 + this.twinkle);
108      let s = this.size * shimmer;
109  
110      noStroke();
111      fill(h, 85, 100, this.alpha * 0.09);
112      circle(this.x, this.y, s * 7);
113  
114      fill(h, 65, 100, this.alpha * 0.25);
115      circle(this.x, this.y, s * 3);
116  
117      fill(h, 25, 100, this.alpha);
118      circle(this.x, this.y, s);
119    }
120  }
121  
122  function mousePressed() {
123    hueOffset = random(360);
124    for (let p of particles) {
125      p.hue = random(-30, 55);
126    }
127  }
128  
129  function windowResized() {
130    resizeCanvas(windowWidth, windowHeight);
131    background(235, 35, 5);
132    stars = [];
133    for (let i = 0; i < 180; i++) {
134      stars.push({
135        x: random(width),
136        y: random(height),
137        size: random(0.5, 2),
138        phase: random(TWO_PI)
139      });
140    }
141  }