zxbc2023 commited on
Commit
2c4bfe0
·
1 Parent(s): 6cc9688

Add glowing jellyfish deep-sea animation (generated via Unsloth Studio)

Browse files
Files changed (2) hide show
  1. glowing_jellyfish.html +433 -0
  2. manifest.json +8 -0
glowing_jellyfish.html ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Deep-Sea Jellyfish</title>
7
+ <style>
8
+ html, body {
9
+ margin: 0;
10
+ padding: 0;
11
+ overflow: hidden;
12
+ height: 100%;
13
+ background: #02031a;
14
+ }
15
+ canvas {
16
+ display: block;
17
+ width: 100vw;
18
+ height: 100vh;
19
+ }
20
+ #title {
21
+ position: fixed;
22
+ top: 20px;
23
+ left: 50%;
24
+ transform: translateX(-50%);
25
+ font-family: 'Georgia', serif;
26
+ color: rgba(180, 220, 255, 0.6);
27
+ font-size: 18px;
28
+ letter-spacing: 6px;
29
+ text-transform: uppercase;
30
+ pointer-events: none;
31
+ text-shadow: 0 0 12px rgba(120, 200, 255, 0.8);
32
+ animation: fadeIn 3s ease;
33
+ }
34
+ @keyframes fadeIn {
35
+ from { opacity: 0; }
36
+ to { opacity: 1; }
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <canvas id="sea"></canvas>
42
+ <div id="title">Abyssal Bloom</div>
43
+ <script>
44
+ (() => {
45
+ const canvas = document.getElementById('sea');
46
+ const ctx = canvas.getContext('2d');
47
+ let W, H;
48
+
49
+ function resize() {
50
+ W = canvas.width = window.innerWidth;
51
+ H = canvas.height = window.innerHeight;
52
+ }
53
+ window.addEventListener('resize', resize);
54
+ resize();
55
+
56
+ // ---------- Palette of glowing jellyfish colors ----------
57
+ const PALETTES = [
58
+ { core: [255, 120, 200], rim: [255, 190, 240] }, // pink
59
+ { core: [130, 220, 255], rim: [210, 245, 255] }, // aqua
60
+ { core: [190, 150, 255], rim: [230, 205, 255] }, // violet
61
+ { core: [255, 200, 110], rim: [255, 235, 190] }, // gold
62
+ { core: [120, 255, 200], rim: [210, 255, 235] }, // mint
63
+ { core: [255, 150, 130], rim: [255, 210, 190] }, // coral
64
+ ];
65
+
66
+ const rand = (a, b) => a + Math.random() * (b - a);
67
+ const TAU = Math.PI * 2;
68
+
69
+ // ---------- Background gradient (rebuilt on resize) ----------
70
+ function drawBackground(t) {
71
+ const g = ctx.createLinearGradient(0, 0, 0, H);
72
+ // subtle breathing shift in the deep blue
73
+ const breathe = Math.sin(t * 0.0002) * 0.5 + 0.5;
74
+ g.addColorStop(0, `rgb(${8 + breathe * 6}, ${20 + breathe * 8}, 60)`);
75
+ g.addColorStop(0.45, 'rgb(4, 12, 48)');
76
+ g.addColorStop(1, 'rgb(1, 3, 20)');
77
+ ctx.fillStyle = g;
78
+ ctx.fillRect(0, 0, W, H);
79
+ }
80
+
81
+ // ---------- God rays from the surface ----------
82
+ class LightRay {
83
+ constructor() { this.reset(true); }
84
+ reset(init) {
85
+ this.x = rand(0, W);
86
+ this.width = rand(40, 160);
87
+ this.speed = rand(0.05, 0.15);
88
+ this.sway = rand(0, TAU);
89
+ this.alpha = rand(0.02, 0.06);
90
+ this.y = init ? rand(-H * 0.2, 0) : -H * 0.3;
91
+ }
92
+ update(dt) {
93
+ this.y += this.speed * dt * 0.06;
94
+ this.sway += 0.0004 * dt;
95
+ if (this.y > H * 1.2) this.reset(false);
96
+ }
97
+ draw(t) {
98
+ const sway = Math.sin(this.sway) * 80;
99
+ const grad = ctx.createLinearGradient(0, 0, 0, H * 0.9);
100
+ const a = this.alpha * (0.7 + 0.3 * Math.sin(t * 0.001 + this.sway));
101
+ grad.addColorStop(0, `rgba(140, 200, 255, ${a})`);
102
+ grad.addColorStop(1, 'rgba(140, 200, 255, 0)');
103
+ ctx.fillStyle = grad;
104
+ ctx.beginPath();
105
+ const topW = this.width * 0.35;
106
+ ctx.moveTo(this.x - topW / 2 + sway * 0.3, this.y);
107
+ ctx.lineTo(this.x + topW / 2 + sway * 0.3, this.y);
108
+ ctx.lineTo(this.x + this.width / 2 + sway, this.y + H * 0.9);
109
+ ctx.lineTo(this.x - this.width / 2 + sway, this.y + H * 0.9);
110
+ ctx.closePath();
111
+ ctx.fill();
112
+ }
113
+ }
114
+
115
+ // ---------- Drifting plankton / particles ----------
116
+ class Plankton {
117
+ constructor() { this.reset(true); }
118
+ reset(init) {
119
+ this.x = rand(0, W);
120
+ this.y = init ? rand(0, H) : H + 10;
121
+ this.r = rand(0.5, 2.2);
122
+ this.vy = rand(0.02, 0.12);
123
+ this.vx = rand(-0.03, 0.03);
124
+ this.phase = rand(0, TAU);
125
+ this.hue = rand(180, 220);
126
+ }
127
+ update(dt, t) {
128
+ this.y -= this.vy * dt * 0.06;
129
+ this.x += (this.vx + Math.sin(t * 0.001 + this.phase) * 0.05) * dt * 0.06;
130
+ if (this.y < -10) this.reset(false);
131
+ if (this.x < -10) this.x = W + 10;
132
+ if (this.x > W + 10) this.x = -10;
133
+ }
134
+ draw(t) {
135
+ const tw = 0.4 + 0.6 * (0.5 + 0.5 * Math.sin(t * 0.002 + this.phase));
136
+ ctx.fillStyle = `hsla(${this.hue}, 80%, 80%, ${0.25 * tw})`;
137
+ ctx.beginPath();
138
+ ctx.arc(this.x, this.y, this.r, 0, TAU);
139
+ ctx.fill();
140
+ }
141
+ }
142
+
143
+ // ---------- Bubbles ----------
144
+ class Bubble {
145
+ constructor() { this.reset(true); }
146
+ reset(init) {
147
+ this.x = rand(0, W);
148
+ this.y = init ? rand(0, H) : H + 10;
149
+ this.r = rand(1.5, 5);
150
+ this.vy = rand(0.15, 0.5);
151
+ this.sway = rand(0, TAU);
152
+ }
153
+ update(dt) {
154
+ this.y -= this.vy * dt * 0.06;
155
+ this.sway += 0.003 * dt;
156
+ if (this.y < -10) this.reset(false);
157
+ }
158
+ draw() {
159
+ const x = this.x + Math.sin(this.sway) * 8;
160
+ ctx.strokeStyle = 'rgba(190, 230, 255, 0.35)';
161
+ ctx.lineWidth = 1;
162
+ ctx.beginPath();
163
+ ctx.arc(x, this.y, this.r, 0, TAU);
164
+ ctx.stroke();
165
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
166
+ ctx.beginPath();
167
+ ctx.arc(x - this.r * 0.3, this.y - this.r * 0.3, this.r * 0.25, 0, TAU);
168
+ ctx.fill();
169
+ }
170
+ }
171
+
172
+ // ---------- Jellyfish ----------
173
+ class Jellyfish {
174
+ constructor() {
175
+ this.reset(true);
176
+ }
177
+ reset(init) {
178
+ this.palette = PALETTES[Math.floor(Math.random() * PALETTES.length)];
179
+ this.size = rand(22, 65);
180
+ this.x = rand(0, W);
181
+ this.y = init ? rand(-H * 0.3, H * 1.3) : H + this.size * 3;
182
+ this.baseSpeed = rand(0.15, 0.45);
183
+ this.drift = rand(-0.08, 0.08);
184
+ this.phase = rand(0, TAU);
185
+ this.pulseSpeed = rand(0.0018, 0.0032);
186
+ this.tentacles = Math.floor(rand(7, 13));
187
+ this.tentacleLen = this.size * rand(1.6, 2.8);
188
+ this.wanderSeed = rand(0, 1000);
189
+ this.glow = rand(0.7, 1.2);
190
+ }
191
+ update(dt, t) {
192
+ // Pulsing motion: jellyfish "swim" upward as the bell contracts
193
+ this.pulse = 0.5 + 0.5 * Math.sin(t * this.pulseSpeed + this.phase);
194
+ this.y -= (this.baseSpeed * (0.5 + this.pulse * 0.9)) * dt * 0.06;
195
+ this.x += (this.drift + Math.sin(t * 0.0006 + this.wanderSeed) * 0.12) * dt * 0.06;
196
+
197
+ // Wrap around
198
+ if (this.y < -this.size * 4) this.reset(false);
199
+ if (this.x < -this.size * 3) this.x = W + this.size * 2;
200
+ if (this.x > W + this.size * 3) this.x = -this.size * 2;
201
+ }
202
+ draw(t) {
203
+ const { core, rim } = this.palette;
204
+ const s = this.size * (0.85 + this.pulse * 0.25); // bell contracts/expands
205
+ const squash = 1 - this.pulse * 0.22; // bell flattens on pulse
206
+
207
+ ctx.save();
208
+ ctx.translate(this.x, this.y);
209
+ const tilt = Math.sin(t * 0.0005 + this.wanderSeed) * 0.18;
210
+ ctx.rotate(tilt);
211
+
212
+ // ---- Outer glow halo ----
213
+ const halo = ctx.createRadialGradient(0, 0, s * 0.2, 0, 0, s * 2.4);
214
+ halo.addColorStop(0, `rgba(${core[0]}, ${core[1]}, ${core[2]}, ${0.28 * this.glow * (0.6 + this.pulse * 0.4)})`);
215
+ halo.addColorStop(1, 'rgba(0,0,0,0)');
216
+ ctx.fillStyle = halo;
217
+ ctx.beginPath();
218
+ ctx.arc(0, 0, s * 2.4, 0, TAU);
219
+ ctx.fill();
220
+
221
+ // ---- Tentacles (wavy, trailing) ----
222
+ ctx.globalCompositeOperation = 'lighter';
223
+ const n = this.tentacles;
224
+ for (let i = 0; i < n; i++) {
225
+ const frac = n === 1 ? 0.5 : i / (n - 1);
226
+ const baseX = (frac - 0.5) * s * 1.5;
227
+ const len = this.tentacleLen * (0.8 + 0.3 * Math.sin(i * 2.7));
228
+ const segs = 14;
229
+ ctx.beginPath();
230
+ ctx.moveTo(baseX, s * 0.15);
231
+ let px = baseX, py = s * 0.15;
232
+ for (let k = 1; k <= segs; k++) {
233
+ const f = k / segs;
234
+ const wave = Math.sin(t * 0.002 + this.phase + i * 0.7 + f * 4) * s * 0.18 * f;
235
+ px = baseX + wave - f * s * 0.15 * Math.sin(i);
236
+ py = s * 0.15 + f * len;
237
+ ctx.lineTo(px, py);
238
+ }
239
+ const a = 0.35 * (1 - 0.6 * Math.abs(frac - 0.5) * 2) * this.glow;
240
+ ctx.strokeStyle = `rgba(${core[0]}, ${core[1]}, ${core[2]}, ${a})`;
241
+ ctx.lineWidth = 1.4 * (1 - 0.4 * Math.abs(frac - 0.5));
242
+ ctx.stroke();
243
+ }
244
+
245
+ // ---- Oral arms (thicker, central) ----
246
+ for (let i = 0; i < 4; i++) {
247
+ const frac = (i + 0.5) / 4;
248
+ const baseX = (frac - 0.5) * s * 0.5;
249
+ const len = this.tentacleLen * 0.65;
250
+ ctx.beginPath();
251
+ ctx.moveTo(baseX, s * 0.1);
252
+ for (let k = 1; k <= 10; k++) {
253
+ const f = k / 10;
254
+ const wave = Math.sin(t * 0.0018 + i * 1.9 + f * 5 + this.phase) * s * 0.12 * f;
255
+ ctx.lineTo(baseX + wave, s * 0.1 + f * len);
256
+ }
257
+ ctx.strokeStyle = `rgba(${rim[0]}, ${rim[1]}, ${rim[2]}, ${0.18 * this.glow})`;
258
+ ctx.lineWidth = 2.6;
259
+ ctx.stroke();
260
+ }
261
+ ctx.globalCompositeOperation = 'source-over';
262
+
263
+ // ---- Bell ----
264
+ ctx.save();
265
+ ctx.scale(1, squash);
266
+
267
+ // Bell body with radial glow
268
+ const bellGrad = ctx.createRadialGradient(0, -s * 0.15, s * 0.1, 0, 0, s);
269
+ bellGrad.addColorStop(0, `rgba(${rim[0]}, ${rim[1]}, ${rim[2]}, ${0.85 * this.glow})`);
270
+ bellGrad.addColorStop(0.5, `rgba(${core[0]}, ${core[1]}, ${core[2]}, ${0.5 * this.glow})`);
271
+ bellGrad.addColorStop(0.85, `rgba(${core[0]}, ${core[1]}, ${core[2]}, ${0.18})`);
272
+ bellGrad.addColorStop(1, 'rgba(0,0,0,0)');
273
+ ctx.fillStyle = bellGrad;
274
+ ctx.beginPath();
275
+ ctx.arc(0, 0, s, Math.PI, TAU);
276
+ // Wavy bottom edge of the bell
277
+ const waves = 6;
278
+ for (let i = 0; i <= waves; i++) {
279
+ const wx = (i / waves - 0.5) * 2 * s;
280
+ const wy = Math.sin(i * Math.PI + t * 0.004 + this.phase) * s * 0.06;
281
+ ctx.lineTo(wx, wy);
282
+ }
283
+ ctx.closePath();
284
+ ctx.fill();
285
+
286
+ // Inner organs — glowing core
287
+ ctx.globalCompositeOperation = 'lighter';
288
+ const coreGrad = ctx.createRadialGradient(0, -s * 0.25, 0, 0, -s * 0.25, s * 0.55);
289
+ const pulseA = 0.5 + 0.5 * this.pulse;
290
+ coreGrad.addColorStop(0, `rgba(255,255,255,${0.75 * pulseA * this.glow})`);
291
+ coreGrad.addColorStop(0.4, `rgba(${rim[0]}, ${rim[1]}, ${rim[2]}, ${0.4 * pulseA * this.glow})`);
292
+ coreGrad.addColorStop(1, 'rgba(0,0,0,0)');
293
+ ctx.fillStyle = coreGrad;
294
+ ctx.beginPath();
295
+ ctx.arc(0, -s * 0.25, s * 0.55, 0, TAU);
296
+ ctx.fill();
297
+
298
+ // Four tiny glowing "gonads"
299
+ for (let i = 0; i < 4; i++) {
300
+ const gx = (i - 1.5) * s * 0.22;
301
+ ctx.beginPath();
302
+ ctx.ellipse(gx, -s * 0.32, s * 0.09, s * 0.14, 0, 0, TAU);
303
+ ctx.fillStyle = `rgba(255,255,255,${0.3 + 0.4 * pulseA})`;
304
+ ctx.fill();
305
+ }
306
+ ctx.globalCompositeOperation = 'source-over';
307
+
308
+ // Bell rim highlight
309
+ ctx.strokeStyle = `rgba(${rim[0]}, ${rim[1]}, ${rim[2]}, ${0.5 * this.glow})`;
310
+ ctx.lineWidth = 1.5;
311
+ ctx.beginPath();
312
+ ctx.arc(0, 0, s * 0.98, Math.PI, TAU);
313
+ ctx.stroke();
314
+
315
+ ctx.restore();
316
+ ctx.restore();
317
+ }
318
+ }
319
+
320
+ // ---------- Seafloor silhouettes ----------
321
+ class Kelp {
322
+ constructor(x, h) {
323
+ this.x = x;
324
+ this.h = h;
325
+ this.phase = rand(0, TAU);
326
+ this.swaySpeed = rand(0.0004, 0.0009);
327
+ this.width = rand(4, 9);
328
+ }
329
+ draw(t) {
330
+ const baseY = H + 5;
331
+ ctx.beginPath();
332
+ ctx.moveTo(this.x, baseY);
333
+ const segs = 12;
334
+ for (let k = 1; k <= segs; k++) {
335
+ const f = k / segs;
336
+ const sway = Math.sin(t * this.swaySpeed + this.phase + f * 3) * 18 * f;
337
+ ctx.lineTo(this.x + sway - this.width * (1 - f), baseY - f * this.h);
338
+ }
339
+ for (let k = segs; k >= 0; k--) {
340
+ const f = k / segs;
341
+ const sway = Math.sin(t * this.swaySpeed + this.phase + f * 3) * 18 * f;
342
+ ctx.lineTo(this.x + sway + this.width * (1 - f), baseY - f * this.h);
343
+ }
344
+ ctx.closePath();
345
+ ctx.fillStyle = 'rgba(10, 30, 40, 0.85)';
346
+ ctx.fill();
347
+ }
348
+ }
349
+
350
+ // ---------- Build the scene ----------
351
+ const jellies = [];
352
+ const plankton = [];
353
+ const bubbles = [];
354
+ const rays = [];
355
+ const kelps = [];
356
+
357
+ function populate() {
358
+ jellies.length = 0;
359
+ const count = Math.max(6, Math.floor((W * H) / 120000));
360
+ for (let i = 0; i < count; i++) jellies.push(new Jellyfish());
361
+
362
+ plankton.length = 0;
363
+ for (let i = 0; i < 90; i++) plankton.push(new Plankton());
364
+
365
+ bubbles.length = 0;
366
+ for (let i = 0; i < 25; i++) bubbles.push(new Bubble());
367
+
368
+ rays.length = 0;
369
+ for (let i = 0; i < 7; i++) rays.push(new LightRay());
370
+
371
+ kelps.length = 0;
372
+ for (let i = 0; i < Math.floor(W / 90); i++) {
373
+ kelps.push(new Kelp(rand(0, W), rand(60, 180)));
374
+ }
375
+ }
376
+ populate();
377
+ window.addEventListener('resize', () => setTimeout(populate, 100));
378
+
379
+ // Mouse interaction: jellies gently drift away from the cursor
380
+ let mouse = { x: -9999, y: -9999 };
381
+ window.addEventListener('mousemove', e => { mouse.x = e.clientX; mouse.y = e.clientY; });
382
+ window.addEventListener('mouseleave', () => { mouse.x = -9999; mouse.y = -9999; });
383
+
384
+ // ---------- Main loop ----------
385
+ let last = performance.now();
386
+ function frame(t) {
387
+ const dt = Math.min(50, t - last);
388
+ last = t;
389
+
390
+ drawBackground(t);
391
+
392
+ // Rays (behind everything)
393
+ for (const r of rays) { r.update(dt); r.draw(t); }
394
+
395
+ // Distant plankton
396
+ ctx.save();
397
+ for (const p of plankton) { p.update(dt, t); p.draw(t); }
398
+ ctx.restore();
399
+
400
+ // Kelp
401
+ for (const k of kelps) k.draw(t);
402
+
403
+ // Bubbles
404
+ for (const b of bubbles) { b.update(dt); b.draw(); }
405
+
406
+ // Jellyfish — nudge away from cursor
407
+ for (const j of jellies) {
408
+ const dx = j.x - mouse.x;
409
+ const dy = j.y - mouse.y;
410
+ const dist = Math.hypot(dx, dy);
411
+ if (dist < 160 && dist > 0.001) {
412
+ const force = (160 - dist) / 160;
413
+ j.x += (dx / dist) * force * 2;
414
+ j.y += (dy / dist) * force * 2;
415
+ }
416
+ j.update(dt, t);
417
+ j.draw(t);
418
+ }
419
+
420
+ // Vignette for depth
421
+ const v = ctx.createRadialGradient(W / 2, H / 2, H * 0.35, W / 2, H / 2, H * 0.95);
422
+ v.addColorStop(0, 'rgba(0,0,0,0)');
423
+ v.addColorStop(1, 'rgba(0, 2, 12, 0.55)');
424
+ ctx.fillStyle = v;
425
+ ctx.fillRect(0, 0, W, H);
426
+
427
+ requestAnimationFrame(frame);
428
+ }
429
+ requestAnimationFrame(frame);
430
+ })();
431
+ </script>
432
+ </body>
433
+ </html>
manifest.json CHANGED
@@ -7,6 +7,14 @@
7
  "agent": "hermes-agent",
8
  "prompt": "Create an awesome animation of a nuclear explosion over a city in html canvas. Verify that it looks correct and beautiful in browser.",
9
  "date": "2026-08-23"
 
 
 
 
 
 
 
 
10
  }
11
  ]
12
  }
 
7
  "agent": "hermes-agent",
8
  "prompt": "Create an awesome animation of a nuclear explosion over a city in html canvas. Verify that it looks correct and beautiful in browser.",
9
  "date": "2026-08-23"
10
+ },
11
+ {
12
+ "file": "glowing_jellyfish.html",
13
+ "title": "deep-sea scene of glowing jellyfish",
14
+ "model": "Qwen3.8-27B-UD-IQ4_XS",
15
+ "agent": "unsloth-studio",
16
+ "prompt": "Create a colorful animated deep-sea scene of glowing jellyfish in html canvas",
17
+ "date": "2026-08-24"
18
  }
19
  ]
20
  }