Threejs Interaction
Add rich user interactions to Three.js scenes with automation and integration
Three.js Interaction is a community skill for adding user interaction to Three.js scenes, covering raycasting, mouse and touch events, drag controls, object selection, and responsive interaction for 3D web experiences.
What Is This?
Overview
Three.js Interaction provides guidance on implementing user interaction with 3D objects in Three.js scenes. It covers raycasting that detects which objects the user clicks or hovers over in 3D space, mouse and touch events that translate screen coordinates to 3D world positions, drag controls that enable object manipulation through click-and-drag gestures, object selection that highlights and tracks user-picked objects with visual feedback, and responsive interaction that handles input across desktop and mobile devices. The skill helps developers build interactive 3D applications.
Who Should Use This
This skill serves web developers building interactive 3D product viewers, game developers adding click and drag mechanics, and creative developers building immersive web experiences.
Why Use It?
Problems It Solves
3D scenes without interaction feel static and unengaging. Converting 2D screen clicks to 3D object hits requires raycasting knowledge. Implementing drag-and-drop in 3D space needs proper coordinate transformation. Touch and mouse events behave differently and need unified handling.
Core Highlights
Raycaster detects 3D object intersections from screen clicks. Event handler normalizes mouse and touch input. Drag controller enables object movement in 3D space. Selection manager tracks picked objects with visual highlights.
How to Use It?
Basic Usage
// Raycasting interaction
import * as THREE from
'three';
class Interactor {
constructor(
camera, domElement
) {
this.camera = camera;
this.raycaster =
new THREE.Raycaster();
this.mouse =
new THREE.Vector2();
this.objects = [];
this.selected = null;
domElement
.addEventListener(
'click',
(e) => this
.onClick(e));
domElement
.addEventListener(
'mousemove',
(e) => this
.onMove(e));
}
onClick(event) {
this._updateMouse(
event);
this.raycaster
.setFromCamera(
this.mouse,
this.camera);
const hits =
this.raycaster
.intersectObjects(
this.objects);
if (hits.length > 0) {
this.select(
hits[0].object);
} else {
this.deselect();
}
}
onMove(event) {
this._updateMouse(
event);
}
select(obj) {
this.deselect();
this.selected = obj;
obj.material
.emissive?.set(
0x444444);
}
deselect() {
if (this.selected) {
this.selected
.material
.emissive?.set(0);
this.selected = null;
}
}
_updateMouse(e) {
this.mouse.x =
(e.clientX
/ innerWidth)
* 2 - 1;
this.mouse.y =
-(e.clientY
/ innerHeight)
* 2 + 1;
}
}
// const inter =
// new Interactor(
// camera, canvas);
// inter.objects = cubes;Real-World Examples
// Drag controls
import * as THREE from
'three';
class DragHandler {
constructor(
camera, plane
) {
this.camera = camera;
this.plane = plane;
this.raycaster =
new THREE.Raycaster();
this.mouse =
new THREE.Vector2();
this.dragging = null;
this.offset =
new THREE.Vector3();
this.intersection =
new THREE.Vector3();
}
startDrag(
object, event
) {
this.dragging = object;
this._getPlanePoint(
event);
this.offset.copy(
this.intersection)
.sub(
object.position);
}
drag(event) {
if (!this.dragging)
return;
this._getPlanePoint(
event);
this.dragging
.position.copy(
this.intersection)
.sub(this.offset);
}
endDrag() {
this.dragging = null;
}
_getPlanePoint(e) {
this.mouse.set(
(e.clientX
/ innerWidth)
* 2 - 1,
-(e.clientY
/ innerHeight)
* 2 + 1);
this.raycaster
.setFromCamera(
this.mouse,
this.camera);
this.raycaster.ray
.intersectPlane(
this.plane,
this.intersection);
}
}
const groundPlane =
new THREE.Plane(
new THREE.Vector3(
0, 1, 0), 0);
// const dragger =
// new DragHandler(
// camera,
// groundPlane);Advanced Tips
Set raycaster layers to limit intersection tests to interactive objects for better performance. Use pointer events instead of separate mouse and touch handlers for unified input. Throttle mousemove raycasts to reduce CPU overhead during continuous hovering.
When to Use It?
Use Cases
Build a product configurator where users click to select parts and change colors. Create a 3D editor with drag-and-drop object placement on a ground plane. Implement hover tooltips that display information when the cursor passes over 3D objects.
Related Topics
Three.js, raycasting, mouse events, touch interaction, drag controls, 3D picking, and user input handling.
Important Notes
Requirements
Three.js library with Raycaster support for intersection testing. A canvas element with proper event listeners for mouse and touch input. Objects using materials with appropriate properties for visual selection feedback.
Usage Recommendations
Do: normalize screen coordinates to the range of negative one to positive one for correct raycasting. Use object layers to separate interactive and non-interactive elements. Provide visual feedback like color changes on hover and selection.
Don't: run raycasts against all scene objects since this is slow for complex scenes. Forget to handle touch events separately since they have different coordinate properties. Attach event listeners to individual 3D objects since Three.js uses raycasting rather than DOM events.
Limitations
Raycasting performance decreases with the number of objects tested per frame. Complex mesh geometry produces slower intersection tests than simple bounding box checks. Touch interaction on mobile lacks hover state which requires alternative UI patterns for discovery.
More Skills You Might Like
Explore similar skills to enhance your workflow
Anndata
Automate AnnData processing and integrate large-scale genomic data analysis into your research workflows
Lemon Squeezy Automation
Automate Lemon Squeezy tasks via Rube MCP (Composio): products,
Scikit Bio
Automate and integrate Scikit Bio for powerful bioinformatics data analysis workflows
Adrapid Automation
Automate Adrapid operations through Composio's Adrapid toolkit via Rube
Browser Automation
Automate web browser interactions using natural language via CLI commands. Use when the user
Web App Testing
Enhance web app quality with automated testing skills for AI and tech tool integration