Keeping Photo Stickers Stable Across Preview and Export

Dalrymple Ramos
Xnap! product preview
table of contents

A sticker placed on a small browser preview needs to land in the same place on a larger exported photo strip. Storing its screen pixel position would tie the composition to one display size.

Xnap! represents sticker geometry with normalized position and size values. The shared strip compositor translates them into output pixels.

Store proportions of the composition#

For a canvas of width W and height H, the renderer multiplies normalized x and width values by W, and normalized y and height values by H.

A horizontal position of 0.25 means a quarter of the composition's width. It becomes 150 pixels on a 600-pixel output and 300 pixels on a 1,200-pixel output. The stored composition remains the same even though its raster dimensions change.

The editor still needs a consistent interpretation of position, size, and origin. Normalization alone cannot repair two renderers that disagree about which point the coordinates represent.

Rotate around the sticker center#

The compositor saves the canvas state, translates to the sticker's center, applies rotation, draws the image, and restores the state. Restoration matters: otherwise the next sticker would inherit the previous transform.

The helper starts from the generated strip at its natural dimensions. It then draws the normalized stickers over that base image, so base layout and overlays share one coordinate system.

Reuse the same export path#

The live editor and guest-dashboard upload flow call the same compositor. That removes one source of drift: independently maintained export implementations.

Image loading remains a separate failure path. The renderer requests anonymous cross-origin loading and continues if a sticker fails to load. A review should therefore check both geometry and asset availability. Matching coordinates cannot guarantee that a missing remote image will appear in the saved strip.