three.js DragControls +TransformControls 实现沿轴线拖拽功能
DragControls
DragControls 类可以实现对图元的拖拽移动功能,但是移动的方向跟场景的旋转有关,这里加上Transform 类,transform类可以给图元添加一个编辑辅助器,但是拖拽的时候会和场景控制器发生冲突。所以使用DragControls 的开始拖拽和结束拖拽监听取消场景控制器,防止冲突。
// 过滤不是mesh的物体
let objects = [];
for (let i = 0; i < this.scene.children.length; i++) {
if (this.scene.children[i].isMesh) {
objects.push(this.scene.children[i]);
}
}
// 初始化拖拽控件
let dragControls = new DragControls(
objects,
this.camera,
this.renderer.domElement
);
// 鼠标略过事件
dragControls.addEventListener("hoveron", (e) => {
// 让变换控件和选中的对象绑定
transformControls.attach(e.object);
this.box.setFromObject(e.object);
this.renderer.render(this.scene, this.camera);
});
// 开始拖拽
dragControls.addEventListener("dragstart", () => {
this.controls.enabled = false;
this.renderer.render(this.scene, this.camera);
});
// 拖拽结束
dragControls.addEventListener("dragend", () => {
this.controls.enabled = true;
this.renderer.render(this.scene, this.camera);
});
dragControls.addEventListener("drag", () => {
this.renderer.render(this.scene, this.camera);
});
TransformControls
// 添加平移控件
let transformControls = new TransformControls(
this.camera,
this.renderer.domElement
);
this.scene.add(transformControls);
transformControls.addEventListener("change", () => {
this.renderer.render(this.scene, this.camera);
});
注意:DragControls的拖拽实现会影响transformControls 所以需要再修改下DragControls.js的部分代码,注释掉拖拽实现的代码,也可添加个判断的参数按条件忽略这部分代码。
function onPointerMove( event ) {
if ( scope.enabled === false ) return;
updatePointer( event );
_raycaster.setFromCamera( _pointer, _camera );
if ( _selected ) {
// if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
// _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
// }
// scope.dispatchEvent( { type: 'drag', object: _selected } );
return;
}
}