Liquid Glass Carousel
An infinite row of image panels drawn through a liquid-glass lens. The carousel renders into an offscreen buffer at device resolution and a fullscreen quad resamples it through a shader that combines an elliptical mask, an inward pull, per-channel chromatic dispersion, a fluid rim wave from two sine harmonics, a central nova, and a shimmering accent ring. Panels share one height and take their width from each image's measured aspect, so nothing is cropped, and the row loops by wrapping a single scroll value against the summed slot widths. Wheel input moves a target the scroll lerps toward, and once the wheel goes quiet the target is redirected onto the nearest panel center so the row settles on an image inside the same glide. Scroll speed shrinks every panel by up to a quarter while it moves. Clicking a panel glides it to center and opens focus: it scales up, the lens distortion fades out, and every other panel sweeps down in a center-out wave. On load the panels rise from below at 80px tall, hold, then grow to full size while the lens blooms in. Three.js with GSAP.
npx shadcn@latest add https://ui.aryank.space/r/liquid-glass-carousel.jsonInstalls from ui.aryank.space. To add it by hand, copy the files in Usage below, or register the @compronents namespace via the docs.
| Prop | Type | Default | Description |
|---|---|---|---|
| projects | { src, brand, desc, aspect? }[] | Twelve BLANK editorial stills | Panel images and their overlay copy. Omit aspect to measure it from the loaded image. |
| panelHeight / gap | number / number | 450 / 12 | Shared panel height in px and the gap between slots. Widths follow each image's aspect. |
| accentColor | string | "#009dff" | Ring, aura, and dispersion tint of the lens. |
| background / textColor | string / string | "#ffffff" / "#000000" | Clear colour behind the panels and the colour of the counter. The overlay heading uses exclusion blending, so it inverts against either. |
| entry | boolean | true | Play the rise-and-grow entry on mount. Set false to start at full size with the lens already on. |
| minWidth / smallScreenText | number / string | 1024 / holding copy | Viewport width at or below which WebGL never boots and a holding screen shows instead. |
projectsasset-urlThe panel images with the brand and project line shown for each.
accentColorcolorRing, aura, and dispersion tint of the lens.
background / textColorcolorPage colour behind the panels and the counter colour.
panelHeight / gaptuplePanel height in px and the gap between slots.
threegsap