Scroll Jellyfish
A translucent 3D jellyfish that swims through your headline as you scroll, with physics-simulated tentacles.
- Zero dependencies
- React + Tailwind
- Accessible
- Reduced-motion aware
Preview
Pelagia · Pink mauve stinger on a light studio background, like the reference. theme="pelagia"
The bell is ray-traced in a WebGL2 shader: front and inner surface, fresnel gel, 16 lappets, ribs and spots. Tentacles and frilly oral arms are a verlet simulation, so they trail behind, stretch and sway like they're in water. Scrolling makes it pulse faster and swim along an S-curve over big words; when you stop, it drifts. Ships as Pelagia (pink), Moon Jelly (ocean) and Abyss (bioluminescent).
Installation
Uses the shadcn CLI. It creates components/guetix/scroll-jellyfish.tsx and installs nothing else.
Usage
Under the hood
The details that make it feel right, and that a one-line prompt usually misses:
- 01Ray / ellipsoid intersection gives both the outer and inner bell surface, composited back-to-front with tentacles in between, so you see through the gel.
- 02Tentacles behind the bell are drawn before it and the ones in front after it, decided per frame from their 3D anchor depth.
- 03Verlet integration at a fixed 120 Hz with distance constraints: the swim pulse moves the anchors and the strands react.
- 04Swim speed comes from scroll velocity, eased in real time, so fast flicks produce strong strokes and long trails.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| sections | { word: string; caption?: string }[] | — | One big word per screen, with an optional caption. |
| theme | "pelagia" | "moon" | "abyss" | "pelagia" | Art direction. |
| mode | "contained" | "page" | "contained" | Scroll inside its own box, or use window scroll with a sticky scene. |
| animated | boolean | true | false = no idle swimming or pulsing. |
| className | string | — | Extra classes on the root. |
Accessibility
- The canvas is decorative (`aria-hidden`, no pointer events); every word is real text.
- The scroll area is focusable for keyboard scrolling.
- Reduced motion: no idle pulse or sway; it only moves when you scroll.