【问题标题】:Three.js OrthographicCamera -- Zoom to cursorThree.js OrthographicCamera -- 缩放到光标
【发布时间】:2022-01-08 01:51:22
【问题描述】:

我的 Three.js 项目使用 OrthographicCamera 和 OrthographicTrackBallControls 进行缩放/平移。我正在尝试添加功能以缩放到光标位置,但没有运气。首先,这是我获取鼠标位置的方法:

var mX = ((event.clientX - offset.left) / renderer.domElement.clientWidth) * 2 - 1;
var mY = -((event.clientY - offset.top) / renderer.domElement.clientHeight) * 2 + 1;
var vector = new THREE.Vector3(mX, mY, 0.5);
vector.unproject(camera);
vector.sub(camera.position);

通过查看 StackOverflow,似乎有很多关于如何使用 PerspectiveCamera 执行此操作的信息,但这些方法不适用于 OrthographicCamera。我找到了这个例子:

https://htmlpreview.github.io/?https://github.com/w3dot0/three.js/blob/973bf1d40ef552dbf19c19654a79f70e2882563d/examples/misc_controls_zoom_to_mouse.html

这正是我想要完成的任务,但实现这一点的代码是隐藏的,尽管我能够辨别出相机位置正在改变。

另一个类似的 SO 问题建议更改 camera.left、camera.right、camera.top 和 camera.bottom,但我对这种方法没有运气。这种方法似乎是一种可能性,但我不明白获得正确的左、右、顶和底值所需的计算。

所以在我看来,我有两种可能:

  1. 更改相机的左/右/上/下以获得正确的视图矩形。
  2. 更改摄像头位置。

但我也不知道如何获得我需要实现的价值,更不用说哪种方法更好了。

2018 年 11 月 16 日更新:

我已经将我的函数更新为这个(基于https://github.com/w3dot0/three.js/blob/973bf1d40ef552dbf19c19654a79f70e2882563d/examples/misc_controls_zoom_to_mouse.html):

zoomDirection = new THREE.Vector3();
function mousewheel(event) {
    event.preventDefault();
    var amount = event.deltaY / 100;
    var zoom = camera.zoom - amount;
    var offset = el.offset();
    ;
    var mX = amount > 0 ? 0 : ((event.clientX - offset.left) / renderer.domElement.clientWidth) * 2 - 1;
    var mY = amount > 0 ? 0 : -((event.clientY - offset.top) / renderer.domElement.clientHeight) * 2 + 1;

    zoomDirection.set(mX, mY, 0.001)
        .unproject(camera)
        .sub(camera.position)
        .multiplyScalar(amount / zoom);

    camera.position.subVectors(camera.position, zoomDirection);

    orthographictrackBallControls.target.subVectors(orthographictrackBallControls.target, webGl.zoomDirection);
    camera.zoom = zoom;
    camera.updateProjectionMatrix();
}

这似乎一开始是可行的:相机放大到鼠标点,但在稍微放大后相机开始“跳跃”,屏幕上不再可见网格。

可能有帮助的东西:我在屏幕上还有一个轴助手,当它按预期停止工作时会“翻转”。加载场景时,X 轴辅助点向左,但是当我到达相机跳跃的点并且我不再看到网格时,X 轴辅助点翻转到正确的点。

另外,如果我先缩小,我可以在网格消失之前进一步放大。我不确定这一切加起来是什么,但我会很感激任何帮助。

【问题讨论】:

标签: javascript three.js


【解决方案1】:

实现具有缩放功能的 D3 库对于这种情况似乎是个好主意。但在很多情况下,放弃三控并非一事无成。

如果您想要像 Google 地图中那样的缩放行为,以下代码可能会有所帮助:

const cameraPosition = camera.position.clone();

// my camera.zoom starts with 0.2
if (zoomOld !== 0.2) {
  const xNew = this.curserVector.x + (((cameraPosition.x - this.curserVector.x) * camera.zoom) /zoomOld);
  const yNew = this.curserVector.y + (((cameraPosition.y - this.curserVector.y) * camera.zoom) /zoomOld);
  const diffX = cameraPosition.x - xNew;
  const diffY = cameraPosition.y - yNew;
  camera.position.x += diffX;
  camera.position.y += diffY;
  controls.target.x += diffX;
  controls.target.y += diffY;
}
zoomOld = camera.zoom;

您的其他问题可能是由frustum 引起的。但我不知道,我还是个三xD的新手

【讨论】:

    【解决方案2】:

    新年后的第一周,修复这个问题花了很长时间。用线性代数覆盖的 A4 的六边结果

    if ( factor !== 1.0 && factor > 0.0 ) {
      const mX =  (event.offsetX / event.target.width ) * 2 - 1;
      const mY = -(event.offsetY / event.target.height) * 2 + 1;
      const vector1 = new THREE.Vector3(mX, mY, 0);
      const vector2 = new THREE.Vector3(0, 0, 0);
      vector1.unproject(this.camera);
      vector2.unproject(this.camera);
      vector1.subVectors(vector1, vector2);
    
      this.camera.zoom /= factor;
      vector1.multiplyScalar(factor - 1.0);
      this.camera.position.subVectors(this.camera.position, vector1);
      this.controls.target.subVectors(this.controls.target, vector1);
      this.camera.updateProjectionMatrix();
      this.camera.updateMatrix();
    }
    

    注意 mX、mY 的不同计算,以便它对视口有效。

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 2015-04-20
      • 2011-07-08
      • 1970-01-01
      • 2012-07-15
      • 2017-02-15
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多