[Beginner] Get Perspective Camera to scale horizontally on Window Resize

Hey all,

This post ( Resize window in OrthographicCamera - #2 by Mugen87 ) helped me ultimately figure out how to accomplish the same with Orthographic Camera. Thanks Mugen!

My goal is to get my models to scale proportionally when I shrink the window size horizontally.
I think that Perspective Camera does this — vertically — by default.

The closest page that I think has the answer is javascript - How to Fit Camera to Object - Stack Overflow … but I’m unsure on how to get this to work. Seems that altering the FOV is important.
fov = 2 * Math.atan( ( width / aspect ) / ( 2 * dist ) ) * ( 180 / Math.PI );

The “dist” is apparently the “closest distance to the object”. However, I’m unsure on how to get the camera’s position to do so.

Here’s my full code, if desired. So far, my models are rendering. When I shrink my browser horizontally, nothing resizes, though. Unsure how to get the bolded equation above into CAMERA and/or onWindowResize().

Thanks,
~DH

// IMPORTS
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { GUI } from 'dat.gui'
import Stats from 'three/examples/jsm/libs/stats.module'

// TIME SAVE
    var Bond_Scale = 1.35;
    var Coin_Scale = 1.5;
    // var OlmLight_Intensity = 1.8;
    var ElseLightAmbient_Intensity = 3.1;
    var ElseLightDirect_Intensity = 3.8;
    // var Olm_Model = 'models/layer0_olm.glb';
    var Bond_Model = 'models/layer1_bond.glb';
    var Coin_Model = 'models/layer1_coin.glb';

// SCENE SETUP
    const scene = new THREE.Scene()
    //scene.background = new THREE.Color( 0x000000 );
    scene.add(new THREE.AxesHelper(5))
    const stats = Stats()
    document.body.appendChild(stats.dom)

// CAMERA
    var aspect = window.innerWidth / window.innerHeight;
    
    const camera_else = new THREE.PerspectiveCamera( 
        80,         // FOV
        aspect,     // Aspect Ratio
        0.1,        // Near
        1000        // Far
        )
    
    camera_else.layers.set(1);
    camera_else.position.set(0, 1.7, 2.3)


// RESIZEABLE
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    // PERSPECTIVE CAMERA 
        
    var aspect = window.innerWidth / window.innerHeight;
        
        camera_else.fov = 80;
        camera_else.aspect = aspect;
        camera_else.near = 0.1;
        camera_else.far = 1000;
        
        camera_else.updateProjectionMatrix()

        renderer.setSize(window.innerWidth, window.innerHeight)
        render()
}

// LIGHT
    var else_light_ambient = new THREE.AmbientLight( 0xffffff, 0.4 );
    else_light_ambient.layers.set(1);
    scene.add( else_light_ambient );

    var else_light_dirLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
    else_light_dirLight.layers.set(1);
    scene.add( else_light_dirLight );

// RENDERER
    const renderer = new THREE.WebGLRenderer( { antialias: true } )
    renderer.physicallyCorrectLights = true
    renderer.setSize(window.innerWidth, window.innerHeight)
    document.body.appendChild(renderer.domElement)

// USER INTERACTION
    const controls = new OrbitControls(camera_else, renderer.domElement)
    controls.enableDamping = true
    controls.target.set(0, 1, 0)

// DATGUI
    const gui = new GUI()
    const cameraFolder = gui.addFolder('Camera')
    cameraFolder.add(camera_else.position, 'x', 0, 10)
    cameraFolder.add(camera_else.position, 'y', 0, 10)
    cameraFolder.add(camera_else.position, 'z', 0, 10)
    cameraFolder.open()


// ELSE AMBIENT & DIRECT
    const elselightFolder = gui.addFolder('THREE.ElseLight')
        else_light_ambient.intensity = ElseLightAmbient_Intensity;
        const data_ambient = { color: else_light_ambient.color.getHex(), mapsEnabled: true }
        elselightFolder.addColor(data_ambient, 'color').onChange(() => {
        else_light_ambient.color.setHex(Number(data_ambient.color.toString().replace('#', '0x')))})
        elselightFolder.add(else_light_ambient, 'intensity', 0, 10, 0.1)

        else_light_dirLight.intensity = ElseLightDirect_Intensity;
        const data_direct = { color: else_light_dirLight.color.getHex(), mapsEnabled: true }
        elselightFolder.addColor(data_direct, 'color').onChange(() => {
        else_light_dirLight.color.setHex(Number(data_direct.color.toString().replace('#', '0x')))})
        elselightFolder.add(else_light_dirLight, 'intensity', 0, 10, 0.1)
        elselightFolder.open()


// ------------- GLTF MODELS -------------- //

// BOND .GLB
const BOND_Rotate = new THREE.Object3D( );
const BOND_loader = new GLTFLoader( );
BOND_loader.load( Bond_Model, 
    ( gltf ) => {
        const box = new THREE.Box3( ).setFromObject( gltf.scene );
        const center = box.getCenter( new THREE.Vector3( ) );
        const size = box.getSize( new THREE.Vector3( ) ); 
        gltf.scene.position.set( -center.x, size.y / 2 - center.y, -center.z );
        
        BOND_Rotate.add( gltf.scene );
        BOND_Rotate.scale.set( Bond_Scale, Bond_Scale, Bond_Scale );
        
        BOND_Rotate.position.x = -1.0;  // Bond X-coord
        BOND_Rotate.position.y = 0.6;   // Bond Y-coord
        BOND_Rotate.position.z = 0.4;   // Bond Z-coord

        gltf.scene.traverse( function ( child ) {
            child.layers.set(1);        // Bond in LAYER 1
        })

        scene.add( BOND_Rotate );
	});
    
// COIN .GLB
const COIN_Rotate = new THREE.Object3D( );
const COIN_loader = new GLTFLoader();
COIN_loader.load( Coin_Model,
    ( gltf ) => {
        const box = new THREE.Box3( ).setFromObject( gltf.scene );
        const center = box.getCenter( new THREE.Vector3( ) );
        const size = box.getSize( new THREE.Vector3( ) ); 
        gltf.scene.position.set( -center.x, size.y / 2 - center.y, -center.z );

        COIN_Rotate.add( gltf.scene );
        COIN_Rotate.scale.set( Coin_Scale, Coin_Scale, Coin_Scale );
        
        COIN_Rotate.position.x = 1.20;  // Coin X-coord
        COIN_Rotate.position.y = 0.58;  // Coin Y-coord
        COIN_Rotate.position.z = 0.4;   // Coin Z-coord

        gltf.scene.traverse( function ( child ) {
            child.layers.set(1);        // Coin in LAYER 1
        })

        scene.add( COIN_Rotate );
	});

// ANIMATE
function animate() {
    requestAnimationFrame(animate)
    controls.update()
    render()
    stats.update()

    BOND_Rotate.rotation.y += 0.01;     // Rotate Bond around its Y-axis
    COIN_Rotate.rotation.y += 0.01;     // Rotate Coin around its Y-axis

}

function render() { renderer.render(scene, camera_else) }
animate()