REFERENCE
- Gallery page: https://magpui.com/en/i/exploded-puppet-layers-on-drag-838885
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/exploded-puppet-layers-on-drag-838885/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/exploded-puppet-layers-on-drag-838885/clip.mp4
- Original post: https://x.com/huozhi/status/2112939947670097940 by @huozhi
Before building, download the first frame and look at it. If ffmpeg is available, download the clip and extract frames (ffmpeg -i clip.mp4 -vf fps=2 frame-%02d.png), then study the motion frame by frame. Match what you see; the text below describes it, the frames are the truth.
ASSETS
This needs real artwork, not shapes drawn in code. Use the files the user gives you (ask where they are). If you have an image generation tool, generate them with these prompts; otherwise leave clearly marked placeholders.
- layered creature illustration: A mythical horned creature in the style of a traditional shadow-puppet cut-out, side view mid-stride, intricate ochre, vermilion and sage green linework with scale patterns and flame-like mane, flat even lighting, plain white background, 1:1. Deliver it also as separate parts (head, mane and neck, torso, front legs, back legs, tail) on the same transparent canvas so they stack back together.
BUILD:
An interactive exploded-view of a layered illustration. At rest it shows one complete creature figure, like a shadow-puppet marionette, hanging from 7 thin strings on a white background. When the user drags, the figure splits into its body-part layers (head, neck and mane, torso, front legs, back legs, tail), each printed on a translucent glass-like pane; the panes fan apart in 3D along the depth axis and the whole stack rotates with the pointer. On release the panes slide back together and the figure becomes flat and whole again, gently swaying on its strings. It should feel tactile, precise and a little magical, like taking apart a museum object.
DESIGN SYSTEM:
- Stage: full-width canvas area, min-height 640px, background #ffffff, figure centred, about 520px wide.
- Layers: 6-8 transparent PNG cut-outs of the same illustration, all the same canvas size so they line up perfectly when stacked.
- Panes (exploded state only): each layer sits on a rectangle about 30% larger than its part, fill rgba(220,232,240,0.35), 1px border rgba(150,170,190,0.45), no radius, very soft shadow 0 8px 24px rgba(30,50,70,0.08).
- Strings: 1px lines #8a8a8a at 60% opacity from the top of the stage to anchor points on the figure, each with a small 6x10px open oval knot about 120px from the top.
- Cursor: grab, grabbing while dragging.
MOTION:
- Explode on pointerdown: each layer translates on Z by index * 70px (centred around 0) and the panes fade in from 0 to 1 opacity; 600ms, stagger 40ms from head to tail, cubic-bezier(0.22, 1, 0.36, 1). Strings fade to 0 over 200ms.
- Drag rotate: pointer delta maps to rotateY (-60deg to 60deg) and rotateX (-25deg to 25deg) on the stack, smoothed with a spring (stiffness 180, damping 22). Base view while exploded: rotateY(-35deg) rotateX(10deg) so the depth reads like a fanned deck.
- Collapse on pointerup: Z back to 0, rotation back to 0, panes fade out; 700ms, stagger 30ms from tail to head, cubic-bezier(0.65, 0, 0.35, 1). Strings fade back in 300ms after.
- Idle sway: whole figure rotates around the top-centre anchor between -1.5deg and 1.5deg, 4000ms, ease-in-out, infinite alternate; each string end follows its anchor point.
SECTIONS:
- Parts: stage, string layer (SVG), layer stack (one element per body part), glass pane behind each part.
- States: idle (flat figure on strings, swaying), hover (cursor grab, figure lifts 4px), dragging (exploded, follows pointer), releasing (collapsing back), reduced motion (static figure plus a toggle button to show the layers).
IMPLEMENTATION:
- CSS 3D transforms (perspective: 1400px, transform-style: preserve-3d) on stacked absolutely positioned images, driven by Motion (Framer Motion) springs for the drag and staggered variants for explode and collapse. No WebGL needed: 6-8 textured planes are cheap as DOM layers. Use three.js with plane meshes only if you need lighting or more than about 15 layers.
- Strings: one SVG overlay, lines recomputed from the anchor points each animation frame while swaying.
- prefers-reduced-motion: no sway, no spring; explode and collapse become 150ms opacity crossfades between a flat view and a static exploded view.
- Keyboard: stage is focusable (tabindex 0, role group, aria-label describing the figure); Space or Enter toggles exploded, arrow keys rotate by 10deg steps; visible 2px focus ring.
- Performance: images pre-decoded, will-change: transform only while dragging, use pointer capture, cap layer image size at 1600px.
ADAPT TO THE PROJECT:
Reuse the project's existing design tokens, components and fonts, and map colors to the closest existing tokens. Never copy logos, brand names, photos or illustrations from the original: use placeholder artwork split into separate layers, all on the same canvas size.
SUCCESS CHECK:
- At rest the layers line up pixel-perfectly into one figure with strings and a gentle sway.
- Dragging fans the panes apart in depth with a visible stagger and the stack follows the pointer smoothly at 60fps.
- Releasing returns everything to the flat figure, and the keyboard toggle plus the reduced-motion fallback both work.