相机在三个旋转。js用鼠标

时间:2021-11-25 06:23:49

I have quite a few objects in my scene so rotating all of them could be a pain. So what is the most easy way to move camera around origin on mouse click and drag? This way all the lights, objects in the scene are in the same location, so the only thing changing is the camera. Three.js does not provide a way to rotate a camera around a point, or does it?

在我的场景中,我有相当多的物体,所以旋转它们都可能是一种痛苦。那么,在鼠标点击和拖动的时候,最简单的移动相机的方式是什么呢?这样所有的灯,场景中的物体都在同一个位置,所以唯一改变的就是相机。三。js并没有提供一种方法来旋转相机在一个点附近,还是?

Thank you

谢谢你!

4 个解决方案

#1


54  

Here's a project with a rotating camera. Looking through the source it seems to just move the camera position in a circle.

这是一个有旋转照相机的项目。从源头看,它似乎只是把摄像机的位置移动了一个圈。

function onDocumentMouseMove( event ) {

    event.preventDefault();

    if ( isMouseDown ) {

        theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 )
                + onMouseDownTheta;
        phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 )
              + onMouseDownPhi;

        phi = Math.min( 180, Math.max( 0, phi ) );

        camera.position.x = radious * Math.sin( theta * Math.PI / 360 )
                            * Math.cos( phi * Math.PI / 360 );
        camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
        camera.position.z = radious * Math.cos( theta * Math.PI / 360 )
                            * Math.cos( phi * Math.PI / 360 );
        camera.updateMatrix();

    }

    mouse3D = projector.unprojectVector(
        new THREE.Vector3(
            ( event.clientX / renderer.domElement.width ) * 2 - 1,
            - ( event.clientY / renderer.domElement.height ) * 2 + 1,
            0.5
        ),
        camera
    );
    ray.direction = mouse3D.subSelf( camera.position ).normalize();

    interact();
    render();

}

Here's another demo and in this one I think it just creates a new THREE.TrackballControls object with the camera as a parameter, which is probably the better way to go.

这是另一个demo,我认为它会创建一个新的3。轨迹球控制对象以相机作为参数,这可能是更好的方法。

controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )

#2


38  

take a look at the following examples

请看下面的例子。

http://threejs.org/examples/#misc_controls_orbit

http://threejs.org/examples/ misc_controls_orbit

http://threejs.org/examples/#misc_controls_trackball

http://threejs.org/examples/ misc_controls_trackball

there are other examples for different mouse controls, but both of these allow the camera to rotate around a point and zoom in and out with the mouse wheel, the main difference is OrbitControls enforces the camera up direction, and TrackballControls allows the camera to rotate upside-down.

对于不同的鼠标控制,还有其他的例子,但这两种方法都允许摄像头绕着一个点旋转,并通过鼠标滚轮来放大和缩小,主要的区别是,轨道控制使相机朝上方向,而轨迹球控制则允许相机倒转。

All you have to do is include the controls in your html document

您所要做的就是在html文档中包含控件。

<script src="js/OrbitControls.js"></script>

and include this line in your source

并且在你的源代码中包含这一行。

controls = new THREE.OrbitControls( camera, renderer.domElement );

#3


3  

Take a look at THREE.PointerLockControls

让我们看一看3。pointerlockcontrols。

#4


2  

This might serve as a good starting point for moving/rotating/zooming a camera with mouse/trackpad (in typescript):

这可能是移动/旋转/缩放带有鼠标/触控板的相机的好起点(在打字稿中):

class CameraControl {
    zoomMode: boolean = false
    press: boolean = false
    sensitivity: number = 0.02

