Three.JS模块化引入轨道控制器OrbitControls.JS(ES6语法)

你。 提交于 2019-12-12 10:36:26

three.js模块化开发

项目中用到Three.js来构建场景,现在想用ES6语法将代码重构一遍,投入模块化开发的怀抱。同时也将这个过程中的经验记录下来,当作知识点备用。
环境是vue-cli^4.1.0,下载了Three的npm包版本^0.105.2

亲测可用的引入方式

在three的这一版本的包中,可以在example的jsm文件夹下找到orbitControls.js文件。可用使用import的方式将其引入到需要的文件中

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
this.controls = new OrbitControls(this.camera,this.renderer.domElement)

这样就成功引入了轨道控制器,可以根据自己的需要设置具体的控制器参数。如是否开启缩放,是否自动旋转,是否支持拖动等等。
下面给出了我常用的设置轨道控制器参数的例子

    // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
    this.controls.dampingFactor = 0.5;
    // 是否可以缩放
    this.controls.enableZoom = true;
    //是否自动旋转
    this.controls.autoRotate = false;
    //设置相机距离原点的最近距离
    this.controls.minDistance = 20;
    //设置相机距离原点的最远距离
    this.controls.maxDistance = 1000;
    //是否开启右键拖拽
    this.controls.enablePan = true;
    //上下翻转的最大角度
    this.controls.maxPolarAngle = 1.5;
    //上下翻转的最小角度
    this.controls.minPolarAngle = 0.0;
    // 是否可以旋转
    // this.enableRotate = true

报错:Unable to preventDefault inside passive event listener

在实际使用中,当我拖动或者缩放时会报上述错误,控制台的报错信息如下
在这里插入图片描述
然后去OrbitControls.js文件中看,发现监听的事件绑定为如下所示

document.addEventListener( 'mousemove', onMouseWheel, false );
document.addEventListener( 'mouseup', onMouseDown, false );

onMouseWheel的方法中写的是如下图所示
在这里插入图片描述
event.preventDefault()没有阻止默认行为

查询博客得知

由于浏览器必须要在执行事件处理函数之后,才能知道有没有调用过 preventDefault() ,这就导致了浏览器不能及时响应滚动,略有延迟。

所以为了让页面滚动的效果如丝般顺滑,从 chrome56 开始,在 window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,会默认为是 passive: true。浏览器忽略 preventDefault() 就可以第一时间滚动了。

举例:
wnidow.addEventListener('mousemove', func) 效果和下面一句一样
wnidow.addEventListener('mousemove', func, { passive: true })

导致问题:
如果mousemove事件处理函数中调用 e.preventDefault() ,会被浏览器忽略掉,并不会阻止默认行为。

解决办法

注册监听事件时,增加{passive:false},这样一来,无论是对场景进行任何鼠标事件都不会报错了。

// 注册处理函数时,用如下方式,明确声明为不是被动的
window.addEventListener('mousemove', onMouseMove, { passive: false })

参考博客

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!