# How to manipulate isometric / orthographic camera to keep content onscreen and optimally scaled?

**URL:** https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269
**Category:** Questions
**Tags:** camera, orthographic
**Created:** [October 31, 2022, 6:08am UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269 "2022-10-31T06:08:08Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![mikeysee](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/mikeysee/32/27714_2.png) [@mikeysee](https://forum.babylonjs.com/u/mikeysee)
#### Post date: [October 31, 2022, 6:08am UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/1 "2022-10-31T06:08:08Z")

</div>

[https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/a/8/a81965e8ec8ec8f4e4fe397ef0d76e742dbca85d.mp4](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/a/8/a81965e8ec8ec8f4e4fe397ef0d76e742dbca85d.mp4)

Hey sorry no playground but you can see from the above video we have an isometric world using an orthographic camera.

We would like it so that the board always stays visible on the screen at all times (with a little padding around the outside) but also optimally takes up the optimal amount of space on the screen it can.

I have already tinkered with it quite a bit to get it to where it is able to always keep it visible and is optimal in the vertical dimension but as you can see when the window shrinks horizontally it grows a bunch of padding on the left and right hand side which should not be needed.

Code is really messy but here is the method im currently using (cobbled together from various sources)

```nohighlight
export interface OrthographicCameraSettings {
  minHeight: number;
  maxHeight: number;
  scaleFactor: number;
  aspectMultiplier: number;
}

export class OrthographicCamera {
  constructor(private scene: Scene, public settings: OrthographicCameraSettings) {}

  calculateZoom() {
    const rect = ensure(this.scene.getEngine().getRenderingCanvasClientRect());
    const aspect = rect.height / rect.width;

    const zoom =
      ((rect.width * 0.001) /
        clamp(rect.height, this.settings.minHeight, this.settings.maxHeight)) *
      this.settings.scaleFactor;

    const constrained = clamp(zoom, aspect * this.settings.aspectMultiplier, 20);

    return constrained;
  }

  updateCamera(camera: ArcRotateCamera) {
    const zoom = this.calculateZoom();

    const rect = ensure(this.scene.getEngine().getRenderingCanvasClientRect());
    const aspect = rect.height / rect.width;

    camera.orthoLeft = -camera.radius * zoom;
    camera.orthoRight = camera.radius * zoom;
    camera.orthoBottom = -camera.radius * aspect * zoom;
    camera.orthoTop = camera.radius * aspect * zoom;
  }
}

```

---

<div class="post-metadata">

### Author: ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)
#### Post date: [October 31, 2022, 11:48am UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/2 "2022-10-31T11:48:01Z")

</div>

Here’s how I would do it:

> **[Babylon.js Playground](https://playground.babylonjs.com/#ZJ8S6X%232)**
>
> Babylon.js playground is a live editor for Babylon.js WebGL 3D scenes

It tries to use the maximum space in the X dimension by keeping the right aspect ratio and same thing for the Y dimension. It needs the scene X and Y world extents and is computed in `computeSceneBounds` in the PG. Note that it needs the extents as seen by the camera, so the world extents of the meshes are transformed by the camera view matrix.

If you move (rotate) the camera in the PG, hit “Enter” to recompute the new extents and to fit the display in the screen.

---

<div class="post-metadata">

### Author: ![mikeysee](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/mikeysee/32/27714_2.png) [@mikeysee](https://forum.babylonjs.com/u/mikeysee)
#### Post date: [November 1, 2022, 5:50am UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/3 "2022-11-01T05:50:30Z")

</div>

Wow!!! This is absolutely perfect! Thankyou so much 😃

---

<div class="post-metadata">

### Author: ![Silver](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/silver/32/31136_2.png) [@Silver](https://forum.babylonjs.com/u/Silver)
#### Post date: [October 9, 2023, 3:14pm UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/4 "2023-10-09T15:14:57Z")

</div>

i tried using the same code structure, but it wouldn’t work for me. I want to be able to use it for ArcRotateCamera.

---

<div class="post-metadata">

### Author: ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)
#### Post date: [October 9, 2023, 3:40pm UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/5 "2023-10-09T15:40:28Z")

</div>

The PG already uses an arc rotate camera. It is created by the `scene.createDefaultCamera(true, true, true);` call, the camera created line 6 is not used.

---

<div class="post-metadata">

### Author: ![Lemcat](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/lemcat/32/44469_2.png) [@Lemcat](https://forum.babylonjs.com/u/Lemcat)
#### Post date: [January 3, 2025, 6:45pm UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/6 "2025-01-03T18:45:14Z")

</div>

I’m just wondering why this code doesn’t work correctly with a rotation of an object similar to this:

 ![Screenshot_2025-01-03-21-42-41-323_com.android.chrome-edit](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/f/c/fcbc26306a9bf637d1b455264c53547f91f80c6a.jpeg)

In other rotations looks it works great!

Chrome, Android 13.

---

<div class="post-metadata">

### Author: ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)
#### Post date: [January 5, 2025, 1:10pm UTC](https://forum.babylonjs.com/t/how-to-manipulate-isometric-orthographic-camera-to-keep-content-onscreen-and-optimally-scaled/35269/7 "2025-01-05T13:10:31Z")

</div>

I’m not sure why it doesn’t correctly fill the screen…  
One thing I think is wrong is the calculation of the margin, which should be something like:

```typescript
    const f = 0.1; // 10% margin
    const d = max.subtract(min).scaleInPlace(f / 2);
    min.subtractInPlace(d);
    max.addInPlace(d);

```
