So far, we've explored creating static 3D scenes. But the real magic of 3D on the web often comes alive when things move in response to the user. In this section, we'll delve into how to trigger animations based on user interactions, such as mouse clicks, hovers, or even keyboard presses. This transforms passive viewers into active participants.
The core idea is to link a user event to a change in an animation property. In Three.js, animations are often controlled by properties like rotation, position, scale, or even material properties like color. We'll use JavaScript event listeners to detect user actions and then update these properties over time.
Let's start with a simple example: making an object rotate when the user clicks on it. We'll need to set up an event listener on the renderer's DOM element.
const canvas = renderer.domElement;
canvas.addEventListener('click', onClick);
function onClick(event) {
// Determine if the click intersected with our object
// If it did, start an animation or toggle a state
}To determine if the click actually hit our 3D object, we can use a Raycaster. A Raycaster shoots a ray from a point in the scene (in this case, the mouse click's position) and checks for intersections with objects. If an intersection is found, we know the user clicked on that specific object.
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onClick(event) {
// Calculate mouse position in normalized device coordinates (-1 to +1)
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
// Update the picking ray with the camera and mouse position
raycaster.setFromCamera(mouse, camera);
// Calculate objects intersecting the picking ray
const intersects = raycaster.intersectObjects(scene.children);
for (const intersect of intersects) {
if (intersect.object === myMesh) { // myMesh is the object we want to animate
// Trigger animation here!
isAnimating = !isAnimating; // For example, toggle an animation
break;
}
}
}Once we've detected a click on our target object, we can then trigger an animation. A common way to manage animations is to use a boolean flag that controls whether the animation logic in our requestAnimationFrame loop should run.