Split Stack ParticlesSplit Stack Particles
A photo-card stack where the front card breaks into animated mosaic blocks, scatters, travels through the stack, and reforms at the back. Includes reduced-motion handling, hover controls, and per-card styling.
Autumn porchVermont
Lake pathMaine
Ridge lightColorado
Golden hourOregon
Fern floorWashington
Installation
- 1
Install the component:
npx shadcn@latest add https://ui.amines.fun/r/split-stack-particles.json - 2
Usage:
jsxapp/page.jsx
1import SplitStackParticles from "@/registry/components/Cards/SplitStackParticles";23export default function Page() {4 return (5 <div className="h-[520px] w-full">6 <SplitStackParticles visible={5} theme={{ edge: "#FF7138" }} />7 </div>8 );9}
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | Array<SplitStackParticlesItem> | Five built-in photo cards | Cards to render. Each item supports id, title, subtitle, icon (ReactNode), image (URL), color, background (CSS background), and content (ReactNode). Images are used as the card face and particle texture; color or theme.card is used when there is no image. |
| visible | number | 5 | Maximum number of cards drawn in the stack. |
| autoplay | boolean | true | Automatically advance the front card through the stack. Autoplay is disabled when reduced motion is requested. |
| delay | number | 1600 | Rest time between animation sweeps, in milliseconds. |
| from | "right" | "left" | "top" | "bottom" | "center" | "right" | Edge or point from which the blocks begin to break away. |
| drift | [number, number] | Derived from from (right: [1, -0.3], left: [-1, -0.3], top: [0.35, -1], bottom: [0.35, 1], center: [0.7, -0.5]) | Optional [x, y] direction for the particle cloud. Overrides the direction derived from from. |
| blocks | number | 28 | Smallest grid size across the card, clamped between 8 and 60. Higher values create finer blocks. |
| mosaic | number | 0.65 | Controls the mix of large and small blocks. 0 creates a uniform grid; higher values add more large blocks. |
| ragged | number | 0.28 | How unevenly the break front crosses the card, from 0 to 1. |
| scatter | number | 46 | Maximum particle travel distance as a percentage of card width. Travel is clamped to the available space. |
| spread | number | 1 | Angular spread of the particle cloud, in radians. |
| cloudAlpha | number | 0.6 | Opacity of the blocks while scattered. |
| shrink | number | 0.2 | How much blocks shrink while scattered. Set to 0 to keep their size. |
| tighten | number | 0.35 | How much the particle cloud contracts as it travels through the stack. Set to 0 to disable contraction. |
| glow | boolean | true | Draw an accent glow around blocks as they break away and land. |
| preTime | number | 0.12 | Seconds the hover state settles before the break begins. |
| dissolveTime | number | 0.65 | Seconds for the break front to cross the card. |
| scatterTime | number | 0.8 | Seconds for each block to fly away from the card. |
| hold | number | 0.1 | Extra pause in seconds between the break and the trip through the stack. |
| hopTime | number | 0.42 | Seconds for the particle cloud to pass one card. Total trip time grows with the stack depth. |
| mergeTime | number | 0.7 | Seconds for each block to fly back and reform the card. |
| mergeSpread | number | 0.4 | Seconds over which block merges are staggered. |
| mergeOverlap | number | 0.5 | How much of the merge overlaps the end of the trip, from 0 to 1. |
| land | number | 0.016 | Scale of the small pulse when the card lands. Set to 0 to disable the pulse. |
| hopArc | number | 1.2 | Height of the cloud's gentle arc through the stack, as a percentage of card height. |
| hopEase | number[] | ((progress: number) => number) | [0.3, 0.15, 0.7, 0.85] | Cubic Bezier control points [x1, y1, x2, y2] or a custom easing function for travel through the stack. |
| pauseOnHover | boolean | true | Pause automatic cycling while a pointer is over the component. |
| clickToAdvance | boolean | true | Let a click or keyboard activation advance the front card immediately. |
| size | number | 1 | Scales the whole stack proportionally. |
| aspect | number | 1 | Card width divided by card height. |
| fallbackAspect | number | 1.2 | Aspect ratio used when the parent does not provide a height. |
| radius | number | 9.5 | Card corner radius as a percentage of card width. |
| spacing | { x?: number; y?: number; z?: number } | { x: 7, y: 0, z: -110 } | Offset between cards. x and y are percentages; z is pixels and should remain negative for depth. |
| tilt | { x?: number; y?: number; z?: number } | { x: 0, y: 0, z: 0 } | Rotation of the whole stack in degrees around each axis. |
| perspective | number | 1400 | 3D perspective distance in pixels. Set to 0 to disable perspective. |
| perspectiveOrigin | string | "50% 45%" | CSS perspective-origin for the 3D stack. |
| dim | number | 0.2 | Darkening applied to cards farther back in the stack. |
| shadow | string | "0 30px 50px -24px rgba(0,0,0,0.8)" | CSS box-shadow drawn under each card. |
| theme | { card?: string; border?: string; text?: string; textMuted?: string; badge?: string; badgeText?: string; captionBg?: string; dim?: string; edge?: string } | Built-in dark theme | Optional CSS color overrides for the card, border, text, muted text, badge, badge text, caption background, depth dimming, and particle edge glow. |
| reserve | { x?: number; y?: number } | { x: 16, y: 6 } | Extra free space reserved around the stack for particles, as percentages of card width. |
| dpr | number | 1.5 | Maximum device-pixel ratio for the particle canvas. Lower values reduce canvas rendering cost. |
| zoom | number | 1.06 | Card image scale at full hover. 1 disables the zoom. |
| caption | boolean | true | Show the title and subtitle caption on the hovered card. |
| sheen | boolean | true | Show the animated sheen on the hovered card. |
| hoverSpread | number | 0.22 | How much cards fan out on hover. |
| hoverPush | number | 0.35 | Additional card movement on hover, relative to the stack spacing. |
| hoverLift | number | 5 | Vertical lift on hover, as a percentage of card width. |
| hoverZ | number | 24 | How far the hovered card moves toward the viewer, in pixels. Capped by stack depth. |
| hoverSpring | object | { type: "spring", stiffness: 300, damping: 28, mass: 0.9 } | Framer Motion transition configuration for hover movement. |
| hoverEase | number[] | ((progress: number) => number) | [0.22, 1, 0.36, 1] | Cubic Bezier control points or a custom easing function for hover movement. |
| hoverTime | number | 0.55 | Hover transition duration in seconds. |
| className | string | "" | Additional CSS classes applied to the root wrapper. |