Three.js 鼠标滚轮可向上/向下移动相机而不是放大/缩小 [英] Three.js mousewheel to move camera up/down instead of zoom-in/out

查看:27
本文介绍了Three.js 鼠标滚轮可向上/向下移动相机而不是放大/缩小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do you do this? I created a scene using the Three.js Editor and downloaded the project using the "Publish" option. I edited the app.js file to import OrbitControls, so now I can use the mouse wheel (or in my case the Apple Magic Mouse 2 trackpad surface) to zoom in/out of the scene. However, I don't want the mouse wheel to zoom, I want it to "scroll" (move the camera up/down along the Y-axis as opposed the Z-axis). Is there a way to do that? Is OrbitControls the way to get there or does that just add complexity? Here is my 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>

推荐答案

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

I don't have the details of your project but seems like you need implement your own stroller module.

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

Well, my young Padawan, we just need to implement a function that moves the camera up/down as you mentioned.

现在,如果这是您唯一需要的相机移动,那么就可以了.

Now, if that is the only camera movement you need, then yupe it does.

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

First, we add window.addEventListener('wheel', onMouseWheel, false); to listen the mouse wheel. Then we call event.preventDefault(); method to prevent the zoom.

现在,我们计算滚动修饰符camera.position.y += event.deltaY/1000;.在这种情况下,我们使用 Y 轴上的增量.对于这个例子,这个值太高了,所以我除以 1000 以获得更平滑的滚动.

Now, we calculate the scroll modifier camera.position.y += event.deltaY / 1000;. In this case, we use the delta in the Y-axis. For this example the value was so high so I divided by 1000 to have a more smooth scrolling.

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

Finally, we add camera.position.clampScalar(0, 10); to prevent the scrolling out of bounds.

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>

这篇关于Three.js 鼠标滚轮可向上/向下移动相机而不是放大/缩小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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