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

Installation
$ pnpm dlx 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}:

FramesMotion
0–6The card rests facing the camera
6–64The 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.

Props11

PropTypeDefault
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
number22

Card thickness in px at 720p

turns
number1

Full rotations over the spin

tilt
number8

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
number1

Playback multiplier

  • childrenReactNode

    Front face content. Defaults to a red card with a mark

  • backReactNode

    Back face content. Defaults to a light card with a stripe

  • thicknessnumber

    Card thickness in px at 720p

    Default22

  • turnsnumber

    Full rotations over the spin

    Default1

  • tiltnumber

    Camera tilt in degrees; positive looks down on the card

    Default8

  • colorsPartial<TurntableColors>

    Background, default face colors, edge slabs, default mark and floor shadow; merged over the defaults. The flat color props below win over it

    Default{ background: "#111111", front: "#E5322D", back: "#F2F2F2", edge: "#A3201C", mark: "#FFFFFF", shadow: "#000000" }

  • frontColorstring

    Default front face color; overrides colors.front

    Default"#E5322D"

  • edgeColorstring

    Card edge color; overrides colors.edge

    Default"#A3201C"

  • backColorstring

    Default back face color; overrides colors.back

    Default"#F2F2F2"

  • backgroundColorstring

    Stage background; overrides colors.background

    Default"#111111"

  • speednumber

    Playback multiplier

    Default1