# Scaling is deforming sprite from atlas

**URL:** <https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969>\
**Category:** Phaser 3\
**Created:** [July 17, 2021, 5:12pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969 "2021-07-17T17:12:47Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 17, 2021, 5:12pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/1 "2021-07-17T17:12:47Z")

</div>

Hi. I have a tilemap with a 32 x 32 tile size and an atlas for a 32 x 41 player sprite that looks like this:

![atlas](https://global.discourse-cdn.com/free1/uploads/phaser1/original/2X/4/4e109f8065de30db00e56e70c9572dbedc092c3e.png)

The problem (I think) is that Phaser is scaling the sprite differently each time it shows the animations, and deforming it in different ways each time. For instance:

![animation-deformed](https://global.discourse-cdn.com/free1/uploads/phaser1/original/2X/0/064111f73f7de4a961d8fd20f63c2b109243c8ed.png)

These are screenshots _of the same animation frame_ (running in Chrome). You can see that they are a bit different each time. This is especially notable in the eyes.

Changing the scale mode from `RESIZE` to `NONE` (or `FIT` / `ENVELOP` for that matter) does nothing to fix the issue. Neither does resizing the sprite to 32 x 32.

The atlas is being loaded with:

```javascript
preload() {
...
this.load.atlas("atlas", "./assets/prod/atlas/atlas.png", "./assets/prod/atlas/atlas.json");
...
}

```

And in my create function I have:

```javascript
this.player = this.physics.add
  .sprite(spawnPoint.x, spawnPoint.y, "atlas", "ariel-front")
  .setSize(32, 41);

const anims = this.anims;
anims.create({
  key: "ariel-left-walk",
  frames: anims.generateFrameNames("atlas", {
    prefix: "ariel-left-walk.",
    start: 0,
    end: 3,
    zeroPad: 3
  }),
  frameRate: 10,
  repeat: -1
});
anims.create({
  key: "ariel-right-walk",
  frames: anims.generateFrameNames("atlas", {
    prefix: "ariel-right-walk.",
    start: 0,
    end: 3,
    zeroPad: 3
  }),
  frameRate: 10,
  repeat: -1
});
// etc for the rest of the animations...

```

Is there any way around this?  
Thanks in advance

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [July 17, 2021, 5:35pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/2 "2021-07-17T17:35:17Z")

</div>

I would avoid scaling the sprite at all.

Turn on `pixelArt` in the game config.

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 17, 2021, 8:24pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/3 "2021-07-17T20:24:30Z")

</div>

`pixelArt` is on. Here’s my current game config:

```javascript
const config = {
  type: Phaser.AUTO,
  scale: {
    // mode: Phaser.Scale.NONE,
    mode: Phaser.Scale.RESIZE,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    parent: "game-container",
  },
  parent: "game-container",
  pixelArt: true,
  physics: {
    default: "arcade",
    arcade: {
      debug: true, // Remove in production
      // debug: false,
      gravity: { y: 0 }
    }
  },
  scene: [SceneA, SceneB, SceneC]
};

const game = new Phaser.Game(config);

```

---

<div class="post-metadata">

**Author:** ![BlunT76](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/blunt76/32/1454_2.png) [@BlunT76](https://phaser.discourse.group/u/BlunT76)\
**Post date:** [July 17, 2021, 10:02pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/4 "2021-07-17T22:02:46Z")

</div>

> [@ariroffe](#):
>
> `mode: Phaser.Scale.RESIZE,`

Try with Phaser.Scale.FIT

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 17, 2021, 10:17pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/5 "2021-07-17T22:17:23Z")

</div>

It’s the same. I tried `Phaser.Scale.FIT`, `Phaser.Scale.RESIZE`, `Phaser.Scale.NONE` and `Phaser.Scale.ENVELOP`. All result in the same problem.

---

<div class="post-metadata">

**Author:** ![BlunT76](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/blunt76/32/1454_2.png) [@BlunT76](https://phaser.discourse.group/u/BlunT76)\
**Post date:** [July 17, 2021, 10:31pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/6 "2021-07-17T22:31:02Z")

</div>

So the problem isn’t related to Phaser.Scale, put it to NONE until you find the problem.  
Paste your atlas.json here (just in case)  
What is the size of your canvas in phaser config ?  
I usually use this config:

```javascript
const config = {
  type: Phaser.AUTO,
  width: 640,
  height: 480,
  pixelArt: true,
  scale: {
    parent: 'game-container',
    mode: Phaser.Scale.HEIGHT_CONTROLS_WIDTH,
    autoRound: true,
    autoCenter: Phaser.DOM.CENTER_BOTH,
  },
  physics: {
    default: 'arcade',
    arcade: {
      tileBias: 20, // for 16x16 tile size
      gravity: { y: 600 }, 
      debug: true,
      debugShowBody: true,
      debugShowStaticBody: true,
    },
  },
  scene: [SceneA, SceneB, SceneC],
};

```

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [July 17, 2021, 11:24pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/7 "2021-07-17T23:24:05Z")

</div>

Remove `setSize(32, 41)` and any other sprite scaling.

Does the Phaser banner in the console show Canvas or WebGL?

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 18, 2021, 12:46am UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/8 "2021-07-18T00:46:40Z")

</div>

Ok, so I tried:

- Setting the scale mode to `NONE`
- Explicitly adding a height and width of 640 x 480 to the game config
- Adding `autoRound:true`
- Removing `setSize`

The problem persists 😓  
The console shows `Phaser v3.54.0 (WebGL | Web Audio) https://phaser.io`

Here’s my full atlas.json:

```javascript
{"frames": {

"ariel-front":
{
	"frame": {"x":32,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-front-walk.000":
{
	"frame": {"x":0,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-front-walk.001":
{
	"frame": {"x":32,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-front-walk.002":
{
	"frame": {"x":64,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-front-walk.003":
{
	"frame": {"x":32,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-back":
{
	"frame": {"x":96,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-back-walk.000":
{
	"frame": {"x":96,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-back-walk.001":
{
	"frame": {"x":96,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-back-walk.002":
{
	"frame": {"x":128,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-back-walk.003":
{
	"frame": {"x":96,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-left":
{
	"frame": {"x":128,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-left-walk.000":
{
	"frame": {"x":0,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-left-walk.001":
{
	"frame": {"x":128,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-left-walk.002":
{
	"frame": {"x":32,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-left-walk.003":
{
	"frame": {"x":128,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-right":
{
	"frame": {"x":160,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-right-walk.000":
{
	"frame": {"x":64,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":64}
},
"ariel-right-walk.001":
{
	"frame": {"x":160,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-right-walk.002":
{
	"frame": {"x":160,"y":0,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
},
"ariel-right-walk.003":
{
	"frame": {"x":160,"y":41,"w":32,"h":41},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":32,"h":41},
	"sourceSize": {"w":32,"h":41}
}
},
"meta": {
	"image": "atlas.png",
	"format": "RGBA8888",
	"size": {"w":192,"h":82},
	"scale": "1"
}

}

```

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 18, 2021, 12:56am UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/9 "2021-07-18T00:56:04Z")

</div>

Using scale mode `Phaser.Scale.HEIGHT_CONTROLS_WIDTH` makes it less noticeable, but it still does persist as well

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [July 18, 2021, 4:32pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/10 "2021-07-18T16:32:57Z")

</div>

> [@ariroffe](#):
>
> Ok, so I tried:
> 
> - Setting the scale mode to `NONE`
> - Explicitly adding a height and width of 640 x 480 to the game config
> - Adding `autoRound:true`
> - Removing `setSize`
> 
> The problem persists 😓

There should be no distortion here. `pixelArt` is on? The sprite scale isn’t changed at all?

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 19, 2021, 4:09pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/11 "2021-07-19T16:09:56Z")

</div>

Ok, I think I managed to pinpoint the issue. I went back to basics and created simple test example. I made a new tileset consisting only of a single 32 x 32 tile, which is this:

![grass_tile](https://global.discourse-cdn.com/free1/uploads/phaser1/original/2X/b/b2e292225cf1676d2a85e5b36ee982f64972cf49.png)

And a new 2 tile x 2 tile tilemap in Tiled that has just 4 copies of that tile in a single layer. I used the same atlas as before, which has a 32 x 41 sprite.

The HTML file:

```javascript
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test</title>
  </head>
  <body>
    <div id="game-container"></div>
    <script src="//cdn.jsdelivr.net/npm/phaser@3.54.0/dist/phaser.js"></script>
    <script src="./index.js" type="module"></script>
  </body>
</html>

```

The index.js file:

```javascript
class SceneA extends Phaser.Scene {
  constructor() {
    super("SceneA");
  }
  
  preload() {
	this.load.image("tileset", "./assets/test/grass_tile.png");
    this.load.tilemapTiledJSON("tilemap", "./assets/test/grass.json");
    this.load.atlas("atlas", "./assets/prod/atlas/atlas.png", "./assets/prod/atlas/atlas.json");
  }
  
  create() {
  this.map = this.make.tilemap({key: "tilemap"});
  const tileset = this.map.addTilesetImage("test_tileset", "tileset");
  const groundLayer = this.map.createLayer("Layer1", tileset, 0, 0);
  this.player = this.physics.add.sprite(31, 38, "atlas", "ariel-front");
  }
}

const config = {
  type: Phaser.AUTO,
  pixelArt: true,
  scale: {
    mode: Phaser.Scale.NONE,
    autoRound: true,
    autoCenter: Phaser.Scale.NO_CENTER,
    zoom: Phaser.Scale.NO_ZOOM,
    parent: "game-container",
    width: 64,
    height: 64,
  },
  physics: {
    default: "arcade",
    arcade: {
      debug: false,
      gravity: { y: 0 }
    }
  },
  scene: [SceneA]
};

const game = new Phaser.Game(config);

```

This is what I get:

![bug2](https://global.discourse-cdn.com/free1/uploads/phaser1/original/2X/d/da150b7777f3f1803f3bf733933bb6f7fef167c1.png)

Notice that the sprite is still deformed. BUT, i also noticed that the map square is not 64 x 64 screen pixels, but 80 x 80 screen pixels. Moreover, if I query `window.devicePixelRatio` in the console, it returns 1.25 (64 x 1.25 = 80). So I assume that what is happening is that Phaser is sizing the map to 64 x 64 **CSS pixels** , which forces it to scale the sprite and thus deform it.

I tried adding:

```javascript
<meta name="viewport" content="initial-scale=1, maximum-scale=1"/>

```

to the HTML head but this doesn’t seem to fix the issue.

Any tips on how to solve this?  
Thanks!

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [July 19, 2021, 11:06pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/12 "2021-07-19T23:06:23Z")

</div>

Reset the page zoom.

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 20, 2021, 3:35pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/13 "2021-07-20T15:35:09Z")

</div>

Ok, adding a script with `document.body.style.zoom = 1 / window.devicePixelRatio;` fixed the zooming issue.

But now I have a new problem, which is that pointer clicks are being registered in the wrong x and y coordinates.

```javascript
update(time, delta) {
  // ...
  let pointer = this.input.activePointer;
  if (pointer.primaryDown) {
    let pointerPosition = this.cameras.main.getWorldPoint(pointer.x, pointer.y);
    console.log(Math.floor(this.player.y), Math.floor(pointer.position.y), Math.floor(pointerPosition.y));
  }
  // ...
}

```

Clicking on the player prints, for example, `1061 621 915`

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [July 20, 2021, 3:42pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/14 "2021-07-20T15:42:09Z")

</div>

I mean in the Chrome **View** menu, do **Actual Size**.

Don’t change `body.style`.

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 20, 2021, 3:51pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/15 "2021-07-20T15:51:13Z")

</div>

But the zoom in Chrome was already set to 100%. I can manually change it to 80% and it will look ok, but that is not a solution, I cannot ask visitors to my site to adjust their browser zoom. The problem happens in Firefox as well. And in mobile devices the CSS pixel vs screen pixel ratio will almost never be 1, which wil make Phaser scale the game as well.

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [July 20, 2021, 4:30pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/16 "2021-07-20T16:30:43Z")

</div>

If you need to handle DPR you can add `{ zoom: 1 / devicePixelRatio }`.

---

<div class="post-metadata">

**Author:** ![ariroffe](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@ariroffe](https://phaser.discourse.group/u/ariroffe)\
**Post date:** [July 20, 2021, 5:32pm UTC](https://phaser.discourse.group/t/scaling-is-deforming-sprite-from-atlas/9969/17 "2021-07-20T17:32:17Z")

</div>

This works for me, but not with scale mode set to Phaser.Scale.RESIZE. Since I want the game to cover the entire screen, I ended up doing:

```javascript
{
  mode: Phaser.Scale.NONE,
  width: window.innerWidth * window.devicePixelRatio,
  height: window.innerHeight * window.devicePixelRatio,
  zoom: 1 / window.devicePixelRatio,
}

```

I’ll also have to resize the game each time the screen is resized. Do you think this is acceptable?  
Thank you for all your help!!! 😊