    constructor(renderer: Three.Renderer, public camera: Three.PerspectiveCamera, updateCallback:() => void){
        renderer.domElement.addEventListener('mousemove', event => {
            if(!this.press){ return }

            if(event.button == 0){
                camera.position.y -= event.movementY * this.sensitivity
                camera.position.x -= event.movementX * this.sensitivity        
            } else if(event.button == 2){
                camera.quaternion.y -= event.movementX * this.sensitivity/10
                camera.quaternion.x -= event.movementY * this.sensitivity/10
            }

            updateCallback()
        })    

        renderer.domElement.addEventListener('mousedown', () => { this.press = true })
        renderer.domElement.addEventListener('mouseup', () => { this.press = false })
        renderer.domElement.addEventListener('mouseleave', () => { this.press = false })

        document.addEventListener('keydown', event => {
            if(event.key == 'Shift'){
                this.zoomMode = true
            }
        })

        document.addEventListener('keyup', event => {
            if(event.key == 'Shift'){
                this.zoomMode = false
            }
        })

        renderer.domElement.addEventListener('mousewheel', event => {
            if(this.zoomMode){ 
                camera.fov += event.wheelDelta * this.sensitivity
                camera.updateProjectionMatrix()
            } else {
                camera.position.z += event.wheelDelta * this.sensitivity
            }

            updateCallback()
        })
    }
}

drop it in like:

把它像:

this.cameraControl = new CameraControl(renderer, camera, () => {
    // you might want to rerender on camera update if you are not rerendering all the time
    window.requestAnimationFrame(() => renderer.render(scene, camera))
})

Controls:

控制:

  • move while [holding mouse left / single finger on trackpad] to move camera in x/y plane
  • 移动时(按住鼠标左键在触控板上)在x/y平面上移动摄像机。
  • move [mouse wheel / two fingers on trackpad] to move up/down in z-direction
  • 移动(鼠标滚轮/两个手指在触控板上)在z方向上移动。
  • hold shift + [mouse wheel / two fingers on trackpad] to zoom in/out via increasing/decreasing field-of-view
  • 按住shift +[鼠标滚轮/两个手指在轨迹板上]通过增加/减少视野来放大/缩小。
  • move while holding [mouse right / two fingers on trackpad] to rotate the camera (quaternion)
  • 按住鼠标左键移动相机(四元数)

Additionally:

另外:

If you want to kinda zoom by changing the 'distance' (along yz) instead of changing field-of-view you can bump up/down camera's position y and z while keeping the ratio of position's y and z unchanged like:

如果你想通过改变“距离”(沿着yz)来变焦,而不是改变视野,你可以在保持位置y和z的比例不变的情况下,提高相机的位置y和z。

// in mousewheel event listener in zoom mode
const ratio = camera.position.y / camera.position.z
camera.position.y += (event.wheelDelta * this.sensitivity * ratio)
camera.position.z += (event.wheelDelta * this.sensitivity)

#1


54  

Here's a project with a rotating camera. Looking through the source it seems to just move the camera position in a circle.

这是一个有旋转照相机的项目。从源头看,它似乎只是把摄像机的位置移动了一个圈。

function onDocumentMouseMove( event ) {

    event.preventDefault();

    if ( isMouseDown ) {

        theta = - ( ( event.clientX - onMouseDownPosition.x ) * 0.5 )
                + onMouseDownTheta;
        phi = ( ( event.clientY - onMouseDownPosition.y ) * 0.5 )
              + onMouseDownPhi;

        phi = Math.min( 180, Math.max( 0, phi ) );

        camera.position.x = radious * Math.sin( theta * Math.PI / 360 )
                            * Math.cos( phi * Math.PI / 360 );
        camera.position.y = radious * Math.sin( phi * Math.PI / 360 );
        camera.position.z = radious * Math.cos( theta * Math.PI / 360 )
                            * Math.cos( phi * Math.PI / 360 );
        camera.updateMatrix();

    }

    mouse3D = projector.unprojectVector(
        new THREE.Vector3(
            ( event.clientX / renderer.domElement.width ) * 2 - 1,
            - ( event.clientY / renderer.domElement.height ) * 2 + 1,
            0.5
        ),
        camera
    );
    ray.direction = mouse3D.subSelf( camera.position ).normalize();

    interact();
    render();

}

Here's another demo and in this one I think it just creates a new THREE.TrackballControls object with the camera as a parameter, which is probably the better way to go.

这是另一个demo,我认为它会创建一个新的3。轨迹球控制对象以相机作为参数,这可能是更好的方法。

controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 )

#2


38  

take a look at the following examples

请看下面的例子。

http://threejs.org/examples/#misc_controls_orbit

http://threejs.org/examples/ misc_controls_orbit

