115 lines, 4 of them comments · 1,205 tokens, written in 8 seconds for $0.037


  1  let particles = [];
  2  let paletteIndex = 0;
  3  let palettes = [
  4    [[100, 180, 255], [200, 100, 255], [255, 100, 180]],
  5    [[255, 180, 60], [255, 80, 100], [255, 230, 150]],
  6    [[80, 255, 200], [60, 180, 255], [180, 255, 120]],
  7    [[255, 100, 220], [140, 100, 255], [255, 220, 100]]
  8  ];
  9  
 10  function setup() {
 11    createCanvas(windowWidth, windowHeight);
 12    pixelDensity(1);
 13    colorMode(RGB, 255);
 14    background(5, 5, 18);
 15    initParticles();
 16  }
 17  
 18  function initParticles() {
 19    particles = [];
 20    let count = min(950, floor(width * height / 700));
 21    for (let i = 0; i < count; i++) {
 22      let radius = random(20, min(width, height) * 0.46);
 23      let angle = random(TWO_PI);
 24      particles.push({
 25        radius: radius,
 26        angle: angle,
 27        speed: random(0.001, 0.006),
 28        size: random(0.7, 3.2),
 29        offset: random(TWO_PI),
 30        colorIndex: floor(random(3)),
 31        drift: random(0.3, 1.8)
 32      });
 33    }
 34  }
 35  
 36  function draw() {
 37    background(5, 5, 18, 35);
 38    translate(width / 2, height / 2);
 39  
 40    let t = frameCount * 0.01;
 41    let mouseInfluence = map(mouseX, 0, width, -1, 1);
 42    let verticalInfluence = map(mouseY, 0, height, 0.5, 1.5);
 43  
 44    // Soft central glow
 45    noStroke();
 46    for (let r = 130; r > 0; r -= 5) {
 47      fill(90, 60, 180, map(r, 130, 0, 0, 8));
 48      ellipse(0, 0, r * 2);
 49    }
 50  
 51    blendMode(ADD);
 52  
 53    for (let p of particles) {
 54      p.angle += p.speed * (1 + mouseInfluence * 0.6);
 55  
 56      let spiral = p.angle + p.radius * 0.012;
 57      let wobble = sin(t * p.drift + p.offset) * 12;
 58      let r = p.radius + wobble;
 59  
 60      let x = cos(spiral) * r;
 61      let y = sin(spiral) * r * 0.62 * verticalInfluence;
 62  
 63      // Slowly rotating galaxy
 64      let rotation = t * 0.08;
 65      let rx = x * cos(rotation) - y * sin(rotation);
 66      let ry = x * sin(rotation) + y * cos(rotation);
 67  
 68      let c = palettes[paletteIndex][p.colorIndex];
 69      let pulse = 0.7 + 0.3 * sin(t * 2 + p.offset);
 70  
 71      noStroke();
 72      fill(c[0], c[1], c[2], 12 * pulse);
 73      circle(rx, ry, p.size * 7);
 74  
 75      fill(c[0], c[1], c[2], 45 * pulse);
 76      circle(rx, ry, p.size * 3.5);
 77  
 78      fill(c[0], c[1], c[2], 190 * pulse);
 79      circle(rx, ry, p.size);
 80    }
 81  
 82    blendMode(BLEND);
 83  
 84    // Bright galaxy core
 85    noStroke();
 86    fill(180, 170, 255, 25);
 87    circle(0, 0, 65 + sin(t * 2) * 8);
 88    fill(220, 210, 255, 60);
 89    circle(0, 0, 24);
 90    fill(255, 255, 255, 220);
 91    circle(0, 0, 5);
 92  
 93    // Interface text
 94    resetMatrix();
 95    fill(180, 185, 220, 150);
 96    textFont('monospace');
 97    textSize(12);
 98    textAlign(CENTER);
 99    text('MOVE MOUSE TO DISTORT  •  CLICK TO SHIFT COLORS', width / 2, height - 25);
100  }
101  
102  function mousePressed() {
103    paletteIndex = (paletteIndex + 1) % palettes.length;
104  }
105  
106  function touchStarted() {
107    paletteIndex = (paletteIndex + 1) % palettes.length;
108    return false;
109  }
110  
111  function windowResized() {
112    resizeCanvas(windowWidth, windowHeight);
113    background(5, 5, 18);
114    initParticles();
115  }