Justified gallery of stills and looping videos. Point at a piece, tap it or tab to it and it steps forward on a spring while the rest makes room.
pnpm dlx shadcn@latest add @spaceui/block-showcase-galleryimport { ShowcaseGallery } from '@/components/blocks/showcase-gallery'
const rows = [
[
{ title: 'Launch film', category: 'Motion', image: '/work/launch.webp', video: '/work/launch.mp4', aspect: 16 / 9 },
{ title: 'Watch face', category: 'Product', image: '/work/watch.webp', video: '/work/watch.mp4', aspect: 0.8 },
],
[
{ title: 'Dashboard', category: 'Product', image: '/work/dashboard.webp', aspect: 16 / 9 },
{ title: 'Mobile app', category: 'Product', image: '/work/app.webp', aspect: 1 },
],
]
export default function Work() {
return <ShowcaseGallery rows={rows} />
}Each row is justified to the full width, with tiles sized by their aspect (width / height). In a narrow container the same items regroup two per row and keep their real proportions.
Focus a tile and it steps forward on a spring: it widens, its row grows taller, its neighbours give way without changing the gallery's height, the media pans slightly toward the focus point and a caption with its title and category comes into focus. Only the focused tile's video plays; with nothing focused, videos play while they're on screen.
With reduced motion the focus still works, without the animation. Videos only load their metadata once they're about to scroll into view.
Remote images go through next/image, so add their host to images.remotePatterns in next.config.
3D cylindrical spiral carousel in WebGL2 with curved cards, axial directional blur, and matrix dither pattern.
ViewVertical WebGL lens gallery. Scroll-linked image planes from Immersive Lens.
ViewSmooth-minimum signed distance field WebGL2 carousel with liquid fusing cards that pull organic metaball strands when separated.
Viewpnpm dlx shadcn@latest add @spaceui/components-spaceui-uipnpm dlx shadcn@latest add @spaceui/block-showcase-gallery