index.html and import a sprite sheet — drop it anywhere,
paste from the clipboard, or use Import image….All control panels live in one collapsible column on the right, in workflow order — the work area gets the full remaining width. Sections you rarely touch (Background, Vectorization, Alignment) start collapsed; click a heading to open it.
Drop a PNG / JPEG / WebP sheet anywhere, paste from the clipboard, or use Import image…. The image is kept at native resolution and never resampled. Then a detection method draws a rectangle around each frame:
On the Sheet view, dashed gray = detected cell, solid amber = tight crop. Click to select, drag to move, drag corners to resize — any method's result is editable. Gap threshold = how many empty columns split two frames; Min area ignores dust; Group distance joins detached parts (a flying feather) into their frame; Crop padding adds margin around every crop.
The background color is auto-detected from the sheet's corners and borders; override it with the Eyedropper, widen or narrow what counts as background with Tolerance. The Mode decides what happens to background-colored pixels:
Knockout edges are alpha-matted: partially blended fringe pixels get fractional transparency with the background unmixed from their color, so there's no pale halo on dark backgrounds. Transparency always previews over a checkerboard.
The Output switch at the top of this panel picks one of two products. Traced vector (SVG) — described below — rebuilds every frame as genuine path-based SVG; right for flat / cel / bold-color art. Original pixels — no tracing skips the tracer entirely: detection, knockout, alignment and timing still apply, and the PNG / APNG / sheet exports carry the source pixels untouched — pick it for painted, 3D-rendered or pixel-art sheets, which posterize under a flat-color trace (SVG export is unavailable in that mode).
In vector mode the pipeline is: build a color palette → assign pixels → extract pixel-exact contours → detect corners → simplify → fit Bézier curves.
| Preset | Behavior |
|---|---|
| Exact / Faithful | pixel-perfect polygons, no simplification — maximum fidelity |
| Clean Vector | removes redundant points, silhouette visually unchanged (default) |
| Smooth Illustration | stronger smoothing and curve fitting for a drawn look |
| Custom | any manual change to an advanced slider switches here |
Simplify — how far a point may drift when removed (px) · Corner angle — turns sharper than this stay sharp · Smoothing — pre-fit contour relaxing · Curve error — max Bézier deviation · Min feature / Despeckle — drop tiny shapes & noise · Alpha threshold / Edge bias — antialiased edge cutoff and grow/shrink · Detail merge — similarity needed to unify a detail across frames.
Shared palette — one quantization for the whole animation · Stabilize repeated details — pixels where most aligned frames agree are averaged; moving parts untouched · Consolidate repeated shapes — near-identical detail loops replaced by one canonical path (the main silhouette is exempt, so poses are never snapped). For AI-generated art where details vary more, lower Detail merge toward 70%.
All frames land on one fixed master canvas (same size and viewBox for every export). The anchor strategy decides which point of each frame is pinned where:
Anchors are computed from the foreground only — blank margins never influence registration. Auto-align all registers every frame to the Reference frame inside the stable region (drawn with Draw stable region, or a torso-window default), searching whole pixels then refining to subpixel. Per-frame Offset / Scale / Rotation plus arrow-key nudging fine-tune the result; Reset frame zeroes it; Copy alignment to selected propagates it. ⚠ in the timeline marks weak registration matches. Fit canvas to frames is the one-click recovery when sprites bleed off an edge: it resizes the master canvas to the largest frame plus padding, recenters the anchor, and zeroes every frame's manual offset.
The source image with detection rectangles. Select / move / resize crops, draw new ones (manual mode), pick the background with the eyedropper. Numbers match the timeline order.
Original / SVG / Overlay / Difference views; hold A/B to flip instantly; opacity slider for overlays. The Difference view paints mismatching pixels red and the status bar reports diff %, mean color error and alpha overlap — tune tracing until these settle. Onion skin (previous / next / reference, ghost or difference-blend), baseline / center / bbox / anchor guides, and a pixel grid at high zoom. Drag the frame to adjust its offset; drag a box in stable-region mode; double-click to place a custom anchor.
Plays the vector frames with real per-frame durations (identical timing to the exported APNG). Play / pause / step / scrub, FPS, speed ×0.25–4, loop / once / ping-pong, zoom to 1600% (Fit / 1:1), nearest or smooth display, checkerboard / solid / image background, onion skin and overlays. Stepping with |◀ ▶|, scrubbing, or clicking a timeline frame pauses playback — the frame you chose stays put until you press play again.
One card per frame: source|SVG thumbnail, duration (ms), enable checkbox, diff score (red when the trace drifts), ⚠ alignment warning. Click to select, Shift/⌘ for multi-select, then Duplicate / Delete / Move / batch-set duration.
| Button | Produces |
|---|---|
| SVG frames | one true-vector SVG per frame, all sharing one viewBox |
| PNG frames | transparent sequence at 1× / 2× / 4× / custom |
| APNG | real animated PNG — lossless alpha, per-frame delays, loop count |
| Sprite sheet | frames re-packed side-by-side on the fixed canvas |
| ZIP bundle | all of the above in one archive |
| Project JSON | everything needed to reopen and reproduce exactly |
| Split rectangles | each crop as its own raw PNG + coordinate manifest |
Snap to whole pixels rounds placement at raster time only (vector data keeps subpixel floats). Preview and every export render through the same placement math — they cannot disagree.
Export folder… (top of the Export panel, Chrome/Edge/Arc/Brave) lets you pick a destination folder once; from then on every export — SVG frames, PNG sequence, APNG, sheet, ZIP, project JSON — is written straight into it, no dialogs, and re-exports overwrite in place. The choice is remembered across sessions (the browser asks you to re-confirm access once per session on first write). Use downloads switches back to normal browser downloads, which is also the automatic fallback in Safari/Firefox or if the folder disappears.
Need a known-good input to try the flow? The bundled test sheet lives at
assets/sprite-idle.png.
Rule of thumb: stable-body / centroid anchors remove position noise; grid + origin preserves position as animation. Choose by what the motion means.
| Keys | Action |
|---|---|
| ← → ↑ ↓ | nudge selected frame(s) by 1 px |
| Shift + arrows | nudge by 10 px |
| Alt/Option + arrows | nudge by 0.1 px (subpixel) |
| [ / ] | previous / next frame |
| Space | play / pause the preview |
More depth: README.md (usage) · NOTES.md (how detection, tracing, alignment and APNG encoding work) · automated checks at tests/tests.html.