Три. js колесика мыши для перемещения камеры вверх / вниз вместо увеличения / уменьшения - PullRequest
0 голосов
/ 16 января 2020

Как ты это делаешь? Я создал сцену с помощью Three. js Editor и загрузил проект, используя опцию «Publi sh». Я отредактировал файл приложения. js, чтобы импортировать OrbitControls, поэтому теперь я могу использовать колесо мыши (или в моем случае поверхность трекпада Apple Magi c Mouse 2) для увеличения / уменьшения масштаба сцены. Однако я не хочу, чтобы колесо мыши увеличивалось, я хочу, чтобы оно «прокручивалось» (перемещайте камеру вверх / вниз вдоль оси Y в противоположность оси Z). Есть способ сделать это? OrbitControls - это способ добраться туда или это только добавляет сложности? Вот мое приложение. 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>

Ответы [ 2 ]

1 голос
/ 17 января 2020

У меня нет деталей вашего проекта, но вам нужно реализовать свой собственный модуль коляски.

Как я могу сделать это Teo?

Ну, мой молодой падаван, нам нужно реализовать функцию, которая перемещает камеру вверх / вниз, как вы упомянули.

Итак, вы имеете в виду, что OrbitControls просто добавляет сложность?

Теперь, если это единственная камера, которая вам нужна, тогда вы делаете, добавляя OrbitControls.

Давайте реализуем это.

Сначала мы добавим window.addEventListener('wheel', onMouseWheel, false);, чтобы прослушать колесо мыши. Теперь мы вызываем метод event.preventDefault(); для предотвращения масштабирования.

Теперь вычисляем модификатор прокрутки camera.position.y += event.deltaY / 1000;. В этом случае мы используем дельту по оси Y. Для этого примера значение было настолько высоким, что я разделил его на 1000, чтобы получить более плавную прокрутку.

Наконец, мы добавляем camera.position.clampScalar(0, 10);, чтобы предотвратить прокрутку за пределы.

var camera, scene, renderer;
var 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>
1 голос
/ 17 января 2020

Если вертикальная прокрутка - это нужное вам поведение only , то да, добавление OrbitControls добавляет ненужную сложность, потому что вы можете легко добиться этого с помощью JavaScript API по умолчанию:

// Add listener to respond to the "wheel" event
window.addEventListener("wheel", onMouseWheel);

function onMouseWheel(event){
    camera.position.y += event.deltaY * 10;
}

Множитель * 10 зависит от размера вашей сцены и от того, насколько быстро вы хотите, чтобы ваша камера двигалась вертикально.

...