TarotCarousel

A 3D card carousel where every card turns on one shared rotation — like cards on a single drum, at different points in the same turn.

132

134 copies

Image preview

Live preview

Abstract dark glass form
Preview

About this component

A full-bleed Framer code component that presents a deck of portrait cards in perspective. One card faces the viewer; its neighbours sit face-down at the edges, leaning toward the lens. Advancing the deck turns every card through the same continuous rotation — passing 90° is what swaps front for back, so there is no separate "flip" animation that can drift out of sync with the movement.

Single file, no dependencies, nothing to install. Paste it into a code file in Framer and drag it onto the canvas.

The component was built as a pixel-exact port of a standalone HTML build; both are verified identical at 0 differing pixels at 1899 and 700 wide.

Key features

One shared rotation — position and face are a single angle, odd in a card's distance from centre (−1 → +180°, 0 → 0°, +1 → −180°). Every card turns the same direction as the deck advances.

  • No separate flip — passing 90° is what swaps front for back, so the turn can never drift out of sync with the movement.

  • Scrubbable — the turn is a function of deck position, not a timed transition. Drag slowly and the card turns under your finger; stop halfway and it holds; reverse and it turns back.

  • Hand-dealt resting angles — no card sits upright. Direction alternates strictly (right, left, right); only magnitude is dealt from a seed, stable for the session.

  • Overlap-proof at any frame shape — the neighbour spread has a floor expressed in card widths, using the tilt-inflated extent (w·cos + h·sin). Verified across 13 sizes from 1920×1080 down to 360×640.

  • Six ways in — drag/swipe, arrow buttons, arrow keys, wheel/trackpad, click a neighbour, autoplay.

  • Gesture-aware scrolling — wheel deltas accumulate into a gesture, a 220 ms pause ends it, and the next turn can't start until the current one finishes easing.

  • Canvas-safe — drag, keyboard, wheel and autoplay are disabled on the Framer canvas. Honours prefers-reduced-motion.

  • Single file, zero dependencies — paste and drag.

  • Pixel-exact to the HTML build — 0 differing pixels at 1899 and 700 wide.

API reference

Content

Prop

Type

Default

Notes

cards

CardItem[]

6 placeholders

The deck

background

string

dark oxblood gradient

Any CSS background — colour or gradient

CardItem

Field

Type

Default

Range

Notes

image

ResponsiveImage | string

—

—

Framer image picker, URL, or data URI. Omitted → built-in placeholder plate

title

string

""

—

Alt text

pip

string

"8"

—

Corner numeral

tilt

number

0

−20…20°

0 = let the deck deal this card an angle

Colour

Prop

Type

Default

cream

Color

#f7f1e6

backField

Color

#1f0308

patternRed

Color

rgba(168,48,42,.46)

patternInner

Color

rgba(126,32,28,.34)

Chrome

Prop

Type

Default

showHeader

boolean

true

headerTitle

string

"The Eight"

headerFont

string

"Italianno, 'Snell Roundhand', cursive"

membersLabel

string

"Members"

showArrows

boolean

true

showCounter

boolean

true

Behaviour

Prop

Type

Default

Range

Notes

responsive

boolean

true

—

Compact layout below 820px wide

wheelControl

boolean

true

—

false = the page keeps the wheel

autoPlay

boolean

false

—


autoPlayDelay

number

3600

800–12000 ms


geometry

Field

Default

Range

Notes

cardSize

84

20–100 %

Centre-card height against the frame

aspect

1.535

0.6–2.2

Height ÷ width

spread

0.494

0.2–1

Neighbour distance, share of width

perspective

1.147

0.5–3

Camera distance, × width

restYaw

9

0–30°

Yaw on a parked card

push

170

0–500

Neighbour lean toward the lens

bump

90

0–400

Extra lens-ward push mid-sweep

lean

2

0–10°

In-plane lean per card of offset

motion

Field

Default

Range

Notes

duration

1000

200–2400 ms

Per card

flipFrom

0.1

0–0.5

Offset where the turn begins

flipTo

0.9

0.5–1

Narrow the span for a snappier turn

deal

Field

Default

Range

Notes

alternate

true

—

Lean right, left, right…

tiltMin

2.5

0–20°

Nothing sits upright

tiltMax

10

0–25°


seed

20260908

1–99999999

Change it to re-deal

Usage

<TarotCarousel
  cards={[
    { image: "/cards/waterfall.jpg", title: "The Waterfall", pip: "8" },
    { image: "/cards/rearing.jpg",   title: "The Rearing",   pip: "8" },
    { image: "/cards/gallop.jpg",    title: "The Gallop",    pip: "8", tilt: -6 },
  ]}
  background="#170104"
  showHeader={false}
  autoPlay
  autoPlayDelay={5000}
  geometry={{ cardSize: 78, spread: 0.52 }}
  motion={{ duration: 1200 }}
  deal={{ seed: 42, tiltMax: 6 }}
/>
<TarotCarousel
  cards={[
    { image: "/cards/waterfall.jpg", title: "The Waterfall", pip: "8" },
    { image: "/cards/rearing.jpg",   title: "The Rearing",   pip: "8" },
    { image: "/cards/gallop.jpg",    title: "The Gallop",    pip: "8", tilt: -6 },
  ]}
  background="#170104"
  showHeader={false}
  autoPlay
  autoPlayDelay={5000}
  geometry={{ cardSize: 78, spread: 0.52 }}
  motion={{ duration: 1200 }}
  deal={{ seed: 42, tiltMax: 6 }}
/>
<TarotCarousel
  cards={[
    { image: "/cards/waterfall.jpg", title: "The Waterfall", pip: "8" },
    { image: "/cards/rearing.jpg",   title: "The Rearing",   pip: "8" },
    { image: "/cards/gallop.jpg",    title: "The Gallop",    pip: "8", tilt: -6 },
  ]}
  background="#170104"
  showHeader={false}
  autoPlay
  autoPlayDelay={5000}
  geometry={{ cardSize: 78, spread: 0.52 }}
  motion={{ duration: 1200 }}
  deal={{ seed: 42, tiltMax: 6 }}
/>

Notes

  • geometry / motion / deal merge field by field — setting one value never wipes its siblings, so the partial objects above are valid.

  • The spread floor only engages when the raw value would cause overlap, so raising it on desktop behaves exactly as expected.

  • Drag, keyboard, wheel and autoplay are disabled on the Framer canvas so the component doesn't fight the editor.

  • Honours prefers-reduced-motion (shortens the move, narrows the turn, drops the bump).

Details

Category

Carousel

Media

Image

Views

132

Copies

134

Paste directly onto your Framer canvas.

Need a custom version?

We adapt components to your brand, motion and CMS setup.