I want my 3d objects to always "fit" inside the window This is how my code currently looks like
export function onWindowResize(camera, renderer) {
const canvas = renderer.domElement;
const width = window.innerWidth;
const height = window.innerHeight;
const connection = getBoundingBox(connectionGroup);
const needResize = canvas.width !== width || canvas.height !== height;
const isPortrait = connection.width < connection.height;
if (needResize) renderer.setSize(width, height);
const aspect = isPortrait ? width / height : height / width;
const frustumSize = Math.max(connection.width, connection.height);
//Front View
if (isPortrait) {
camera.left = (-frustumSize * aspect) / 2;
camera.right = (frustumSize * aspect) / 2;
camera.top = frustumSize / 2;
camera.bottom = -frustumSize / 2;
} else {
camera.left = -frustumSize / 2;
camera.right = frustumSize / 2;
camera.top = (frustumSize * aspect) / 2;
camera.bottom = (-frustumSize * aspect) / 2;
}
camera.updateProjectionMatrix();
}
Currently, everything works as expected: the object fits in the window based on its height or width. A problem occurs if the object's height exceeds the window height but still fits within the maximum width (vice-versa), causing the model to be cropped.
I only need to fit the object on the initial display, user can perform orbit controls freely after that
MAX WIDTH but models height exceed window/camera height
I tried manually setting camera.zoom
, but even then, I couldn't figure out the right value for it. After that, my orbit controls stopped functioning.
Calculations should account for a special case when the ratio of window
dimensions (aspect
) is less than the ratio of connection
dimensions (frustumAspect
). The frustumSize
should be scaled to reflect that difference (frustumScaled
).
Optionally, camera.left
and camera.bottom
can be simplified by negating the opposite properties.
const frustumAspect = isPortrait ? (connection.width / connection.height) :
(connection.height / connection.width);
const aspectScale = Math.max(frustumAspect / aspect, 1);
const frustumScaled = frustumSize * aspectScale;
//Front View
if (isPortrait) {
camera.right = (frustumScaled * aspect) / 2;
camera.top = frustumScaled / 2;
} else {
camera.right = frustumScaled / 2;
camera.top = (frustumScaled * aspect) / 2;
}
camera.left = -camera.right;
camera.bottom = -camera.top;