maiermic
maiermic

Reputation: 4984

How to fit the viewport centered to the scene in CraftyJS?

I'd like to show the whole scene (static size) and center it, i.e. I have to zoom/scale and move the viewport according to the window size. Depending on the aspect ratio, I scale either to fit the width or the height. Then I centerOn the scene

const heightScale = Crafty.viewport.height / staticSceneHeight
const widthScale = Crafty.viewport.width / staticSceneWidth
if (heightScale < widthScale) {
  Crafty.viewport.scale(heightScale)
} else {
  Crafty.viewport.scale(widthScale)
}
Crafty.viewport.centerOn(scene, 0)

Scaling works, but the scene is not centered correctly. See this example:

const staticSceneWidth = 640
const staticSceneHeight = 960
Crafty.init()
Crafty.background('rgb(127,127,127)')
// grid of four rectangles
// top left
Crafty.e('2D, Canvas, Color, Fourway')
  .attr({ x: 0, y: 0, w: 320, h: 480 })
  .color('red')
// top right
Crafty.e('2D, Canvas, Color, Fourway')
  .attr({ x: 320, y: 0, w: 320, h: 480 })
  .color('green')
// bottom left
Crafty.e('2D, Canvas, Color, Fourway')
  .attr({ x: 0, y: 480, w: 320, h: 480 })
  .color('blue')
// bottom right
Crafty.e('2D, Canvas, Color, Fourway')
  .attr({ x: 320, y: 480, w: 320, h: 480 })
  .color('yellow')
// dummy for centering
const scene = Crafty.e('2D').attr({ x: 0, y: 0, w: 640, h: 960 })

function fitViewportToScene() {
  const heightScale = Crafty.viewport.height / staticSceneHeight
  const widthScale = Crafty.viewport.width / staticSceneWidth
  if (heightScale < widthScale) {
    Crafty.viewport.scale(heightScale)
  } else {
    Crafty.viewport.scale(widthScale)
  }
  Crafty.viewport.centerOn(scene, 0)
}

window.onresize = fitViewportToScene

fitViewportToScene()
body,
html {
  margin: 0;
  padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.9.0/crafty.js"></script>

screenshot of scene that is not centered correctly

Why is the scene not centered correctly? How to center it correctly?


Crafty.JS 0.9.0

Upvotes: 0

Views: 52

Answers (1)

maiermic
maiermic

Reputation: 4984

I don't understand the behavior of centerOn, if it is intended or a bug, but I found a workaround. I calculate the viewport x-/y-coordinate manually. Therefore, I scale the viewport dimension using the current scale. Just replace centerOn in the example with

function centerOnScene() {
  const scaledViewportWidth = Crafty.viewport.width / Crafty.viewport._scale;
  Crafty.viewport.x = Math.abs(staticSceneWidth - scaledViewportWidth) / 2;
  const scaledViewportHeight = Crafty.viewport.height / Crafty.viewport._scale;
  Crafty.viewport.y = Math.abs(staticSceneHeight - scaledViewportHeight) / 2;
}

const staticSceneWidth = 640;
const staticSceneHeight = 960;
Crafty.init();
Crafty.background("rgb(127,127,127)");
// grid of four rectangles
// top left
Crafty.e("2D, Canvas, Color, Fourway")
  .attr({ x: 0, y: 0, w: 320, h: 480 })
  .color("red");
// top right
Crafty.e("2D, Canvas, Color, Fourway")
  .attr({ x: 320, y: 0, w: 320, h: 480 })
  .color("green");
// bottom left
Crafty.e("2D, Canvas, Color, Fourway")
  .attr({ x: 0, y: 480, w: 320, h: 480 })
  .color("blue");
// bottom right
Crafty.e("2D, Canvas, Color, Fourway")
  .attr({ x: 320, y: 480, w: 320, h: 480 })
  .color("yellow");

function centerOnScene() {
  const scaledViewportWidth = Crafty.viewport.width / Crafty.viewport._scale;
  Crafty.viewport.x = Math.abs(staticSceneWidth - scaledViewportWidth) / 2;
  const scaledViewportHeight = Crafty.viewport.height / Crafty.viewport._scale;
  Crafty.viewport.y = Math.abs(staticSceneHeight - scaledViewportHeight) / 2;
}

function fitViewportToScene() {
  const heightScale = Crafty.viewport.height / staticSceneHeight;
  const widthScale = Crafty.viewport.width / staticSceneWidth;
  if (heightScale < widthScale) {
    Crafty.viewport.scale(heightScale);
  } else {
    Crafty.viewport.scale(widthScale);
  }
  centerOnScene();
}

window.onresize = fitViewportToScene;

fitViewportToScene();
body,
html {
  margin: 0;
  padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/crafty/0.9.0/crafty.js"></script>

Upvotes: 0

Related Questions