# Depth Carousel

> Cards recede into depth on a 3D rail, with drag, wheel, keyboard and auto-advance navigation.

An image carousel where the focused card sits in front and the rest fan back along a tilted 3D rail, dimming, tinting and blurring with distance. Drag or flick to scrub, scroll the wheel or trackpad, press the arrow keys, click a card or a dot, or let it auto-advance.

<demo-depth-carousel>



</demo-depth-carousel>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/depth-carousel.json"
```

## Usage

```vue
<script setup lang="ts">
  import DepthCarousel from '~/components/ui/depth-carousel/DepthCarousel.vue';

  const items = [
    { image: 'https://picsum.photos/seed/dc-alto/800/1000', alt: 'Alto' },
    { image: 'https://picsum.photos/seed/dc-bay/800/1000', alt: 'Bay' },
    { image: 'https://picsum.photos/seed/dc-coast/800/1000', alt: 'Coast' },
  ];

  function onChange(index: number) {
    console.log('focused', index);
  }
</script>

<template>
  <div class="relative h-125 w-full">
    <DepthCarousel
      :items="items"
      :card-width="300"
      :card-height="380"
      :depth="220"
      :spread="90"
      :tilt="22"
      tilt-direction="right"
      ease="power3.out"
      autoplay
      @change="onChange"
    />
  </div>
</template>
```

The carousel fills its parent, so give the parent a height. It scales the stack down on narrow containers.

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        items
      </code>
    </td>
    
    <td>
      <code>
        Array<string | { image: string; alt?: string }>
      </code>
    </td>
    
    <td>
      6 sample images
    </td>
    
    <td>
      Slides to display. Pass image URLs or objects with an image URL and alt text.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        card-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        300
      </code>
    </td>
    
    <td>
      Width of each card in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        card-height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        380
      </code>
    </td>
    
    <td>
      Height of each card in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        18
      </code>
    </td>
    
    <td>
      Corner rounding of the cards in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tint
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#05060a'
      </code>
    </td>
    
    <td>
      Colour multiplied over cards as they recede, shading the depth of the stack.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        220
      </code>
    </td>
    
    <td>
      Z distance in px between cards along the depth rail. Higher values push the stack further back.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        spread
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        90
      </code>
    </td>
    
    <td>
      Lateral offset in px applied per card so the stack fans out to one side.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        22
      </code>
    </td>
    
    <td>
      Degrees each receding card rotates around the vertical axis, revealing its edge.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt-direction
      </code>
    </td>
    
    <td>
      <code>
        'left' | 'right'
      </code>
    </td>
    
    <td>
      <code>
        'right'
      </code>
    </td>
    
    <td>
      Which side the stack fans and tilts toward.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        perspective
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1400
      </code>
    </td>
    
    <td>
      CSS perspective in px. Lower values exaggerate the foreshortening.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        visible-cards
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        4
      </code>
    </td>
    
    <td>
      How many cards deep stay visible before further ones fade out.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        falloff
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.2
      </code>
    </td>
    
    <td>
      How quickly brightness, tint and blur ramp up with depth.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        blur
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        6
      </code>
    </td>
    
    <td>
      Maximum blur in px on the furthest visible card.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        duration
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        700
      </code>
    </td>
    
    <td>
      Length of the advance transition in ms.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ease
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'power3.out'
      </code>
    </td>
    
    <td>
      GSAP-style ease name: <code>
        power0
      </code>
      
      –<code>
        power4
      </code>
      
      , <code>
        sine
      </code>
      
      , <code>
        expo
      </code>
      
      , <code>
        circ
      </code>
      
      , <code>
        back(n)
      </code>
      
       with <code>
        .in
      </code>
      
      /<code>
        .out
      </code>
      
      /<code>
        .inOut
      </code>
      
      , or <code>
        none
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        autoplay
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Auto-advance the carousel, pausing on hover or focus.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        autoplay-delay
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        3200
      </code>
    </td>
    
    <td>
      Delay between auto-advances in ms (at least 600).
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        loop
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Wrap seamlessly from the last card back to the first.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        show-controls
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Show the previous and next arrow buttons.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        show-indicators
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Show the dot indicators.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root element.
    </td>
  </tr>
</tbody>
</table>

## Events

<table>
<thead>
  <tr>
    <th>
      Event
    </th>
    
    <th>
      Payload
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        change
      </code>
    </td>
    
    <td>
      <code>
        (index: number, item: { image: string; alt?: string })
      </code>
    </td>
    
    <td>
      Fires whenever the focused card changes.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The root is a focusable `role="group"` with `aria-roledescription="carousel"`. Left and Right arrow keys move between cards.
- Each card is a slide labelled "n of total"; slides other than the focused one are `aria-hidden`.
- The arrows are labelled buttons and the dots are a `tablist` with `aria-selected` on the current slide. All controls show a visible focus ring.
- With `prefers-reduced-motion: reduce` transitions jump instantly and autoplay is off.
- Ported from [React Bits](https://reactbits.dev/components/depth-carousel) by David Haz.
