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

2024-01-15

你怎么做到这一点?我使用创建了一个场景三.js编辑器 https://threejs.org/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>

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

我该怎么做,特奥?

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

所以,你的意思是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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • Flutter:如何更新单个列表项的 ValueNotifier

    我有一个列表生成器 用于创建包含内容的卡片 在这张卡中 我有一个按钮和文本小部件 基本上 我想在按下按钮时更新文本小部件 我尝试使用 ValueNotifier 并且它有效 但它会更新每个列表项的值 这是主要功能 我创建了 ValueNot
  • HTTP 范围:使用 WebClient C# 的字节

    我正在尝试恢复文件下载 我使用下面的代码成功下载了我需要的文件 downlaodfile new WebClient downlaodfile Headers Add Range bytes 0 600000 downlaodfile Do
  • DOCTYPE 的选择是否会影响 javascript 代码所看到的 DOM?

    鉴于一个利用 ASP NET javascript css 等技术的大型遗留项目 我想知道是否以任何方式更改网页的 DOCTYPE 例如从 HTML 4 0 Transitional 到 XHTML 1 0 Transitional 或其他
  • 如何将多列乘以另一列pandas

    我有一个 100 列的数据框 我想将一列 计数 值与范围从 6 到 74 的列位置相乘 请告诉我该怎么做 我已经试了 df df ix 0 6 74 multiply df Count axis index df df df columns
  • Django:Bootstrap CDN 或从本地服务器加载 Bootstrap 文件?

    我正在尝试制作我的第一个网站 我正在使用 Django 我有一个与 Bootstrap 中包含 css js 相关的问题 安装它和使用链接它有什么区别BootstrapCDN 如果该链接无法再访问会发生什么 会影响网站吗 我不能将这些文件包
  • Javascript,固定一位小数,除了为 0 时

    我需要将小数点后的数字固定为小数点后一位 所以我尝试了以下方法 const convert numberWithDecimal gt numberWithDecimal toFixed 1 replace replace d d 3 d g
  • 如何从spring资源获取文件

    我有一个资源对象 org springframework core io ClassPathResource 我需要获取 File 对象 但是resource getFile 抛出异常文件未找到 但调用后resource getURI 我有
  • DbMigrator - 详细的代码优先迁移

    使用包管理器控制台时 您可以运行以下命令 PM gt Update Database Verbose The Verboseswitch 会将所有尝试的 SQL 命令写入控制台窗口 这对于调试非常有用 您可以使用DbMigrator类在代码
  • 无法将图像传递给另一个类

    我正在尝试将图像传递给另一个类intent but 它只适用于captured image 不是为了image selected from gallery 这是相机功能开始的地方 ImageFitScreen java 它有一个ok用于返回
  • 浏览器渲染和 JavaScript 执行的同步/异步性质

    我有一些处理需要花费几秒钟 所以我想在处理过程中添加一个视觉指示器 processing background color ff0000 div Processing div Script mydiv addClass processing
  • Skobbler SDK Android - SKNavigationState 对象损坏/不一致

    我们确实遇到了 SKNavigationState 更新与 Android 的一些不一致问题 有时 我们在开始导航后会得到不一致的 SKNavigationState 对象 因此导航停止工作 奇怪的是 有时它确实有效 首先 我们怀疑某些构建
  • 用于列出所有打开的资源管理器窗口的 Powershell 脚本

    这个问题 https stackoverflow com questions 31347905 get report of all open explorer windows显示了一个 Powershell 脚本 用于生成打开的文件资源管理
  • 通过命令行使用苏门答腊pdf批量打印pdf

    自从 Adob e 发布了 Adob e Reader 的新更新 2014 年 9 月 16 日的 11 09 以来 我们在通过命令行打印 pdf 文件时遇到了问题 我们的正式脚本如下所示 job for F tokens 1 delims
  • vuex 未加载用 vuex-module-decorators 装饰的模块

    当尝试将带有 vuex module decorators 的存储模块加载到初始化程序中时 我收到此错误 vuex esm js 2f62 261 未捕获类型错误 无法读取属性 Array forEach 的 eval vuex esm j
  • 在 SQL Server 中存储大量 XML 类型数据的最佳实践

    是否有人可以分享有关在 SQL Server 2008 中存储 XML 字段类型数据的最佳实践 我们有很多小型 XML 结构 但也有一些较大 gt 50MB 我们发现删除时速度有点慢 任何建议 战争故事将不胜感激 我发现到目前为止大多数答案
  • SELECT 语句中有多个条件?

    首先 我没有 ABAP 经验 我在这里只是猜测 我想向现有报表中的 SELECT 添加条件 现有代码如下所示 SELECT SINGLE FROM EKPO WHERE EBELN GT MSEG EBELN AND EBELP GT MS
  • 更改PostgreSQL 9.6中某种数据类型表中的所有列

    似乎几个月前我遇到了一个涉及此问题的问题 但现在我似乎找不到了 基本上 我想做两件事 首先 制作了许多表格 其中有几列numeric 20 2 我想把它们全部改为numeric 对于一列来说 该语句很简单 ALTER TABLE table
  • 如何更改 Visual Studio Code 中的 UI 语言?

    如何更改 UI 语言视觉工作室代码 https code visualstudio com 1 0 于 2016 年 4 月发布 打开VScode 按 F1 并输入 显示 选择 配置显示语言 选择你的语言 上面是已安装的语言 下面是其他语言
  • 如何用Java连接MySQL?

    我已经安装了MYSQL服务器5 1 然后我安装了 mysql connector java 3 0 8 stable bin jar 并将其放入驱动器 c 中 文件夹 core 为 C core 然后在计算机的属性中 我创建带有变量名 CL
  • Three.js 鼠标滚轮用于向上/向下移动相机而不是放大/缩小

    你怎么做到这一点 我使用创建了一个场景三 js编辑器 https threejs org editor 并使用 发布 选项下载该项目 我编辑了 app js 文件以导入 OrbitControls 因此现在我可以使用鼠标滚轮 或者在我的情况