javascript - Three.js 鼠标滚轮用于向上/向下移动相机而不是放大/缩小

标签 javascript three.js

你是如何做到这一点的?我使用 Three.js Editor 创建了一个场景并使用“发布”选项下载该项目。我编辑了 app.js 文件以导入 OrbitControls,因此现在我可以使用鼠标滚轮(或者在我的情况下使用 Apple Magic Mouse 2 触控板表面)来放大/缩小场景。但是,我不希望鼠标滚轮缩放,我希望它“滚动”(沿 Y 轴而不是 Z 轴向上/向下移动相机)。有没有办法做到这一点? OrbitControls 是实现这一目标的方法还是只会增加复杂性?这是我的 app.js:

import {OrbitControls} from './OrbitControls.js'; // Added
var APP = {
    Player: function ( THREE ) {
        window.THREE = THREE; // FIX for editor scripts (they require THREE in global namespace)
        var loader = new THREE.ObjectLoader();
        var camera, scene, renderer;
        var events = {};
        var dom = document.createElement( 'div' );
        dom.className = "threejs-app";
        this.dom = dom;
        this.width = 500;
        this.height = 500;
        this.load = function ( json ) {
            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.outputEncoding = THREE.sRGBEncoding;
            renderer.setClearColor( 0x000000 );
            renderer.setPixelRatio( window.devicePixelRatio );
            var project = json.project;
            if ( project.shadows ) renderer.shadowMap.enabled = true;
            if ( project.vr ) renderer.xr.enabled = true;
            dom.appendChild( renderer.domElement );
            this.setScene( loader.parse( json.scene ) );
            this.setCamera( loader.parse( json.camera ) );
            var controls = new OrbitControls( camera, renderer.domElement ); // Added
            events = {
                init: [],
                start: [],
                stop: [],
                keydown: [],
                keyup: [],
                mousedown: [],
                mouseup: [],
                mousemove: [],
                touchstart: [],
                touchend: [],
                touchmove: [],
                update: []
            };
            var scriptWrapParams = 'player,renderer,scene,camera';
            var scriptWrapResultObj = {};
            for ( var eventKey in events ) {
                scriptWrapParams += ',' + eventKey;
                scriptWrapResultObj[ eventKey ] = eventKey;
            }
            var scriptWrapResult = JSON.stringify( scriptWrapResultObj ).replace( /\"/g, '' );
            for ( var uuid in json.scripts ) {
                var object = scene.getObjectByProperty( 'uuid', uuid, true );
                if ( object === undefined ) {
                    console.warn( 'APP.Player: Script without object.', uuid );
                    continue;
                }
                var scripts = json.scripts[ uuid ];
                for ( var i = 0; i < scripts.length; i ++ ) {
                    var script = scripts[ i ];
                    var functions = ( new Function( scriptWrapParams, script.source + '\nreturn ' + scriptWrapResult + ';' ).bind( object ) )( this, renderer, scene, camera );
                    for ( var name in functions ) {
                        if ( functions[ name ] === undefined ) continue;
                        if ( events[ name ] === undefined ) {
                            console.warn( 'APP.Player: Event type not supported (', name, ')' );
                            continue;
                        }
                        events[ name ].push( functions[ name ].bind( object ) );
                    }
                }
            }
            dispatch( events.init, arguments );
        };
        this.setCamera = function ( value ) {
            camera = value;
            camera.aspect = this.width / this.height;
            camera.updateProjectionMatrix();
        };
        this.setScene = function ( value ) {
            scene = value;
        };
        this.setSize = function ( width, height ) {
            this.width = width;
            this.height = height;
            if ( camera ) {
                camera.aspect = this.width / this.height;
                camera.updateProjectionMatrix();
            }
            if ( renderer ) {
                renderer.setSize( width, height );
            }
        };
        function dispatch( array, event ) {
            for ( var i = 0, l = array.length; i < l; i ++ ) {
                array[ i ]( event );
            }
        }
        var time, prevTime;
        function animate() {
            time = performance.now();
            try {
                dispatch( events.update, { time: time, delta: time - prevTime } );
            } catch ( e ) {
                console.error( ( e.message || e ), ( e.stack || "" ) );
            }
            renderer.render( scene, camera );
            prevTime = time;
        }
        this.play = function () {
            prevTime = performance.now();
            document.addEventListener( 'keydown', onDocumentKeyDown );
            document.addEventListener( 'keyup', onDocumentKeyUp );
            document.addEventListener( 'mousedown', onDocumentMouseDown );
            document.addEventListener( 'mouseup', onDocumentMouseUp );
            document.addEventListener( 'mousemove', onDocumentMouseMove );
            document.addEventListener( 'touchstart', onDocumentTouchStart );
            document.addEventListener( 'touchend', onDocumentTouchEnd );
            document.addEventListener( 'touchmove', onDocumentTouchMove );
            dispatch( events.start, arguments );
            renderer.setAnimationLoop( animate );
        };
        this.stop = function () {
            document.removeEventListener( 'keydown', onDocumentKeyDown );
            document.removeEventListener( 'keyup', onDocumentKeyUp );
            document.removeEventListener( 'mousedown', onDocumentMouseDown );
            document.removeEventListener( 'mouseup', onDocumentMouseUp );
            document.removeEventListener( 'mousemove', onDocumentMouseMove );
            document.removeEventListener( 'touchstart', onDocumentTouchStart );
            document.removeEventListener( 'touchend', onDocumentTouchEnd );
            document.removeEventListener( 'touchmove', onDocumentTouchMove );
            dispatch( events.stop, arguments );
            renderer.setAnimationLoop( null );
        };
        this.dispose = function () {
            while ( dom.children.length ) {
                dom.removeChild( dom.firstChild );
            }
            renderer.dispose();
            camera = undefined;
            scene = undefined;
            renderer = undefined;
        };
        //
        function onDocumentKeyDown( event ) {
            dispatch( events.keydown, event );
        }
        function onDocumentKeyUp( event ) {
            dispatch( events.keyup, event );
        }
        function onDocumentMouseDown( event ) {
            dispatch( events.mousedown, event );
        }
        function onDocumentMouseUp( event ) {
            dispatch( events.mouseup, event );
        }
        function onDocumentMouseMove( event ) {
            dispatch( events.mousemove, event );
        }
        function onDocumentTouchStart( event ) {
            dispatch( events.touchstart, event );
        }
        function onDocumentTouchEnd( event ) {
            dispatch( events.touchend, event );
        }
        function onDocumentTouchMove( event ) {
            dispatch( events.touchmove, event );
        }
    }
};
export { APP };
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>

最佳答案

我没有您项目的详细信息,但似乎您需要实现自己的婴儿车模块。

我该怎么做,Teo?

好吧,我年轻的学徒,我们只需要实现一个像你提到的那样向上/向下移动相机的功能。

那么,您的意思是 OrbitControls 只是增加了复杂性?

现在,如果这是您唯一需要的相机移动,那么确实如此。

让我们实现它。

首先,我们添加 window.addEventListener('wheel', onMouseWheel, false); 来监听鼠标滚轮。然后我们调用 event.preventDefault(); 方法来阻止缩放。

现在,我们计算滚动修饰符camera.position.y += event.deltaY/1000;。在本例中,我们使用 Y 轴的增量。对于此示例,该值非常高,因此我除以 1000 以获得更平滑的滚动。

最后,我们添加 camera.position.clampScalar(0, 10); 以防止滚动出界。

let camera, scene, renderer;
let geometry, material, mesh;

init();
animate();

function init() {
  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);

  camera.position.z = 1;

  scene = new THREE.Scene();

  geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
  material = new THREE.MeshNormalMaterial();

  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });

  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  window.addEventListener('wheel', onMouseWheel, false);
  window.addEventListener('resize', onWindowResize, false);
}


function animate() {

  requestAnimationFrame(animate);

  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.02;

  renderer.render(scene, camera);
}


function onMouseWheel(ev) {
  event.preventDefault();

  camera.position.y += event.deltaY / 1000;

  // prevent scrolling beyond a min/max value
  camera.position.clampScalar(0, 10);
}


function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>

关于javascript - Three.js 鼠标滚轮用于向上/向下移动相机而不是放大/缩小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59776570/

相关文章:

angular - Three.js + Angular : texture loading fails

javascript - JSON.stringify 和 "\u2028\u2029"检查?

javascript - chrome 扩展 popup.js 问题中的 setTimeout 函数

javascript - 在多维javascript对象中递归查找和替换

javascript - 按多个匹配值过滤数组

javascript - 加速 THREE.js 的方法

javascript - WebView: Uncaught ReferenceError: Android 未定义

javascript - TypeError Object[object object] 没有方法 SubSelf,TypeError Object[object object] 没有方法 intersectsPlane

javascript - 在 Three.js 中使用 FBXLoader 将 BufferGeometry 转换为 Geometry

javascript - 使用 Three.js PositionalAudio 制作音锥