Threejs基于TransfromControls控制器实现单方向缩放
Threejs基于TransfromControls控制器实现单方向缩放
一、前言
我们遇到了这样的问题,创建一个长方体,当鼠标选中X轴正方向拉伸时,其负方向的部分要不拉伸,视觉效果为固定一面不动。官方自带的TransfromControls,是同时缩放X、Y、Z缩放轴的正负轴,拉伸一边另外一边也随之而动。不满足我们的需要,需要通过特殊的方式去处理。
二、正确的思路
- 缩放还是要缩放的,只是缩放的同时要控制物体沿着缩放的方向进行正确的移动,看上去就实现了固定一边
- 实现的效果在多边缩放时无法预知移动的方向,所以只有沿着 X Y Z的某方向缩放才能实现,XY XZ YZ这样的缩放仍然是沿用官方插件的实现
三、代码实现
1.不改动TransfromControls源码的方式
- 监听渲染场景的鼠标click事件,选中对象时计算出,相对中心点的拖拽方向向量,后面计算的时候用
_self.renderer.domElement.addEventListener('click', function (event) {
event.preventDefault();
if (!_self.elem) return;
let mouse = new THREE.Vector2();
let raycaster = new THREE.Raycaster();
let top = _self.offsetTop(_self.elem);
let left = _self.offsetLeft(_self.elem);
mouse.x = ((event.clientX - left) / _self.elem.clientWidth) * 2 - 1;
mouse.y = -((event.clientY - top) / _self.elem.clientHeight) * 2 + 1;
raycaster.setFromCamera(mouse, _self.camera);
let intersects = raycaster.intersectObjects(_self.scene.children);
if (intersects.length > 0) {
let object = intersects[0].object;
if (object.userData.type == null) return false;
//就在点击的时候就存下相对位置
_self.point = intersects[0].point.clone().sub(object.position);
_self.point.x = Math.sign(_self.point.x);
_self.point.y = Math.sign(_self.point.y);
_self.point.z = Math.sign(_self.point.z);
_self.transformControl.attach(object)
_self.prevScale.copy(object.scale);
}
});
- 监听TransfromControls的objectChange,缩放的同时计算要移动的距离
_self.transformControl.addEventListener('objectChange', function () {
let object = _self.transformControl.object;
let curScale = object.scale.clone();
let direction = curScale.clone().sub(_self.prevScale);
//只有缩放模式起作用 而且只对单一缩放起作用
if(_self.transformControl.getMode() === 'scale'){
object.geometry.computeBoundingBox();
let distance = object.geometry.boundingBox.getSize(new THREE.Vector3()).multiplyScalar(0.5).multiply(direction).multiply(_self.point);
//得到了移动方向 判断移动的是哪个轴
//通过鼠标点位置相对于 矩形中心点位置来判断是负方向还是正方向 相对位置是正则正 负则负
//一起判断移动的相对正负 仅仅对轴的缩放起作用
if(direction.x != 0 && direction.y == 0 && direction.z == 0
|| direction.x == 0 && direction.y != 0 && direction.z == 0
|| direction.x == 0 && direction.y == 0 && direction.z != 0){
object.position.add(distance);
}
}
// 更新上一个缩放值
_self.prevScale.copy(curScale);
});
2.改动TransfromControls
- 思路魔改的TransfromControls,在它的object中存储拖拽的方向
下载地址 https://files.cnblogs.com/files/lovefoolself/TransformControls.js?t=1706152892&download=true - 代码实现
![image]()


浙公网安备 33010602011771号