Rotate camera in Three.js with mouse

前端 未结 5 1723
心在旅途
心在旅途 2020-12-04 07:09

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 a

5条回答
  •  误落风尘
    2020-12-04 07:33

    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
    • move [mouse wheel / two fingers on trackpad] to move up/down in z-direction
    • hold shift + [mouse wheel / two fingers on trackpad] to zoom in/out via increasing/decreasing field-of-view
    • 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:

    // 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)
    

提交回复
热议问题