DEV Community

FrameSprite for FrameSprite

Posted on Originally published at framesprite.com Fully Autonomous

Canvas Pixel Writes Ignore Zoom? Use the Right API

Disclosure: This article was generated with AI for the FrameSprite team, which has a commercial interest in FrameSprite. It received a separate AI editorial review against the cited sources. Executed synthetic fixtures are identified with their runtime and limits; no other editor, engine, production or performance test is implied.

Use putImageData for direct bitmap-coordinate writes. It does not apply the current drawing transform, so scaling the context does not move or enlarge those pixels. If your sprite preview should honor zoom or opacity, put the pixels into an intermediate image surface and draw that surface through drawImage.

Key takeaway: Raw pixel placement and transformed drawing are different operations. Choose the one your preview actually needs.

Reproduce the coordinate mismatch

The authored fixture sets scale to two and globalAlpha to 0.25, then writes one opaque red pixel with putImageData at x = 1, y = 1. The putImageData reference states that the method is not affected by the current transformation matrix.

ctx.scale(2, 2);
ctx.globalAlpha = 0.25;
const pixel = new ImageData(
  new Uint8ClampedArray([255, 0, 0, 255]), 1, 1
);
ctx.putImageData(pixel, 1, 1);
Enter fullscreen mode Exit fullscreen mode

In the recorded local run, pixel 1,1 is fully opaque red. Pixel 2,2 is still transparent. The test therefore makes it clear that the write did not follow the expected scaled-drawing path.

Keep raw editing in image space

For a brush, threshold mask or per-pixel correction, raw bitmap coordinates may be exactly what you want. Convert pointer coordinates into image coordinates before editing the pixel array, and retain a separate display transform for showing that array.

Do not apply the preview zoom to the stored pixel positions. Otherwise a UI zoom change can alter which source pixels the edit modifies. The getImageData reference is relevant when reading the source bitmap back for those edits.

Draw the edited bitmap through the preview transform

An integration pattern is to write the pixels into an offscreen or temporary 2D canvas, then draw that canvas as an image source on the preview. The current transform and alpha then apply to the drawImage operation rather than to putImageData.

rawContext.putImageData(imageData, 0, 0);
previewContext.save();
try {
  previewContext.scale(zoom, zoom);
  previewContext.globalAlpha = previewOpacity;
  previewContext.drawImage(rawCanvas, 0, 0);
} finally {
  previewContext.restore();
}
Enter fullscreen mode Exit fullscreen mode

This is an integration example. The supplied fixture tested the raw-write behavior, not this complete preview component. The Canvas specification provides the distinction between pixel manipulation and drawing operations.

Recorded evidence

Chromium 156.0.8078.4 ran two assertions in the local browser checker. The output records RGBA 255,0,0,255 at 1,1 and RGBA 0,0,0,0 at 2,2. The input preserves scale, alpha and write position. No game engine or production editor ran; the checker belongs to the controlled local harness recorded with this article.

Check adjacent coordinate errors

Use the pointer-coordinate mapping guide for screen-to-image input. Use the DPR budget guide for CSS and bitmap sizing. Use the transparent RGB review guide when the stored channel values, rather than their display coordinates, are wrong.

Keep a one-pixel asymmetric test in the editor. A detailed sprite can make a small coordinate mismatch look like antialiasing or a source-art defect.

Editorial ownership

Prepared by the workflow team, which has a commercial relationship with this site. This guide was drafted with AI assistance; independent editorial review is recorded separately. Report a technical correction with the relevant input, tool version and observed result.

Original guide and downloadable materials

Top comments (0)