如何使 THREE.js 视图适合 canvas 大小?

How can I fit THREE.js view to canvas size?

我想将元素拖放到鼠标位置。 为此,我需要将 THREE.js space“同步”到 canvas 大小({0,0} 坐标位于屏幕中间)。 所以假设我的元素的宽度为 500px,如果我用鼠标坐标 x = 500 放置一个元素,那么对象 x 坐标应该是 x = 250。 此时我正在使用 PerspectiveCamera.

我依靠this tutorial的解释并进行了计算以使fov(视野)边界与绿线的边界相交(在示例圆高度中,在我的例子中canvas宽度)

这是我到目前为止所做的基于相机 z 位置计算 fov 的方法(主要使用毕达哥拉斯)。

  calculateFOV(z:number){
    const b = z;
    const a = this.width / 2;
    const c = Math.sqrt((a**2) + (b**2));
    const cosa =  a / c;
    let angle = (Math.acos(cosa) * (180 / Math.PI));
    let resAngle = 180 - 90 - angle
    return (resAngle * 2);
  }

...

const zPosition = 40;
const fov = this.calculateFOV(zPosition);
this.camera = new THREE.PerspectiveCamera( fov, this.width / this.height, 10,  zPosition);

但它没有按预期工作。

如果您需要更多详细信息,请告诉我。

您的模型(线条?)宽度为 W,高度为 H。
假设相机在 Z.
canvas 的宽度为 w,高度为 h。
THREE.jsfov是基于身高的。

您需要比较模型的纵横比与 canvas。

if ((W/H) < (w/h)) then fov = 2*atan2(H/2, Z);
else                    fov = 2*atan2(W*h/w/2, Z);

(是的,THREE.js 相机 fov 需要度数)

(这让我对自己的工作有了一些信心:)

If the canvas aspect ratio is 4/3, H=30, W<40, Z=100, then  
  (W/H)<(4/3) and fov = 2*atan2(30/2, 100);  
If the canvas aspect ratio is 4/3, W=40, H<30, Z=100, then  
  (W/H)>(4/3) and fov = 2*atan2(40*3/4/2, 100);

我这样做成功了:

  calculateFOV(z:number){
    const b = z;
    //scaling mid base of fov triangle to aspect ratio
    const a = ((this.width / 2 ) / (this.width / this.height));
    //pythagore
    const c = Math.sqrt((a**2) + (b**2));
    //cosine of angle
    const cosa = a / c;
    //invert cosine to degrees
    const angle = Math.acos(cosa) * (180 / Math.PI);
    //angle left multiplied by 2
    let resAngle = (90 - angle) * 2
    return (resAngle);
  }

z = this.width

不能真正理解它,但它通过将中间基础缩放到纵横比来工作。