Source of: Cosmic Jellyfish, by Claude Opus 4.6
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 }