【问题标题】:Three.js limit and scale mouse controls to canvas sizeThree.js 限制和缩放鼠标控件到画布大小
【发布时间】:2019-04-18 08:47:34
【问题描述】:

我一直在使用 Three.js,我目前处理鼠标拖动的方式与 three.js 的可拖动立方体示例中的相同,使用轨迹球控件来操作相机,但是这些控件两者似乎都假设我将整个浏览器窗口用于我的应用程序。
有什么方法可以将这些鼠标控件缩放(和限制)到我的画布上?

编辑: 这是一个显示拖动对象的鼠标事件的代码示例(它实际上与three.js的示例目录中提供的示例几乎相同,但我应用了uhura的代码)

`//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];
        }`

【问题讨论】:

  • 我看到在修改后的版本中您没有遵循 uhura 提供的代码。您没有缩放矢量以匹配屏幕坐标,因此 Y 轴将被翻转。鼠标矢量应该是标准化的,并且为了匹配 WebGL 使用的坐标,Y 必须被翻转。如果您不这样做,您可能会在 RayCaster 中看到奇怪的行为。

标签: javascript three.js webgl


【解决方案1】:

使用 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

更新:

mouse.x = (cursorPositionInCanvas( renderer.domElement, event )[0]) / $(canvas).width()) * 2 - 1;
mouse.y = - (cursorPositionInCanvas( renderer.domElement, event )[1])/ $(canvas).height()) * 2 + 1;

【讨论】:

    【解决方案2】:

    你的问题的答案其实很简单。不过,我花了一段时间才弄清楚这一点。通过向 TrackballControls 构造函数添加第二个参数,您可以控制控件处于活动状态的元素。

    var controls = new THREE.TrackballControls(camera, renderer.domElement)
    

    【讨论】:

      猜你喜欢
      • 2020-11-12
      • 2018-11-14
      • 2018-08-21
      • 2011-07-08
      • 2018-11-25
      • 2014-04-16
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多