模块中引入OrbitControls
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 })
来源:CSDN
作者:端午的一天
链接:https://blog.csdn.net/Demi1024w/article/details/103484422