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

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.

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

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.