ThreeJS中的缩放到对象

3

在three.js中,我该如何更改缩放方向?我希望能够针对鼠标光标的方向进行缩放,但我不知道在哪里可以更改缩放目标。

6个回答

10

我更新了wetwipe的解决方案,以支持Three.js的71个版本,并稍微进行了一些清理。它非常好用,您可以查看http://www.tectractys.com/market_globe.html获取完整的使用示例:

mX = ( event.clientX / window.innerWidth ) * 2 - 1;
mY = - ( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3(mX, mY, 1 );
vector.unproject(camera);
vector.sub(camera.position);
camera.position.addVectors(camera.position,vector.setLength(factor));
controls.target.addVectors(controls.target,vector.setLength(factor));

3
这句话的翻译是:“控制一个实例的是什么?” - arhoskins

4

好的!我是这样解决问题的......只需禁用由THREEJS提供的缩放功能。

controls.noZoom = true;

$('body').on('mousewheel', function (e){

        var mouseX = (e.clientX - (WIDTH/2)) * 10;
        var mouseY = (e.clientY - (HEIGHT/2)) * 10;

        if(e.originalEvent.deltaY < 0){ // zoom to the front
            camera.position.x -= mouseX * .00125;
            camera.position.y += mouseY * .00125;
            camera.position.z += 1.1 * 10;
            controls.target.x -= mouseX * .00125;
            controls.target.y += mouseY * .00125;
            controls.target.z += 1.1 * 10;
        }else{                          // zoom to the back
            camera.position.x += mouseX * .00125;
            camera.position.y -= mouseY * .00125;
            camera.position.z -= 1.1 * 10;
            controls.target.x += mouseX * .00125;
            controls.target.y -= mouseY * .00125;
            controls.target.z -= 1.1 * 10;
        }
});

我知道这不是完美的...但我希望能对你有所帮助....总之...我会继续努力,让它变得更好。


它在正交相机上不起作用。我们需要采用不同的方法吗? - Aasha joney

2

最近我遇到了一个类似的问题,但是我需要放大的范围更广。我使用了Niekes在他的解决方案中提供的代码,并得出了以下结论:

container.on('mousewheel', function ( ev ){

        var factor = 10;

        var WIDTH = window.innerWidth;
        var HEIGHT = window.innerHeight;

        var mX = ( ev.clientX / WIDTH ) * 2 - 1;
        var mY = - ( ev.clientY / HEIGHT ) * 2 + 1;

        var vector = new THREE.Vector3(mX, mY, 1 );
        projector.unprojectVector( vector, camera );
        vector.sub( camera.position ).normalize();

        if( ev.originalEvent.deltaY < 0 ){
            camera.position.x += vector.x * factor;
            camera.position.y += vector.y * factor;
            camera.position.z += vector.z * factor;
            controls.target.x += vector.x * factor;
            controls.target.y += vector.y * factor;
            controls.target.z += vector.z * factor;
        } else{
            camera.position.x -= vector.x * factor;
            camera.position.y -= vector.y * factor;
            camera.position.z -= vector.z * factor;
            controls.target.x -= vector.x * factor;
            controls.target.y -= vector.y * factor;
            controls.target.z -= vector.z * factor;
        }
});

虽然不太美观,但至少功能上还是可以的。欢迎提出改进意见 :)


