How do we scale the PlaneGeometry based on the aspect ratio

Hi there!

We are currently working on scaling, moving, and rotating an image in our viewer using TransformControls. The viewer has a simple setup that includes an orthographic camera and OrbitControls for easy panning and zooming.

However, we’ve noticed that scaling the PlaneGeometry where the image texture is located causes the image to stretch out. We’re wondering if there’s a way to maintain the aspect ratio and prevent any stretching.

    const loader = new TextureLoader();

    const texture = loader.load('/grote-tekening.jpg');
    const material = new MeshBasicMaterial({map: texture, color: 0xffffff, transparent: true, opacity: 0.5});
    const geometry = new PlaneGeometry(8000 / 7, 4485 / 7);
    const mesh = new Mesh(geometry, material);

    mesh.position.set(0, 0, 0);
    mesh.rotation.x = -Math.PI / 2;


    const control = new TransformControls(, ModelManager.instance._renderer.domElement);

    control.axis = "XY";

    control.addEventListener('dragging-changed', event => {
      if (ModelManager.instance.cameraController.orbitController !== undefined)
        ModelManager.instance.cameraController.orbitController.orbitControls.enabled = !event.value;

    window.addEventListener('keydown', function (event) {
      switch (event.code) {
        case "KeyW":

        case "KeyE":

        case "KeyR":


fork yourself dreis image component GitHub - pmndrs/drei: 🥉 useful helpers for react-three-fiber

it does exactly that, it’s a css cover implementation that fits any texture on any plane any dimension. for instance like this

the code is here, it’s mostly just a three.shadermaterial so very easy to port drei/Image.tsx at d4e7f638f42b4a6a6bda175cfcc025c4c9e68c7e · pmndrs/drei · GitHub

the raw math is from here CSS-style `background-size: cover` for an image texture in a GLSL shader · GitHub

Thank you very much for the reply! I’ll take a look at it.