http://threejs.org/examples/#misc_controls_trackball

http://threejs.org/examples/ misc_controls_trackball

there are other examples for different mouse controls, but both of these allow the camera to rotate around a point and zoom in and out with the mouse wheel, the main difference is OrbitControls enforces the camera up direction, and TrackballControls allows the camera to rotate upside-down.

对于不同的鼠标控制,还有其他的例子,但这两种方法都允许摄像头绕着一个点旋转,并通过鼠标滚轮来放大和缩小,主要的区别是,轨道控制使相机朝上方向,而轨迹球控制则允许相机倒转。

All you have to do is include the controls in your html document

您所要做的就是在html文档中包含控件。

<script src="js/OrbitControls.js"></script>

and include this line in your source

并且在你的源代码中包含这一行。

controls = new THREE.OrbitControls( camera, renderer.domElement );

#3


3  

Take a look at THREE.PointerLockControls

让我们看一看3。pointerlockcontrols。

#4


2  

This might serve as a good starting point for moving/rotating/zooming a camera with mouse/trackpad (in typescript):

这可能是移动/旋转/缩放带有鼠标/触控板的相机的好起点(在打字稿中):

class CameraControl {
    zoomMode: boolean = false
    press: boolean = false
    sensitivity: number = 0.02

    constructor(renderer: Three.Renderer, public camera: Three.PerspectiveCamera, updateCallback:() => void){
        renderer.domElement.addEventListener('mousemove', event => {
            if(!this.press){ return }

            if(event.button == 0){
                camera.position.y -= event.movementY * this.sensitivity
                camera.position.x -= event.movementX * this.sensitivity        
            } else if(event.button == 2){
                camera.quaternion.y -= event.movementX * this.sensitivity/10
                camera.quaternion.x -= event.movementY * this.sensitivity/10
            }

            updateCallback()
        })    

        renderer.domElement.addEventListener('mousedown', () => { this.press = true })
        renderer.domElement.addEventListener('mouseup', () => { this.press = false })
        renderer.domElement.addEventListener('mouseleave', () => { this.press = false })

        document.addEventListener('keydown', event => {
            if(event.key == 'Shift'){
                this.zoomMode = true
            }
        })

        document.addEventListener('keyup', event => {
            if(event.key == 'Shift'){
                this.zoomMode = false
            }
        })

        renderer.domElement.addEventListener('mousewheel', event => {
            if(this.zoomMode){ 
                camera.fov += event.wheelDelta * this.sensitivity
                camera.updateProjectionMatrix()
            } else {
                camera.position.z += event.wheelDelta * this.sensitivity
            }

            updateCallback()
        })
    }
}

drop it in like:

把它像:

this.cameraControl = new CameraControl(renderer, camera, () => {
    // you might want to rerender on camera update if you are not rerendering all the time
    window.requestAnimationFrame(() => renderer.render(scene, camera))
})

Controls:

控制:

  • move while [holding mouse left / single finger on trackpad] to move camera in x/y plane
  • 移动时(按住鼠标左键在触控板上)在x/y平面上移动摄像机。
  • move [mouse wheel / two fingers on trackpad] to move up/down in z-direction
  • 移动(鼠标滚轮/两个手指在触控板上)在z方向上移动。
  • hold shift + [mouse wheel / two fingers on trackpad] to zoom in/out via increasing/decreasing field-of-view
  • 按住shift +[鼠标滚轮/两个手指在轨迹板上]通过增加/减少视野来放大/缩小。
  • move while holding [mouse right / two fingers on trackpad] to rotate the camera (quaternion)
  • 按住鼠标左键移动相机(四元数)

Additionally:

另外:

If you want to kinda zoom by changing the 'distance' (along yz) instead of changing field-of-view you can bump up/down camera's position y and z while keeping the ratio of position's y and z unchanged like:

如果你想通过改变“距离”(沿着yz)来变焦,而不是改变视野,你可以在保持位置y和z的比例不变的情况下,提高相机的位置y和z。

// in mousewheel event listener in zoom mode
const ratio = camera.position.y / camera.position.z
camera.position.y += (event.wheelDelta * this.sensitivity * ratio)
camera.position.z += (event.wheelDelta * this.sensitivity)