183 lines, 17 of them comments ยท 2,405 tokens, written in 35 seconds for $0.061


  1  let stars = [];
  2  let tentacles = [];
  3  let numTentacles = 12;
  4  let time = 0;
  5  
  6  function setup() {
  7    createCanvas(windowWidth, windowHeight);
  8    colorMode(HSB, 360, 100, 100, 100);
  9    
 10    // Create stars
 11    for (let i = 0; i < 200; i++) {
 12      stars.push({
 13        x: random(width),
 14        y: random(height),
 15        size: random(1, 3),
 16        twinkleSpeed: random(0.01, 0.05),
 17        phase: random(TWO_PI)
 18      });
 19    }
 20    
 21    // Create tentacle base points
 22    for (let i = 0; i < numTentacles; i++) {
 23      tentacles.push({
 24        angle: map(i, 0, numTentacles, -PI * 0.4, PI * 0.4),
 25        length: random(120, 250),
 26        segments: floor(random(15, 25)),
 27        phase: random(TWO_PI),
 28        speed: random(0.015, 0.035),
 29        hue: random(180, 280)
 30      });
 31    }
 32  }
 33  
 34  function draw() {
 35    background(240, 80, 8);
 36    time += 0.01;
 37    
 38    // Draw stars
 39    noStroke();
 40    for (let s of stars) {
 41      let brightness = 50 + 50 * sin(frameCount * s.twinkleSpeed + s.phase);
 42      fill(220, 20, brightness, 80);
 43      ellipse(s.x, s.y, s.size);
 44    }
 45    
 46    // Floating particles
 47    for (let i = 0; i < 30; i++) {
 48      let px = (width * 0.3 + noise(i * 10, time * 0.5) * width * 0.4);
 49      let py = (noise(i * 20, time * 0.3) * height);
 50      let ps = 2 + sin(time * 2 + i) * 1.5;
 51      fill(200, 60, 80, 30);
 52      ellipse(px, py, ps);
 53    }
 54    
 55    // Jellyfish position follows mouse gently
 56    let jx = lerp(width / 2, mouseX, 0.3);
 57    let jy = lerp(height * 0.35, mouseY, 0.2);
 58    
 59    // Breathing/pulsing
 60    let pulse = sin(time * 2) * 0.15 + 1;
 61    let bellWidth = 120 * pulse;
 62    let bellHeight = 80 * pulse;
 63    
 64    push();
 65    translate(jx, jy);
 66    
 67    // Draw glow
 68    for (let g = 5; g > 0; g--) {
 69      fill(220, 70, 70, 3);
 70      ellipse(0, 0, bellWidth * 2 + g * 40, bellHeight * 2 + g * 30);
 71    }
 72    
 73    // Draw tentacles
 74    for (let t of tentacles) {
 75      let baseX = cos(t.angle + HALF_PI) * bellWidth * 0.7;
 76      let baseY = bellHeight * 0.3;
 77      
 78      beginShape();
 79      noFill();
 80      strokeWeight(2);
 81      
 82      for (let s = 0; s <= t.segments; s++) {
 83        let frac = s / t.segments;
 84        let wave = sin(frac * PI * 3 + frameCount * t.speed * 2 + t.phase) * (20 + frac * 30);
 85        let mouseInfluence = (mouseX - jx) * 0.02 * frac;
 86        let sx = baseX + wave + mouseInfluence;
 87        let sy = baseY + frac * t.length;
 88        
 89        let alpha = map(frac, 0, 1, 70, 10);
 90        stroke(t.hue, 60, 80, alpha);
 91        curveVertex(sx, sy);
 92      }
 93      endShape();
 94      
 95      // Small glowing dots on tentacles
 96      for (let s = 0; s <= t.segments; s += 3) {
 97        let frac = s / t.segments;
 98        let wave = sin(frac * PI * 3 + frameCount * t.speed * 2 + t.phase) * (20 + frac * 30);
 99        let mouseInfluence = (mouseX - jx) * 0.02 * frac;
100        let sx = baseX + wave + mouseInfluence;
101        let sy = baseY + frac * t.length;
102        let dotAlpha = 40 + 30 * sin(time * 4 + frac * PI);
103        noStroke();
104        fill(t.hue, 50, 90, dotAlpha);
105        ellipse(sx, sy, 4 * (1 - frac * 0.5));
106      }
107    }
108    
109    // Draw bell (body)
110    noStroke();
111    
112    // Outer bell layers for glow
113    for (let i = 3; i >= 0; i--) {
114      fill(220, 50 - i * 10, 70 + i * 5, 15 - i * 3);
115      ellipse(0, 0, bellWidth * 2 + i * 20, bellHeight * 2 + i * 15);
116    }
117    
118    // Main bell
119    fill(230, 40, 75, 50);
120    arc(0, 0, bellWidth * 2, bellHeight * 2, PI, TWO_PI, CHORD);
121    
122    // Inner bell detail
123    fill(210, 60, 85, 30);
124    arc(0, -5, bellWidth * 1.4, bellHeight * 1.4, PI, TWO_PI, CHORD);
125    
126    // Bell rim
127    noFill();
128    stroke(200, 50, 90, 50);
129    strokeWeight(2);
130    arc(0, 0, bellWidth * 2, bellHeight * 2, PI, TWO_PI);
131    
132    // Scalloped edge
133    let numScallops = 20;
134    for (let i = 0; i < numScallops; i++) {
135      let a = map(i, 0, numScallops, PI, TWO_PI);
136      let a2 = map(i + 1, 0, numScallops, PI, TWO_PI);
137      let r = bellWidth;
138      let x1 = cos(a) * r;
139      let y1 = sin(a) * bellHeight;
140      let x2 = cos(a2) * r;
141      let y2 = sin(a2) * bellHeight;
142      let scallop = 5 + sin(time * 3 + i) * 3;
143      stroke(250, 40, 90, 40);
144      strokeWeight(1.5);
145      noFill();
146      bezier(x1, y1, x1, y1 + scallop, x2, y2 + scallop, x2, y2);
147    }
148    
149    // Internal organs pattern
150    noStroke();
151    for (let i = 0; i < 4; i++) {
152      let orgX = sin(time + i * HALF_PI) * 15;
153      let orgY = -bellHeight * 0.3 + cos(time * 0.5 + i) * 5;
154      fill(280, 50, 80, 25 + sin(time * 2 + i) * 10);
155      ellipse(orgX, orgY, 20, 30);
156    }
157    
158    pop();
159    
160    // Ambient bubbles rising
161    noStroke();
162    for (let i = 0; i < 15; i++) {
163      let bx = width * noise(i * 100, time * 0.2);
164      let by = height - ((frameCount * (0.5 + i * 0.1) + i * 200) % (height + 50));
165      let bs = 3 + sin(time + i) * 2;
166      fill(200, 30, 90, 20);
167      ellipse(bx, by, bs);
168    }
169  }
170  
171  function windowResized() {
172    resizeCanvas(windowWidth, windowHeight);
173    stars = [];
174    for (let i = 0; i < 200; i++) {
175      stars.push({
176        x: random(width),
177        y: random(height),
178        size: random(1, 3),
179        twinkleSpeed: random(0.01, 0.05),
180        phase: random(TWO_PI)
181      });
182    }
183  }