Putting an outfit together in a shop means pulling things off rails and holding them up against yourself. Online it means three tabs. I wanted the rail: the clothes hang in the air round the model, and you throw them at her. Get dressed at avivashishta.com/lab/outfit.
Drag a piece onto her, or just fling it in her direction, and it arcs onto the spot where it goes and the new layer spreads over her from there. Throw a second top and the first pops off. Click a piece on her to take it off, or shake the lot off.
The short version: Codex makes one photo of the model in a plain tee and shorts, then one edit per piece with only that piece on her, plus a product shot of each piece. A prep script keeps only the part of each edit that changed, as a transparent layer. Stacking those layers (bottoms, then tops, then shoes, then hats) on the first photo dresses her in any combination, though Codex only ever drew one piece at a time.
Step 1: the model, then one piece at a time (Codex)
A full-length fashion e-commerce photo of a young woman model with dark wavy shoulder-length hair standing facing the camera, relaxed confident pose, arms slightly away from her body, feet apart. She wears a plain fitted heather grey t-shirt, black bike shorts and white crew socks, no shoes, bare head. The whole body visible head to toe with margin, centered. Pale warm grey seamless studio background (#E9E8E4), crisp even studio light, photoreal. No text, no logos, no jewellery. Portrait 2:3, 1024x1536.
Eight pieces, two for each slot, each an edit of that photo that says exactly what it replaces:
The attached image is a full-length photo of a model. Dress her in wide khaki cargo trousers that reach the floor, over her socks, worn naturally and realistically, replacing only the black bike shorts. Keep EVERYTHING else exactly identical: the same woman, face, hair, pose, arms, the rest of her outfit, the framing, scale and position, the light and the pale grey background. Photoreal. No text, no logos. Portrait 2:3, 1024x1536.
Step 2: an edit becomes a layer
Eight pieces in four slots would need 81 photos to cover every outfit. Instead, the prep script compares each edit with the first photo and keeps only what changed: the trousers, and nothing else. Both photos are cut out with macOS Vision first, so a hoodie wider than the tee still counts. Three passes turn "what changed" into a clean layer:
m[i] = d > 70 ? 255 : 0; // 1. pixels that changed
// 2. only the big blobs: the largest, and any a quarter its size (two shoes are two blobs)
// 3. each row filled from its leftmost to its rightmost change
px[i * 4 + 3] = Math.min(px[i * 4 + 3], edge[i]); // the edit, cut to that shape
The second pass is there because a stray strand of hair that Codex redrew would otherwise count. The third is there because khaki cargo pockets over a bare leg are close enough in colour to not count as changed, which left holes in the trousers; filling each row closes them, and the gaps it bridges (between the legs, between an arm and the body) are background in the edit's own cut-out, so its alpha takes them back out.
The middle of that shape is where the piece goes on her, and where a thrown piece flies to.
bun scripts/prepare-outfit.mjs ./raw
On the page she is the first photo with up to four layers on top, in an order that matches how clothes go on: bottoms, then tops (so a hoodie hangs over the waistband), then shoes over the hems, then hats.
Step 3: things on springs
Every loose piece is a little spring toward its spot beside her, with a slow bob so the rail breathes. Dragging takes it off its spring and remembers how fast you were moving; letting go over her, or moving fast toward her when you let go, puts it on:
const tx = ev.clientX + s.vx * 0.25, ty = ev.clientY + s.vy * 0.25; // where it was headed
const thrown = inside(tx, ty) && Math.hypot(s.vx, s.vy) > 600;
Putting a piece on flies it in an arc to its spot on her, shrinking as it goes, and the layer then spreads out from that spot with a growing clip-path circle. Taking one off kicks it back out to its spring from where it was on her.
The small things
- The fit on the right lists what she has on by slot, with a running total and "Add the fit".
- Shake it off sends every piece flying back to the rail.
- A click on a loose piece puts it straight on, and the keyboard works too.
Build your own
Build a drag-to-dress store page (React, no libraries). Assets: a cut-out photo of a model in basics, and per piece a full-frame transparent layer of just that piece on her (made offline by keeping only the pixels that differ between an edit with the piece on and the original), the point on her where it sits, its slot (top, bottom, shoes, head) and a cut-out product shot. Show the model bottom-centre with the worn layers stacked in the order bottom, top, shoes, head.
Float the product shots round her, each a damped spring toward its spot with a gentle bob. Dragging a piece moves it and tracks its velocity; on release, if it is over her or was moving fast toward her, fly it in an arc to its point on her (shrinking and fading) and add its layer with a clip-path circle that grows from that point. A piece already in that slot is kicked back out. Invisible buttons at each worn piece's point take it off. Show the outfit by slot with a total, Add the fit and Shake it off.