Trim a Sprite Atlas Without Moving the Character's Anchor

Removing transparent borders changes a sprite's stored rectangle. It need not change where the character stands, but that requires preserving the removed offset and interpreting it correctly. Before adjusting animation frames by eye, separate three coordinate spaces: the original canvas, the trimmed image, and the packed atlas.
Disclosure: This article was prepared with AI assistance by the FrameSprite Workflow Team. It explains a general atlas handoff, not a claim that our tools export trimming or pivot metadata. All dimensions and placement results below are hypothetical calculations, not a product or engine test.
Key takeaways
- Keep the original dimensions and the trimmed region's original offset.
- State whether an anchor is measured against the original or cropped rectangle.
- Let a compatible importer restore trimming, or compensate manually; do not apply both.
Keep the three rectangles separate
The atlas rectangle answers where to sample pixels. The original size and trim offset answer where those pixels belong. PixiJS's texture guide distinguishes frame, orig, and trim; they are not interchangeable dimensions.
| Space | Question it answers | Example below |
|---|---|---|
| Original canvas | Where did the artist place the character and anchor? | 128 × 128 pixels |
| Trimmed region | Which part remains, and where was it inside that canvas? | Offset (24, 20), size 80 × 96 |
| Atlas | Where is that retained rectangle packed? | Offset (256, 64), size 80 × 96 |
TexturePacker's exporter reference separately describes cornerOffset, untrimmedSize, and the packed frameRect. Its definitions also distinguish rotation and extrusion. Check the chosen export format rather than assuming these internal names appear verbatim in every JSON file.
Read one frame before building the animation
Here is an illustrative frame entry using fields present in the PixiJS 8.2.3 spritesheet parser. This is an excerpt, not a complete atlas file or an observed FrameSprite export. Assume no packing rotation, no resolution scaling, and a rectangular crop:
{
"frame": { "x": 256, "y": 64, "w": 80, "h": 96 },
"rotated": false,
"trimmed": true,
"sourceSize": { "w": 128, "h": 128 },
"spriteSourceSize": { "x": 24, "y": 20, "w": 80, "h": 96 }
}
The retained region fits the original canvas: its right edge is 24 + 80 = 104, and its bottom edge is 20 + 96 = 116. Both lie within 128. Those are geometric edges, not inclusive pixel indices. The atlas position (256, 64) does not tell you how far the character stood from the original canvas edge.
Original canvas: 128 x 128
origin (0,0)
|
+-- trim starts at (24,20)
retained region: 80 x 96
anchor within it: (40,92)
Same retained pixels are packed at atlas (256,64).
Packing location does not replace the trim offset.
Convert the anchor once
Choose a foot reference point at original-canvas coordinate (64, 112). Here “anchor” means the image point that must land on a specified scene position. Use top-left origins, x increasing right, y increasing down, unit scale, and no rotation throughout this calculation.
Subtract the trim offset to express the same point inside the crop:
crop anchor x = 64 - 24 = 40
crop anchor y = 112 - 20 = 92
Suppose that point must land at scene position (300, 240). The cropped rectangle's scene top-left must then be:
left = 300 - 40 = 260
top = 240 - 92 = 148
Check the same result through the original canvas. Its top-left would be (300 − 64, 240 − 112) = (236, 128). Adding the retained region's offset gives (236 + 24, 128 + 20) = (260, 148). The two routes agree.
If you instead place the crop at (236, 128) without restoring the removed offset, the retained art moves 24 pixels left and 20 pixels up. Changing the atlas packing position cannot repair that placement error.
These equations describe translation only. Rotation, flips, parent transforms, resolution scaling, and a different destination coordinate system need their own explicit handling.
Ask what a normalized anchor is relative to
On the original canvas, the example point is (64/128, 112/128) = (0.5, 0.875). On the crop, it is (40/80, 92/96) = (0.5, 0.95833…). These describe the same point in different rectangles.
Reusing original-normalized y 0.875 against the crop's height gives 84, not 92: an eight-pixel mismatch. This is a useful diagnostic calculation, not an instruction to rewrite every imported anchor. A trim-aware loader may already retain the original dimensions and compensate correctly.
PixiJS's TextureOptions reference includes original and trimmed rectangles alongside a default placement/rotation anchor. Verify how the actual sprite and loader use them. Do not add manual trim compensation to a pipeline that already restores it.
Diagnose placement before repainting frames
Use an untrimmed reference and a fixed scene marker. Keep the sprite's transform unchanged while switching frames, then compare the same intended body reference point. Natural movement in the drawing still exists; preserving canvas placement does not freeze an animated foot or create collision data.
| Observation | Check first | Recovery |
|---|---|---|
| Correct pixels, but one frame shifts | That frame's original size and trim offset | Restore matching metadata; compare with its untrimmed reference |
| Every frame is offset after a manual fix | Whether the loader already applies trimming | Remove duplicate compensation and retest the marker |
| The anchor changes when crop size changes | Which rectangle normalized values refer to | Convert against the declared rectangle, or retain the loader's original-space model |
| The atlas preview looks correct but import differs | Export mode, rotation flag, resolution and loader support | Select a supported contract; rebuild and reimport a small example |
TexturePacker's trim settings distinguish preserving original placement from crop modes that change size or discard position. Similar-looking packed images can therefore carry different placement contracts. Inspect the data and importer together.
If the untrimmed reference already drifts, start with the fixed-canvas alignment review. If the crop itself selects the wrong pixels, the Unity slicing and pivot review addresses a separate rectangle-selection problem.
Hand off enough information to repeat the check
Keep the atlas and matching metadata together with the original source frames. Record the packer/export format, trim mode, rotation and scale settings, loader/version, anchor space, and a reference placement. Repacking may change atlas coordinates; changing the crop may change local coordinates. Neither should silently redefine the intended reference point.
An atlas handoff is usable when the receiving workflow samples the intended pixels and places them against the agreed reference. A smaller rectangle alone proves neither condition.
About the author: The FrameSprite Workflow Team documents game-asset workflows. About the team · Contact and corrections. The cover is an AI-generated concept illustration, not a product screenshot or a diagram of this example.
About the author
- We operate FrameSprite, a browser tool for indie game asset workflows. We publish practical sprite-sheet and animation export guides with downloadable examples, verification methods, and explicit limitations. Editorial ownership and corrections: https://www.framesprite.com/about#workflow-team. Contact: https://www.framesprite.com/contact.
Comments
Join the discussionNo comments yet. Be the first to comment.



