Background
I size everything using viewport units:
body {
font-size: calc((1vw + 1vh) / 2);
}
h6 {
font-size: 1em;
}
div {
width: 20em;
}
As the number of pixels in the screen increases, so will the size of units. For example, a 1920 x 1080 display will have smaller type than a 2560 x 1080 display. This allows automatic support of ultra-wide, vertical, and high DPI (8k or even 16K) displays without media queries.
Problem
Using Three.js, object scale responds only to the height of the screen. The object will appear the same size on a 1920x1080 monitor as it is on a 2560x1080 monitor. This is because Three.js camera uses a vertical field of view (FOV).
Default Behaviour - 2560x1080 compared to 1080x1080. Notice, the text becomes smaller, but the 3D object stays the same size. codepen example
My Attempt
The reason Three.js only responds to height is because it uses a vertical-fov. I tried to change the vertical-fov to diagonal-fov using this formula I found on stackOverflow here.
var height = window.innerHeight;
var width = window.innerWidth;
var distance = 1000;
var diag = Math.sqrt((height*height)+(width*width))
var fov = 2 * Math.atan((diag) / (2 * distance)) * (180 / Math.PI);
camera = new THREE.PerspectiveCamera(fov , width / height, 1, distance * 2);
camera.position.set(0, 0, distance);
The resulting behavior is the opposite of what should happen.
- On a smaller screen the object becomes larger.
- On a larger screen the object becomes smaller.
current results
Objects in Three.js only become larger when increasing the viewport height. I attempted to modify the default vertical-fov to a diagonal-fov. However, this did not work.
desired results
When the viewport is resized, the object should change perceived size based on the formula ((viewport height + viewport width) / 2). This will ensure and text placed on the page remains the same relative scale to 3D objects. I would like to achieve this by altering the camera, instead of the 3D objects themselves.