DragControls 是 Three.js 提供的一个控制器,用于在 3D 场景中通过鼠标或触控拖拽物体。它的主要作用是帮助开发者在交互式的 Three.js 项目中更轻松地实现拖动操作。
注意,这个拖放控制主要功能是将场景中的物体直接通过属标控制位置,极大的简化了 three 中对物体位置操作的使用
DragControls 有五个属性五个事件
DragControls( objects : Array, camera : Camera, domElement : HTMLDOMElement ) objects: 一组可被拖拽的3D Objects。 camera: 渲染场景的摄像机。 domElement: 用于事件监听的HTML元素。(可选) 创建一个新的 DragControls 实例。
// 添加环境光和点光源
const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(5, 5, 5);
scene.add(pointLight);
// 创建一个可拖拽的立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 设置拖拽对象数组(这里是单个立方体)
const objects = [cube];
// 初始化 OrbitControls 以便旋转视角
const orbitControls = new OrbitControls(camera, renderer.domElement);
// 创建 DragControls 控制器
const dragControls = new DragControls(objects, camera, renderer.domElement);
// 监听拖拽事件
dragControls.addEventListener('dragstart', (event) => {
orbitControls.enabled = false; // 禁用 OrbitControls,防止拖拽冲突
event.object.material.color.set(0xff0000); // 开始拖拽时改变颜色
});
dragControls.addEventListener('drag', (event) => {
console.log("拖拽中,位置:", event.object.position); // 输出拖拽位置
});
dragControls.addEventListener('dragend', (event) => {
orbitControls.enabled = true; // 重新启用 OrbitControls
event.object.material.color.set(0x00ff00); // 结束拖拽时恢复颜色
});
事件
- dragstart 当用户开始拖拽3D Objects时触发。
- drag当用户拖拽3D Objects时触发。
- dragend 当用户开始完成3D Objects时触发。
- hoveron 当指针移动到一个3D Object或者其某个子级上时触发。
- hoveroff 当指针移出一个3D Object时触发。
属性
- objects : Array 可拖放对象的数组。
- raycaster : Raycaster 内部用于检测拾取对象的光线投射器。
- recursive : Boolean 可拖放对象的子对象是否可以独立于其父对象进行拖放。 默认值为 true。在 Three.js 中,DragControls 的 .recursive: Boolean 参数用于控制可拖拽对象的子对象是否可以独立拖动。这个选项的默认值是 true,意味着子对象默认情况下是可以被单独拖动的,而不依赖于父对象。dragControls.recursive = false:设置 recursive 为 false 后,即便在 objects 数组中包含了父对象 parentCube,其子对象 childCube 也不会被单独拖动。只有在拖动 parentCube 时,childCube 才会随之移动。
// 创建父对象和子对象
const parentGeometry = new THREE.BoxGeometry(2, 2, 2);
const parentMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const parentCube = new THREE.Mesh(parentGeometry, parentMaterial);
scene.add(parentCube);
const childGeometry = new THREE.BoxGeometry(1, 1, 1);
const childMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff });
const childCube = new THREE.Mesh(childGeometry, childMaterial);
childCube.position.set(1.5, 0, 0); // 子对象在父对象右侧
parentCube.add(childCube);
// 设置拖拽对象数组(包含父对象)
const objects = [parentCube];
// 创建 DragControls 并设置 recursive 为 false,避免拖动子对象
const dragControls = new DragControls(objects, camera, renderer.domElement);
dragControls.recursive = false; // 禁止单独拖动子对象
- rotateSpeed : Float 执行 rotate 时的旋转速度。该值越大旋转速度越快。 默认值为 1。
- transformGroup : Boolean 当 DragControls.objects 数组包含一个单个可拖拽的组对象时该选项生效。 如果设置为true,DragControls会转换整个组对象,而不对单个对象做转换。默认值为false。在 Three.js 的 DragControls 中,transformGroup: Boolean 参数用于控制是否将选中的多个对象作为一个整体来拖动。默认情况下,这个值为 false,意味着每个对象在拖动时会单独移动。如果将其设置为 true,则所有选中的对象会被视为一个整体并一起移动。
// 创建多个对象并添加到场景中
const objects = [];
const colors = [0xff0000, 0x00ff00, 0x0000ff];
for (let i = 0; i < 3; i++) {
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: colors[i] });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(i * 2 - 2, 0, 0); // 分散放置
scene.add(cube);
objects.push(cube); // 将每个对象添加到拖拽对象数组中
}
// 创建 DragControls 并启用 transformGroup,将多个对象视为一个整体
const dragControls = new DragControls(objects, camera, renderer.domElement);
dragControls.transformGroup = true; // 设置为 true,将多个对象作为一个整体拖动