QUICKUPSCALE

PRACTICAL GUIDE

Sprite sheet tools and workflows

Trim animation frames without introducing position jitter

Start here

Choose Shared sequence union in the PNG trimmer. The four original 16×12 frames share bounds (2,1,9,8), so each result is 9×8 at offset (2,1), including the empty fourth frame.

Expected result:

A consistently placed sequence and a four-column 36×8 sheet built from its actual trim downloads. Intended character motion remains; extra movement caused by independently aligned tight crops is removed.

What you need

Use assets/inputs/sequence-00.png through sequence-03.png from the original CC0 pack. Keep the same 16×12 source canvas and order 00,01,02,03. Frame 03 is entirely transparent.

The pack's reference strips are software illustrations. The actual downloaded sheet is shown below; it is not a static substitute for the recorded playback trace.

Tested with: Actual U05 trim-download→U03 maker flow in local Cloudflare/workerd, desktop Chrome 154/macOS; independent Pillow/Canvas reconstruction and two timed cycles. Node 24.22.0 references checked separately.

1. Use one shared crop

Select the four sequence PNGs, choose Shared sequence union and select Trim PNG frames. Their individual visible bounds are (3,2,7,7), (5,1,6,8), (2,4,8,5) and null. The union is (2,1,9,8).

All results retain the same 9×8 canvas, including the empty frame. Keep the actual trim manifest: every frame has original size 16×12 and offset (2,1). A differently sized empty input still violates the shared-canvas rule.

2. Preserve intended motion

The source landmark moves through (6,6), (7,6), (6,7). Shared trimming puts it at (4,5), (5,5), (4,6), retaining those one-pixel changes. Aligning independent tight crops at one top-left would put it at (3,4), (2,5), (4,3), adding crop-induced displacement.

Shared bounds preserve a common coordinate system; they do not freeze an intentionally moving character or recover pivots that were never supplied.

3. Build from the actual downloaded PNGs

Extract the trim ZIP. Choose those four PNGs in the sprite-sheet maker, check order 00–03, choose Grid, Columns 4 and Require equal frame dimensions, then build. Do not replace them with the pack's reference union files.

Actual four-column sheet containing three shared-union poses and an empty fourth cell
Actual 36×8 maker download from the actual 9×8 trim outputs, in order 00,01,02,03.

The actual maker manifest maps its four source PNGs to 9×8 sheet cells. It does not automatically merge the trimmer's original-space offsets; retain both manifests.

4. Keep the empty dwell and inspect placement

Inspect all four cells and at least two ordered playback cycles. Frame 03 must remain empty and occupy its turn in the sequence. Place each crop back on a transparent 16×12 canvas at (2,1) when comparing original-space motion.

The recorded actual trace followed 0,1,2,3 twice, including two empty dwells, and checked all 1,536 reconstructed pixels against the decoded basis. Its requested interval was 125ms; observed intervals were about 126–226ms. This establishes the finite order/placement observation, not guaranteed 8 FPS delivery.

5. Keep no-op and codec limits explicit

An all-empty common-canvas sequence remains full-size 16×12 with null union bounds and offset (0,0). It is not reduced to fabricated artwork. Browser decoding can change hidden RGB and some partial-alpha colors, so comparisons use decoded source planes rather than claiming full raw-file channel identity.

Run node --test fixture.test.mjs, node generate.mjs and node generate.mjs --check in the extracted padding-trim-workflows folder for the separate 26-case software reference. Those commands do not replay the actual tool or timed browser trace.

Sources and next steps