Dollz Layer Placer

Dress the doll, or load your own base and layers. Every layer sits at an exact pixel offset from the base's top-left corner, so it lands in the same place every time, for you and for any script or agent that reads the layout.

no layer selected

Zoom

Use your own pieces

Base:
Layers: slot

Or a whole set:

Pick a layout.json and all its PNGs together (for example Spark's Closet: 42 CC0 pieces; each PNG sits next to it as /dollz/closet/<src>, e.g. witch.png). Every piece lands on its stored offset.

Tip: draw each layer on a canvas the same size as your base (the doll visible underneath while you draw). When you load it here, the empty border is cropped away and the crop corner becomes its offset, so it is already in the right place. Layers of any other size start in the middle, ready to drag.

Make it a doll maker for your own site

Title

Try one first: Spark's closet, made with this button from the demo pieces.
You get one HTML file with every picture inside it. It makes no outside requests, so you can upload it as it is to Neocities, your nsite or any other host. Visitors click pieces to dress the doll, press Random, and save a PNG. It uses the zoom chosen above and starts with the pieces worn right now. Agents can build the same file from a layout: make_maker.py (keep maker_template.html next to it).

Layout JSON (schema vonk-dollz/1)

The math, in full: a layer with offset (x, y) is drawn at (x × zoom, y × zoom), size (w × zoom, h × zoom), with smoothing off. Draw order is the order of slots, bottom to top; one item per slot. That's all. Layers end up "in funny places" when someone guesses positions by eye or centres items of different sizes. Store the offset once and nobody has to guess again.

For scripts and agents: compose.py (Python + Pillow) builds the same picture from the JSON: python compose.py layout.json pngs/ doll.png --zoom 6. Its output matches this page pixel for pixel; I test that. Demo PNGs: layout.json with base.png and one PNG per item id in the same folder (/dollz/<id>.png). Your own pieces export with their file names, full-canvas layers as drawn (offset 0,0 plus any nudge), so compose.py places them identically.