Three.js 将鼠标移动限制为仅场景 [英] Three.js Restrict the mouse movement to Scene only

查看:85
本文介绍了Three.js 将鼠标移动限制为仅场景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理来自three.js (webgl_interactive_cubes_gpu.html) 的立方体示例.我意识到事件会传播到整个 html 页面.我的意思是我可以旋转、放大或缩小,即使鼠标指针不在场景内..

I am working on the cube example from three.js (webgl_interactive_cubes_gpu.html). I realized that events goes to the entire html page. I mean i can rotate, zoom in or zoom out, even if the mouse pointer is not inside the scene..

我谷歌了一下,找到了一些答案(仅当鼠标位于画布上方时才允许鼠标控制三个.js 场景) 但它们对我不起作用..下面是我的代码......

I google a little bit and found some answers (Allow mouse control of three.js scene only when mouse is over canvas) but they do not work for me..Below is my code...

        var container, stats;
        var camera, controls, scene, renderer;
        var pickingData = [], pickingTexture, pickingScene;
        var objects = [];
        var highlightBox;

        var mouse = new THREE.Vector2();
        var offset = new THREE.Vector3( 10, 10, 10 );

        init();
        animate();

        function init() {

            container = document.getElementById( "container" );

            camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.z = 1000;
            //camera.translateZ( -500 );

            controls = new THREE.TrackballControls(camera);
            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 4;
            controls.panSpeed = 0.8;
            controls.noZoom = false;
            controls.noPan = false;
            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.3;


            scene = new THREE.Scene();

            pickingScene = new THREE.Scene();
            pickingTexture = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
            pickingTexture.minFilter = THREE.LinearFilter;
            pickingTexture.generateMipmaps = false;

            scene.add( new THREE.AmbientLight( 0x555555 ));

            var light = new THREE.SpotLight( 0xffffff, 1.5 );
            light.position.set( 0, 500, 2000 );
            scene.add( light );

            var geometry = new THREE.Geometry(),
            pickingGeometry = new THREE.Geometry(),
            pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
            defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading,      vertexColors: THREE.VertexColors} );

            function applyVertexColors( g, c ) {

                g.faces.forEach( function( f ) {

                    var n = ( f instanceof THREE.Face3 ) ? 3 : 4;

                    for( var j = 0; j < n; j ++ ) {

                        f.vertexColors[ j ] = c;

                    }

                } );

            }

            var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
            var color = new THREE.Color();

            var matrix = new THREE.Matrix4();
            var quaternion = new THREE.Quaternion();

            var coord="219_163_189;130_173_179;161_113_231;
            var splitCoord=coord.split(";");

            var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;
            var splitCoordColor=coordColr.split(";");

            for ( var i = 0; i < splitCoord.length; i++ ) {

                var position = new THREE.Vector3();
                var xyz=splitCoord[i].split("_");
                var col=splitCoordColor[i].split("_");

                position.x = xyz[0];
                position.y = xyz[1];
                position.z = xyz[2];

                var rotation = new THREE.Euler();
                rotation.x = 0
                rotation.y = 0;
                rotation.z = 0;

                var scale = new THREE.Vector3();
                scale.x = 200 + 100;
                scale.y = 200 + 100;
                scale.z = 200 + 100;

                quaternion.setFromEuler(rotation, false );
                matrix.compose( position, quaternion, scale);

                col[0]=col[0]/255;
                col[1]=col[1]/255;                  
                col[2]=col[2]/255;

                applyVertexColors(geom, color.setRGB(col[0], col[1], col[2]));
                geometry.merge(geom, matrix);

                // give the geom's vertices a color corresponding to the "id"
                applyVertexColors( geom, color.setHex( i ) );

                pickingGeometry.merge( geom, matrix );

                pickingData[ i ] = {

                    position: position,
                    rotation: rotation,
                    scale: scale

                };

            }

            var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
            scene.add(drawnObject);

            pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );

            highlightBox = new THREE.Mesh(
                new THREE.BoxGeometry( 0.01, 0.01, 0.01 ),
                new THREE.MeshLambertMaterial( { color: 0xffff00 }
            ) );
            scene.add( highlightBox );

            renderer = new THREE.WebGLRenderer( );
            //renderer.setClearColor( 0xffffff );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize(800, 800);
            renderer.sortObjects = false;
            container.appendChild(renderer.domElement);

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild( stats.domElement );

            //renderer.domElement.addEventListener('mousemove', onMouseMove );

        }


        function onMouseMove( e ) {
            mouse.x = e.clientX;
            mouse.y = e.clientY;
        }

        function animate() {

            requestAnimationFrame( animate );
            render();
            stats.update();
        }

        function pick() {


            //render the picking scene off-screen
            renderer.render( pickingScene, camera, pickingTexture );

            //create buffer for reading single pixel
            var pixelBuffer = new Uint8Array( 4 );

            //read the pixel under the mouse from the texture
            renderer.readRenderTargetPixels(pickingTexture, mouse.x, pickingTexture.height - mouse.y, 1, 1, pixelBuffer);

            //interpret the pixel as an ID

            var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2] );
            var data = pickingData[ id ];

            if (data) {

                //move our highlightBox so that it surrounds the picked object
                if ( data.position && data.rotation && data.scale ){

                    highlightBox.position.copy( data.position );
                    highlightBox.rotation.copy( data.rotation );
                    highlightBox.scale.copy( data.scale ).add( offset );
                    highlightBox.visible = true;
                }

            } else {

                highlightBox.visible = false;
            }

        }

        function render() {

            controls.update();
            pick();
            renderer.render( scene, camera );

        }

非常感谢任何帮助..谢谢

any help is greatly appreciated.. Thanks

推荐答案

您可以将画布作为参数传递给 TrackballsControls 构造函数.

You can pass in the canvas as an argument to the TrackballsControls constructor.

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

这应该可以解决问题.

包括一个工作示例,

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, 400 / 300, 1, 1000);

var renderer = new THREE.WebGLRenderer();
renderer.setSize(400, 300);
document.body.appendChild(renderer.domElement);

var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 4;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;


var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
  color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

var render = function() {
  requestAnimationFrame(render);
  controls.update();
  cube.rotation.x += 0.1;
  cube.rotation.y += 0.1;

  renderer.render(scene, camera);
};

render();

根本无法运行您的代码,所以..

could not get your code to run at all so..

这篇关于Three.js 将鼠标移动限制为仅场景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