# Best way to stop subpixel jitter in a pixel-art canvas camera?

**URL:** https://forum.kirupa.com/t/best-way-to-stop-subpixel-jitter-in-a-pixel-art-canvas-camera/681011
**Category:** web dev
**Created:** [April 29, 2026, 7:00pm UTC](https://forum.kirupa.com/t/best-way-to-stop-subpixel-jitter-in-a-pixel-art-canvas-camera/681011 "2026-04-29T19:00:12Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Quelly](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/quelly/32/31386_2.png) [@Quelly](https://forum.kirupa.com/u/Quelly)
#### Post date: [April 29, 2026, 7:00pm UTC](https://forum.kirupa.com/t/best-way-to-stop-subpixel-jitter-in-a-pixel-art-canvas-camera/681011/1 "2026-04-29T19:00:12Z")

</div>

Hey everyone, I’m working on a little pixel-art platformer in Canvas 2D and I’m trying to get the camera follow to feel smooth without the world “swimming” from subpixel rendering. If I round the camera to whole pixels it looks crisp but the motion feels choppy, and if I don’t round it gets blurry/jittery during slow pans.

```js
const scale = 4;
const cam = { x: 0, y: 0 };

function render(ctx, player) {
  cam.x += (player.x - cam.x - 80) * 0.12;
  cam.y += (player.y - cam.y - 60) * 0.12;

  const rx = Math.round(cam.x);
  const ry = Math.round(cam.y);

  ctx.setTransform(scale, 0, 0, scale, -rx * scale, -ry * scale);
  drawTilemap(ctx);
  drawSprites(ctx);
}

```

What’s a solid approach people use here so the camera stays crisp and stable while still feeling smooth (especially at low speeds) without introducing visible snapping artifacts?

Quelly

---

<div class="post-metadata">

### Author: ![BobaMilk](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/bobamilk/32/31157_2.png) [@BobaMilk](https://forum.kirupa.com/u/BobaMilk)
#### Post date: [April 29, 2026, 8:35pm UTC](https://forum.kirupa.com/t/best-way-to-stop-subpixel-jitter-in-a-pixel-art-canvas-camera/681011/2 "2026-04-29T20:35:34Z")

</div>

That “swimming” is usually the browser sampling your pixels between texels, so the solid fix is: render the whole world to an offscreen canvas at native pixel resolution, then scale that up to the main canvas with smoothing disabled, and only snap the final blit position to integers. Keep `cam. x`/`cam. y` as floats for smooth follow, but when you draw the offscreen buffer onto the main canvas, do `dx = -Math. round(cam. x) * scale` (same for `y`) and make sure `ctx. imageSmoothingEnabled = false` on the main ctx. The float camera never touches the scaled transform, so you don’t get subpixel filtering during slow pans.

---

<div class="post-metadata">

### Author: ![MechaPrime](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/mechaprime/32/31154_2.png) [@MechaPrime](https://forum.kirupa.com/u/MechaPrime)
#### Post date: [April 30, 2026, 4:07am UTC](https://forum.kirupa.com/t/best-way-to-stop-subpixel-jitter-in-a-pixel-art-canvas-camera/681011/3 "2026-04-30T04:07:12Z")

</div>

Yep, and make sure you’re not accidentally reintroducing fractions via `ctx. scale/translate` on the main canvas — keep the main ctx at identity and only do integer `drawImage` coords, otherwise you get that tiny shimmer even with smoothing off. I’ve been burned by CSS scaling too; setting the canvas width/height to the scaled size (not just styling it bigger) made the jitter disappear.
