Three.js limit and scale mouse controls to canvas

2019-06-01 09:26发布

I've been playing around with Three.js for a little while, I'm currently handling mouse dragging the same way as in the draggable cubes example of three.js, with Trackball Controls to operate the camera, however these controls both seem to work on the assumption that I use the whole browser window for my application.
Is there any way to scale (and restrict) these mouse controls to my canvas?

EDIT: Here is a code sample showing the mouse events for dragging objects (it's actually pretty much identical to the example provided in three.js' examples directory, but I applied uhura's code)

`//Called when cursor is moved, drags object if one is selected
        function onDocumentMouseMove( event ) {

            event.preventDefault();

            //mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            //mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

            mouse.x = cursorPositionInCanvas( renderer.domElement, event )[0];
            mouse.y = cursorPositionInCanvas( renderer.domElement, event )[1];

            var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
            projector.unprojectVector( vector, camera );
            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

            if ( SELECTED ) {
                var intersects = raycaster.intersectObject( plane );
                SELECTED.position.copy( intersects[ 0 ].point.sub( offset ) );
                return;
            }

            var intersects = raycaster.intersectObjects( objects );

            if ( intersects.length > 0 ) {
                if ( INTERSECTED != intersects[ 0 ].object ) {
                    INTERSECTED = intersects[ 0 ].object;
                    plane.position.copy( INTERSECTED.position );
                    plane.lookAt( camera.position );
                }
            } 
            else {
                INTERSECTED = null;
            }               

        }

        //Called when user clicks, selects object if mouse is over it and disables trackball controls
        function onDocumentMouseDown( event ) {

            event.preventDefault();

            var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
            projector.unprojectVector( vector, camera );
            var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
            var intersects = raycaster.intersectObjects( objects );
            if ( intersects.length > 0 ) {
                controls.enabled = false;

                SELECTED = intersects[ 0 ].object;
                var intersects = raycaster.intersectObject( plane );
                offset.copy( intersects[ 0 ].point ).sub( plane.position );
            }

        }

        //Called when user releases mouse button, deselects any selected objects and re-enables trackball controls
        function onDocumentMouseUp( event ) {

            event.preventDefault();

            controls.enabled = true;
            if ( INTERSECTED ) {
                plane.position.copy( INTERSECTED.position );

                SELECTED = null;
            }

        }

        function cursorPositionInCanvas(canvas, event) {
            var x, y;

            canoffset = $(canvas).offset();
            x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - Math.floor(canoffset.left);
            y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - Math.floor(canoffset.top) + 1;
            return [x,y];
        }`

2条回答
我只想做你的唯一
2楼-- · 2019-06-01 09:34

The answer to your question is actually quite simple. It took me a while to figure this out, though. By adding a second parameter to your TrackballControls constructor, you can control the elements over which the controls are active.

var controls = new THREE.TrackballControls(camera, renderer.domElement)
查看更多
Luminary・发光体
3楼-- · 2019-06-01 09:40

With jQuery :

function cursorPositionInCanvas(canvas, event) {
                var x, y;

                canoffset = $(canvas).offset();
                x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - Math.floor(canoffset.left);
                y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - Math.floor(canoffset.top) + 1;

                return [x,y];
    }

Javascript solution

Others

Updated:

mouse.x = (cursorPositionInCanvas( renderer.domElement, event )[0]) / $(canvas).width()) * 2 - 1;
mouse.y = - (cursorPositionInCanvas( renderer.domElement, event )[1])/ $(canvas).height()) * 2 + 1;
查看更多
登录 后发表回答