它对正交相机不起作用。你有正交相机的解决方法吗? - Aasha joney
@Aashajoney:我已经有一段时间没有使用three.js了。也许这可以帮助你:https://dev59.com/w47da4cB1Zd3GeqP7whU#41583081 - zaSmilingIdiot
谢谢您的回复。但是该链接是用于将对象适配到场景中。 - Aasha joney
好的,我看到之前我链接的帖子实际上是你发的。所以我找到了这个链接(https://blender.stackexchange.com/a/649),它似乎很有道理。不过,除此之外,我还在这里(https://threejs.org/examples/canvas_camera_orthographic2.html)找到了一个例子,从源代码来看,它似乎已经完成了大部分工作。剩下的就是移动相机/场景以使目标对象居中。应该是一些鼠标下方对象的坐标、相机位置/中心和场景位置/中心的组合。可能不对,但这是我的几分建议... - zaSmilingIdiot
非常感谢您的回复。 - Aasha joney

0

我完全是Three.js的新手,但它太棒了。我甚至不是一个好的开发者,正在努力练习。 我曾经遇到过鼠标缩放的问题,但我认为我已经稍微改进了代码。这是我的代码。

// zooming to the mouse position
window.addEventListener('mousewheel', function (e) { mousewheel(e); }, false); 
function mousewheel(event) {
    orbitControl.enableZoom = false;
    event.preventDefault();

    // the following are constants depending on the scale of the scene
    // they need be adjusted according to your model scale  
    var factor = 5; 
    // factor determines how fast the user can zoom-in/out  
    var minTargetToCameraDistanceAllowed = 15; 
    // this is the minimum radius the camera can orbit around a target. 

    // calculate the mouse distance from the center of the window
    var mX = (event.clientX / window.innerWidth) * 2 - 1;
    var mY = -(event.clientY / window.innerHeight) * 2 + 1;
    var vector = new THREE.Vector3(mX, mY, 0.5);

    vector.unproject(camera);
    vector.sub(camera.position);

    if (event.deltaY < 0) { 
        // zoom-in -> the camera is approaching the scene
        // with OrbitControls the target is always in front of the camera (in the center of the screen)
        // So when the user zoom-in, the target distance from the camera decrease.
        // This is achieved because the camera position changes, not the target.
        camera.position.addVectors(camera.position, vector.setLength(factor));
    } else { 
        // zoom-out -> the camera is moving away from the scene -> the target distance increase
        camera.position.subVectors(camera.position, vector.setLength(factor));
    }
    // Now camera.position is changed but not the control target. As a result: 
    //  - the distance from the camera to the target is changed, and this is ok.
    //  - the target is no more in the center of the screen and needs to be repositioned. 
    // The new target will be in front of the camera (in the direction of the camera.getWorldDirection() )
    // at a suitable distance (no less than the value of minTargetToCameraDistanceAllowed constant).
    // Thus, the target is pushed a little further if the user approaches too much the target.
    var targetToCameraDistance = Math.max(minTargetToCameraDistanceAllowed, 
                                            orbitControl.target.distanceTo(camera.position));
    var newTarget = camera.getWorldDirection().setLength( targetToCameraDistance ).add(camera.position);
    orbitControl.target = newTarget;

    camera.updateProjectionMatrix();

}

另一个改进的方法是将targetToCameraDistance设置为鼠标击中的对象的距离,当用户开始轨道运动时。
如果鼠标击中了一个对象,并且距离>minTargetToCameraDistanceAllowed,则计算并设置新的目标。
...但我仍然不知道如何做到这一点。


0

从未听说过缩放方向,

您可能需要检查相机的FOV参数,

并调用此函数以应用更改:

yourCam.updateProjectionMatrix();

1
我想表达的是,我希望实现类似于谷歌地图的缩放行为...鼠标光标是感兴趣的点,当您缩放时,摄像机会沿着鼠标光标的方向移动...目前您只能将其缩放到文档中心...有什么想法吗? - Niekes
嗯...有点复杂,需要修改投影矩阵。如果你查看OpenGL矩阵,你需要修改左右上下的字段。因此,你需要找到新的中心,扭曲投影,然后缩放它(基本上就像改变视野一样)。 - pailhead

0

如果您正在使用轨迹球控制,请设置

trackBallControls.noZoom=true;

在鼠标滚轮事件中使用以下代码:

mousewheel = function (event) {

            event.preventDefault();
            var factor = 15;
            var mX = (event.clientX / jQuery(container).width()) * 2 - 1;
            var mY = -(event.clientY / jQuery(container).height()) * 2 + 1;
            var vector = new THREE.Vector3(mX, mY, 0.1);

            vector.unproject(Camera);
            vector.sub(Camera.position);
            if (event.deltaY < 0) {
                Camera.position.addVectors(Camera.position, vector.setLength(factor));
                trackBallControls.target.addVectors(trackBallControls.target, vector.setLength(factor));
                Camera.updateProjectionMatrix();
            } else {
                Camera.position.subVectors(Camera.position, vector.setLength(factor));
                trackBallControls.target.subVectors(trackBallControls.target, vector.setLength(factor));

            }

        };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接