# Turntable
URL: https://remocn.dev/docs/camera/turntable

A product card with real thickness spins on an invisible turntable through front, edge and back, with face shading, a moving sheen and a floor shadow

- Install: `npx shadcn@latest add @remocn/turntable`
- Vibe: premium
- Natural length: 64f @ 30fps

## Installation

```bash
npx shadcn@latest add @remocn/turntable
```

## Usage

`Turntable` builds a card in CSS 3D: a front face, a back face and four edge
slabs, sized like a credit card at 46% of the frame height. It spins around
its vertical axis on a slow-in, slow-out curve. Each face is shaded from a key
light at the front left, a sheen slides across as it turns, and a soft floor
shadow narrows and fades when the card is edge-on. With no children it shows a
red front with a mark and a light back.

```tsx
import { Turntable } from "@/components/remocn/turntable";

export const CardSpin = () => <Turntable />;
```

`turns` sets full rotations, so `turns={0.5}` ends on the back face and
`turns={2}` spins twice in the same time. `tilt` looks down on the card in
degrees; negative values look up at it. `thickness` is the card depth in px
at 720p.

### Your own faces

`children` is the front face and `back` is the back face. Each face clips its
content to the rounded card, so fill it edge to edge. The face font size is
1/30 of the card height, so content sized in `em` scales with the
composition.

```tsx
import { AbsoluteFill } from "remotion";
import { Turntable } from "@/components/remocn/turntable";

export const PassSpin = () => (
  <Turntable
    turns={1}
    edgeColor="#2E2A8C"
    back={<AbsoluteFill style={{ background: "#F5F5F5" }} />}
  >
    <AbsoluteFill
      style={{
        background: "linear-gradient(135deg, #4F46E5, #7C3AED)",
        padding: "2.5em",
        color: "white",
        fontSize: "1.6em",
        fontWeight: 700,
      }}
    >
      Pro Pass
    </AbsoluteFill>
  </Turntable>
);
```

Set `edgeColor` to a darker shade of your front so the card edge reads as
the same material.

## Timing

At 30 fps and `speed={1}`:

| Frames | Motion |
| --- | --- |
| 0–6 | The card rests facing the camera |
| 6–64 | The card spins `turns` times on one eased curve, fastest around frame 29 |
| 64+ | The card holds, facing front for whole turns or back for half turns |

`speed` scales the spin, so `speed={2}` ends at frame 32.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `children` | `ReactNode` | — | Front face content. Defaults to a red card with a mark |
| `back` | `ReactNode` | — | Back face content. Defaults to a light card with a stripe |
| `thickness` | `number` | `22` | Card thickness in px at 720p |
| `turns` | `number` | `1` | Full rotations over the spin |
| `tilt` | `number` | `8` | Camera tilt in degrees; positive looks down on the card |
| `colors` | `Partial<TurntableColors>` | `{ background: "#111111", front: "#E5322D", back: "#F2F2F2", edge: "#A3201C", mark: "#FFFFFF", shadow: "#000000" }` | Background, default face colors, edge slabs, default mark and floor shadow; merged over the defaults. The flat color props below win over it |
| `frontColor` | `string` | `"#E5322D"` | Default front face color; overrides colors.front |
| `edgeColor` | `string` | `"#A3201C"` | Card edge color; overrides colors.edge |
| `backColor` | `string` | `"#F2F2F2"` | Default back face color; overrides colors.back |
| `backgroundColor` | `string` | `"#111111"` | Stage background; overrides colors.background |
| `speed` | `number` | `1` | Playback multiplier |

## Use when
- A physical-looking object, such as a credit card, a membership pass or a ticket, should be shown from every side.
- A product launch needs a hero beat where the object turns once and settles facing the camera.
- Front and back carry different content and both should be seen in one move.

## Don't use when
- The content is a long page or recording the camera should travel across — use `stage`.
- A flat word should pop out of the plane into 3D — use `extrude-pop`.
- The object should come apart into labelled layers — use `exploded-view`.