Three.js DragControls Tutorial: Move Objects with Mouse
This article provides a step-by-step guide on how to implement the
DragControls class in Three.js to select and translate 3D
objects within a scene using a mouse or touch inputs. You will learn how
to import the controller, initialize it with an array of draggable
meshes, and handle event listeners to prevent conflicts with other
camera controls.
Step 1: Import DragControls
DragControls is an add-on and is not included in the
core Three.js namespace. You must import it separately from the examples
directory.
import * as THREE from 'three';
import { DragControls } from 'three/examples/jsm/controls/DragControls.js';Step 2: Set Up Draggable Objects
DragControls requires an array of 3D objects that it is
allowed to interact with. Create your meshes, add them to your scene,
and push them into a dedicated array.
const objects = [];
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
for (let i = 0; i < 5; i++) {
const cube = new THREE.Mesh(geometry, material);
cube.position.set(Math.random() * 4 - 2, 0, Math.random() * 4 - 2);
scene.add(cube);
objects.push(cube); // Add to the tracking array
}Step 3: Initialize DragControls
Instantiate the DragControls class by passing the array
of draggable objects, the active camera, and the DOM element used for
event listeners (usually the renderer’s canvas).
const dragControls = new DragControls(objects, camera, renderer.domElement);Step 4: Deactivate OrbitControls During Dragging (Crucial)
If your scene uses OrbitControls to rotate the camera,
dragging an object will also rotate the screen. To prevent this
conflict, temporarily disable OrbitControls when a drag
event starts, and re-enable it when the drag event ends.
// Assuming orbitControls is already defined
dragControls.addEventListener('dragstart', function (event) {
orbitControls.enabled = false;
event.object.material.emissive.setHex(0x333333); // Highlight the object
});
dragControls.addEventListener('dragend', function (event) {
orbitControls.enabled = true;
event.object.material.emissive.setHex(0x000000); // Reset object color
});Step 5: Clean Up (Optional)
If you ever need to remove the drag controls from your scene to stop
interaction, use the dispose method to remove all internal
event listeners.
// Call this when removing the component or changing scenes
dragControls.dispose();