One of the most engaging aspects of 3D web experiences is the ability to bring objects to life through animation, and even more so when that animation is directly controlled by the user's actions. In this section, we'll explore how to trigger animations in response to user input, making your Three.js scenes feel dynamic and interactive.
The core idea is to listen for specific user events, such as mouse clicks, keyboard presses, or mouse movements, and then use those events to alter an object's properties over time. This often involves manipulating the object's rotation, position, or scale.
A common way to manage animations is by using the requestAnimationFrame loop. This function tells the browser that you want to perform an animation and requests that your browser call a specified function to update an animation before the next repaint. Inside this loop, we can check if an animation is active and update the object's transformation accordingly. We'll then use a flag or a state variable to control whether the animation should be running.
let isAnimating = false;
let objectToAnimate = null;
function animate() {
requestAnimationFrame(animate);
if (isAnimating && objectToAnimate) {
objectToAnimate.rotation.y += 0.01;
}
renderer.render(scene, camera);
}
animate();Now, let's tie this animation loop to user input. For instance, we can use a click event listener on the renderer.domElement (the canvas where your 3D scene is rendered) to toggle the isAnimating flag.
renderer.domElement.addEventListener('click', () => {
isAnimating = !isAnimating;
});When the canvas is clicked, the isAnimating variable will flip its value. If it was false, it becomes true, and the animation inside the requestAnimationFrame loop will start for objectToAnimate. If it was true, it becomes false, and the animation will pause.
We also need to ensure that objectToAnimate is properly assigned. This could be done by selecting an object from the scene, perhaps by raycasting or by having a reference to it. Let's assume you have a reference to a cube object called myCube.
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const myCube = new THREE.Mesh(geometry, material);
scene.add(myCube);
let objectToAnimate = myCube;To make the interaction even more intuitive, you might want to highlight or indicate which object can be interacted with. This can be achieved using a simple cursor change on hover or by visually distinguishing the clickable object.
Consider other input methods as well. Keyboard input can be used to control more complex movements. For example, pressing the 'W' key could move an object forward, 'S' backward, 'A' left, and 'D' right. This involves adding event listeners for keydown and keyup events.
document.addEventListener('keydown', (event) => {
if (event.key === 'w' && objectToAnimate) {
objectToAnimate.position.z -= 0.1;
}
if (event.key === 's' && objectToAnimate) {
objectToAnimate.position.z += 0.1;
}
});For more sophisticated animations, like smooth transitions or physics-based movements, you might integrate animation libraries like GSAP (GreenSock Animation Platform) or explore Three.js's built-in animation capabilities with Tweens from the THREE.js/examples/jsm/math/Interpolant.js or external libraries like tween.js. These libraries offer powerful ways to interpolate values over time, creating fluid and complex animations driven by user actions.
graph TD
A[User Input Event] --> B{Check Event Type}
B -- Click --> C{Toggle Animation Flag}
B -- Key Press --> D{Update Object Transform}
C --> E[Animation Loop]
D --> F[Render Scene]
E --> F
F --> G[Display on Screen]