In this section, we'll explore how to make your Three.js creations interactive using keyboard input. This is a fundamental aspect of creating engaging 3D experiences, allowing users to navigate scenes, control objects, and trigger actions with simple key presses.
Three.js doesn't directly handle keyboard events. Instead, we leverage the browser's built-in event listeners. The most common events we'll use are 'keydown' and 'keyup'. These events fire when a key is pressed down and released, respectively.
To listen for these events, we attach event listeners to the window object. The event listener function will receive an event object, which contains information about the key that was pressed, such as its keyCode or key property.
window.addEventListener('keydown', (event) => {
console.log(`Key pressed: ${event.key}`);
});
window.addEventListener('keyup', (event) => {
console.log(`Key released: ${event.key}`);
});The event.key property provides a human-readable string representing the key (e.g., 'ArrowUp', 'w', 'Enter'). The event.keyCode property (though deprecated in favor of event.key) provides a numerical code for the key. For consistency and future-proofing, event.key is generally preferred.
A common pattern for handling keyboard input is to maintain a state object that tracks which keys are currently being pressed. This is particularly useful for continuous movement, like walking or flying through a scene.
const keysPressed = {};
window.addEventListener('keydown', (event) => {
keysPressed[event.key] = true;
});
window.addEventListener('keyup', (event) => {
keysPressed[event.key] = false;
});
// In your animation loop:
if (keysPressed['w']) {
// Move forward
}
if (keysPressed['a']) {
// Move left
}To implement movement, we can modify the position or rotation of our camera or a specific object in our animation loop based on the keys being pressed. For example, to move a camera forward, we'd adjust its position.z property.
const cameraMoveSpeed = 0.1;
function animate() {
requestAnimationFrame(animate);
if (keysPressed['w']) {
camera.position.z -= cameraMoveSpeed;
}
if (keysPressed['s']) {
camera.position.z += cameraMoveSpeed;
}
if (keysPressed['a']) {
camera.position.x -= cameraMoveSpeed;
}
if (keysPressed['d']) {
camera.position.x += cameraMoveSpeed;
}
renderer.render(scene, camera);
}For more complex controls, like first-person camera movement, you might also need to handle mouse input for looking around. This typically involves tracking mouse movement and rotating the camera accordingly. We'll touch upon that in a later section.
graph TD;
A[User Presses Key] --> B{Event Listener Fires (keydown/keyup)};
B --> C{Update keysPressed State Object};
C --> D{Animation Loop Checks State};
D -- Key Pressed --> E[Apply Transformation (e.g., move camera)];
E --> F[Render Scene];
D -- Key Not Pressed --> F;
It's important to choose appropriate keys for your controls. Common conventions include WASD keys for movement and arrow keys for directional control. Providing visual feedback to the user, like highlighting an object when it's selected and controllable, can greatly enhance usability.