Componentregistry:component
DNA Carousel
A cinematic 3D image carousel where cards travel along two intertwined helix strands. Drag, swipe, scroll or use the arrow keys, with momentum, snapping, infinite looping, optional autoplay, blur and RGB-split depth effects, and reduced-motion support. No dependencies.
Installation
$ npx shadcn@latest add @creative-ui/dna-carouselOn an older shadcn CLI, use the URL: npx shadcn@latest add https://ui.krutikraut.com/r/dna-carousel.json
Preview
Marble statue · 1/6 · drag, scroll or use arrow keys
Depth260px
Helix spread70px
Curve24°
Rotation22°
Tilt-6°
Blur1.5px
RGB split0px
Side opacity0.80
Speed0.15/s
Usage
Example.tsx
import { DnaCarousel } from "@/components/dna-carousel"
const images = [
{ src: "https://images.unsplash.com/photo-1566054757965-8c4085344c96?w=600&q=80&auto=format&fit=crop", alt: "Marble statue" },
{ src: "https://images.unsplash.com/photo-1579783902614-a3fb3927b6a5?w=600&q=80&auto=format&fit=crop", alt: "Floral still life" },
{ src: "https://images.unsplash.com/photo-1578301978693-85fa9c0320b9?w=600&q=80&auto=format&fit=crop", alt: "Pastoral landscape" },
]
export function Gallery() {
return (
<DnaCarousel
images={images}
aria-label="Classical artworks"
className="h-[420px] w-full"
/>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| images* | { src: string; alt?: string }[] | — | Cards to show. Short lists are repeated so the loop fills both sides of the helix. |
| itemWidth | number | 220 | Card width in px, before responsive fitting. |
| itemHeight | number | 300 | Card height in px, before responsive fitting. |
| gap | number | 20 | Extra space between neighbouring cards along the helix axis, in px. |
| radius | number | 14 | Card corner radius in px. |
| depth | number | 260 | How far the back strand sits behind the front strand, in px. |
| curve | number | 24 | Extra helix twist per card, in degrees. 0 gives a flat zig-zag. |
| spread | number | 70 | Vertical distance between the two strands, in px. |
| perspective | number | 1100 | CSS perspective distance in px. Lower is more dramatic. |
| rotation | number | 22 | Y-axis rotation per card away from the centre, in degrees. |
| tilt | number | -6 | Tilt of the whole helix axis, in degrees. |
| activeScale | number | 1 | Scale of the centred card. |
| inactiveScale | number | 0.8 | Scale of the other cards. |
| blur | number | 1.5 | Blur in px per card of distance from the centre. |
| rgbSplit | number | 0 | Chromatic-aberration offset in px, off by default. Grows with distance and scroll speed. |
| inactiveOpacity | number | 0.8 | Opacity of cards away from the centre, 0 to 1. |
| shadow | boolean | true | Drop shadow under each card. |
| shadowStrength | number | 0.35 | Shadow opacity, 0 to 1. |
| dragSensitivity | number | 1 | Multiplier on drag distance. Higher moves more cards per swipe. |
| inertia | number | 0.93 | Momentum kept per frame after a flick, 0 to 1. Higher coasts longer. |
| snapStrength | number | 0.08 | How quickly cards settle into place, 0 to 1. |
| autoplay | boolean | true | Drift on its own. Resumes 2.5 s after the user stops interacting. |
| autoplaySpeed | number | 0.15 | Autoplay speed in cards per second. Negative values run backwards. |
| pauseOnHover | boolean | true | Pause autoplay while a mouse is over the carousel. |
| wheel | boolean | true | Scroll the carousel with the mouse wheel or trackpad while hovering it. |
| grabCursor | boolean | true | Show grab and grabbing cursors. |
| visibleItems | number | 4 | How many cards stay visible on each side of the active one. |
| onIndexChange | (index: number) => void | — | Called with the index into images of the card that becomes active. |
| aria-label | string | "Image carousel" | Name announced for the carousel region. |
Also accepts every div prop, which is spread onto the root element.
Notes
- Give it a height with
className. Cards are absolutely positioned, and the helix scales down to fit smaller containers. - Focusable, with arrow-key navigation. The active card's
altis announced through a polite live region. - With reduced motion, autoplay, blur and the RGB split are off and cards settle faster.
- Stops animating while scrolled out of view.
