简体   繁体   English

如何使 Three.js FOV 响应高度和宽度?

[英]How to make Three.js FOV responsive to height AND width?

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.例如,1920 x 1080 显示器的字体比 2560 x 1080 显示器的字体小。 This allows automatic support of ultra-wide, vertical, and high DPI (8k or even 16K) displays without media queries.这允许在没有媒体查询的情况下自动支持超宽、垂直和高 DPI(8k 甚至 16K)显示。

Problem问题

Using Three.js, object scale responds only to the height of the screen.使用 Three.js,对象缩放仅响应屏幕高度。 The object will appear the same size on a 1920x1080 monitor as it is on a 2560x1080 monitor.该对象在 1920x1080 显示器上的显示大小与在 2560x1080 显示器上的大小相同。 This is because Three.js camera uses a vertical field of view (FOV).这是因为 Three.js 相机使用垂直视野 (FOV)。

Default Behaviour - 2560x1080 compared to 1080x1080.默认行为- 2560x1080 与 1080x1080 相比。 Notice, the text becomes smaller, but the 3D object stays the same size .请注意,文本变小了,但 3D 对象的大小保持不变 codepen example代码笔示例

2560x10801080x1080

My Attempt我的尝试

The reason Three.js only responds to height is because it uses a vertical-fov. Three.js 只响应高度的原因是因为它使用了一个垂直视角。 I tried to change the vertical-fov to diagonal-fov using this formula I found on stackOverflow here .我尝试使用我在 stackOverflow here上找到的这个公式将垂直 fov 更改为对角 fov。

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.由此产生的行为与应该发生的行为相反。

current results当前结果

Objects in Three.js only become larger when increasing the viewport height. Three.js 中的对象只会在增加视口高度时变大。 I attempted to modify the default vertical-fov to a diagonal-fov.我试图将默认的垂直 fov 修改为对角线 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).调整视口大小时,对象应根据公式((视口高度 + 视口宽度)/ 2)更改感知大小。 This will ensure and text placed on the page remains the same relative scale to 3D objects.这将确保放置在页面上的文本与 3D 对象保持相同的相对比例。 I would like to achieve this by altering the camera, instead of the 3D objects themselves.我想通过改变相机而不是 3D 对象本身来实现这一点。

You should create a scale ratio based on the width or height of the screen.您应该根据屏幕的宽度或高度创建缩放比例。 For example:例如:

SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;

if(SCREEN_WIDTH > {something} && SCREEN_WIDTH < {something}){
    camera.fov = SCREEN_WIDTH / {something}; //This is your scale ratio.
};

//Repeat for window.innerHeight or SCREEN_HEIGHT.

if(SCREEN_HEIGHT > {something} && SCREEN_HEIGHT < {something}){
    camera.fov = SCREEN_HEIGHT / {something}; //This is your scale ratio for height, it could be same as window.innerWidth if you wanted.
};

//Updating SCREEN_WIDTH and SCREEN_HEIGHT as window resizes.

window.addEventListener('resize', onResize, false); //When window is resized, call onResize() function.

function onResize() {
    SCREEN_WIDTH = window.innerWidth; //Re-declaring variables so they are updated based on current sizes.
    SCREEN_HEIGHT = window.innerHeight;

    camera.aspect = window.innerWidth / window.innerHeight; //Camera aspect ratio.
    camera.updateProjectionMatrix(); //Updating the display
    renderer.setSize(window.innerWidth, window.innerHeight) //Setting the renderer to the height and width of the window.
};

Hope this helps!希望这可以帮助! Let me know if you still have any questions如果您还有任何问题,请告诉我

-Anayttal -阿奈塔尔

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM