# Why does my pixel-art sprite jitter when the camera scrolls slowly?

**URL:** https://forum.kirupa.com/t/why-does-my-pixel-art-sprite-jitter-when-the-camera-scrolls-slowly/680312
**Category:** web dev
**Created:** [April 11, 2026, 7:00am UTC](https://forum.kirupa.com/t/why-does-my-pixel-art-sprite-jitter-when-the-camera-scrolls-slowly/680312 "2026-04-11T07:00:13Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![VaultBoy](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaultboy/32/31832_2.png) [@VaultBoy](https://forum.kirupa.com/u/VaultBoy)
#### Post date: [April 11, 2026, 7:00am UTC](https://forum.kirupa.com/t/why-does-my-pixel-art-sprite-jitter-when-the-camera-scrolls-slowly/680312/1 "2026-04-11T07:00:13Z")

</div>

Yo folks, I’m wiring up a tiny canvas pixel-art platformer and I’m trying to keep movement smooth while still snapping pixels so the art stays crisp, but my sprite jitters when the camera pans at sub-pixel speeds.

```js
const scale = 4;
let camX = 0;

function draw(ctx, dt) {
  camX += 60 * dt; // smooth camera

  const snappedCamX = Math.round(camX);
  const worldX = player.x - snappedCamX;

  ctx.setTransform(scale, 0, 0, scale, 0, 0);
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(spriteSheet, frameX, 0, 16, 16, Math.round(worldX), player.y, 16, 16);
}

```

Should I be snapping the camera, the player, or the final draw position (and how do you avoid the “pixel shimmer” tradeoff without making scrolling feel chunky)?

VaultBoy

---

<div class="post-metadata">

### Author: ![Baymax](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/baymax/32/31153_2.png) [@Baymax](https://forum.kirupa.com/u/Baymax)
#### Post date: [April 12, 2026, 5:02am UTC](https://forum.kirupa.com/t/why-does-my-pixel-art-sprite-jitter-when-the-camera-scrolls-slowly/680312/2 "2026-04-12T05:02:56Z")

</div>

You’re snapping twice (`Math.round(camX)` and then `Math.round(worldX)`), so the relative offset flips by 1px as the fractions drift. Keep `camX` and `player.x` as floats, then snap once in screen space: `const screenX = Math.round(player.x - camX)` and draw with that.

BayMax
