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.

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.

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.

Props
PropTypeDefaultDescription
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
number22Card thickness in px at 720p
turns
number1Full rotations over the spin
tilt
number8Camera 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
number1Playback multiplier