Creates a new MouseEventManager instance.
The Three.js scene containing interactive objects
The camera used for raycasting calculations
The HTML canvas element to attach pointer event listeners
Optional
option: {Optional configuration parameters
Optional
recursive?: booleanWhether to recursively search object hierarchies during raycasting (default: true)
Optional
targets?: Object3D<Object3DEventMap>[]Array of specific objects to test for intersections (default: scene.children)
Optional
throttlingTime_ms?: numberThrottling interval in milliseconds (default: 33ms for ~30fps)
Optional
viewport?: Vector4Viewport region for multi-viewport applications (Vector4: x, y, width, height)
Initializes the interaction management system by setting up pointer event listeners and registering with RAFTicker for throttled updates. The manager immediately begins processing pointer interactions according to the specified configuration.
Configuration Guidelines:
throttlingTime_ms
(16ms) for responsive interactions at cost of performancerecursive: false
when using pre-registered targets
array for optimizationviewport
for applications using WebGLRenderer.setViewport()targets
to known interactive objects to reduce intersection testing overheadRecursive Flag Behavior:
The recursive
parameter is passed directly to Three.js Raycaster.intersectObjects() and only
affects raycasting intersection detection. It does NOT affect the parent hierarchy traversal
performed by checkTarget(). This means:
recursive: true
(default): Raycaster tests all descendants of target objectsrecursive: false
: Raycaster tests only the direct target objects specifiedrecursive: false
, if a child object is hit during raycasting,
checkTarget() will still traverse upward to find parent ClickableGroup objectstargets
array with recursive: false
, child objects
not in the targets array will not be detected by raycasting, preventing parent ClickableGroups
from receiving events even if they would be found during hierarchy traversal// Basic setup
const manager = new MouseEventManager(scene, camera, canvas);
// Performance-optimized setup
const fastManager = new MouseEventManager(scene, camera, canvas, {
throttlingTime_ms: 16, // 60fps for responsive UI
recursive: false, // Skip hierarchy traversal
targets: [button1, button2] // Test only specific objects
});
// Multi-viewport application
const viewportManager = new MouseEventManager(scene, camera, canvas, {
viewport: new Vector4(100, 100, 400, 300) // x, y, width, height
});
Protected
cameraProtected
canvasProtected
currentProtected
hasProtected
mouseProtected
raycasterProtected
recursiveProtected
sceneProtected
targetsProtected
throttlingProtected
Optional
viewportProtected
checkProtected
Searches for interactive objects by traversing up the parent hierarchy from a target object.
The Three.js Object3D to start searching from (may be null/undefined)
The type of interaction event to process ("down", "up", "over", "out")
Whether any interactive target has been found in the current search chain
True if an interactive object was found and processed, false otherwise
Performs upward traversal through the Three.js object hierarchy to locate objects implementing the IClickableObject3D interface. When an interactive object is found, it processes the specified event type and may continue searching parent objects for additional interactive targets.
Hierarchy Traversal Process:
Independence from Raycasting Recursive Flag:
This hierarchy traversal operates independently of the constructor's recursive
flag.
Even when recursive: false
is set for raycasting optimization, this method will
still traverse upward to find parent ClickableGroup objects once an initial
intersection is detected.
Event Processing: When an interactive object is found, the method delegates to onButtonHandler() for actual event processing. For "over" events, it also maintains the currentOver array to track hover state across multiple objects.
Recursive Search: The method can find multiple interactive objects in a single parent chain, allowing nested interactive elements where both child and parent respond to the same pointer event.
Protected
clearClears hover states for a specific pointer or all pointers.
Optional
pointerId: numberThe ID of the pointer to clear hover state for. If undefined, clears hover states for ALL pointers.
Cleans up DOM event listeners and RAF ticker subscriptions.
Removes all event listeners attached to the canvas element and unsubscribes from RAFTicker to prevent memory leaks. Call this method when the MouseEventManager is no longer needed, especially in long-running applications that recreate managers (e.g., during scene rebuilds).
The method performs comprehensive cleanup by:
// Clean up before recreating the manager
manager.dispose();
manager = new MouseEventManager(newScene, newCamera, canvas);
// In a React component unmount
useEffect(() => {
const manager = new MouseEventManager(scene, camera, canvas);
return () => manager.dispose(); // Cleanup on unmount
}, []);
// When switching scenes
oldManager.dispose();
const newManager = new MouseEventManager(newScene, newCamera, canvas);
Protected
getProtected
Performs raycasting to detect object intersections and filters duplicate results.
The pointer event containing screen coordinates
Array of intersection results filtered by unique Object3D instances
Wraps Three.js raycasting functionality to detect objects intersected by the pointer. Converts screen coordinates to normalized device coordinates, performs raycasting against configured targets, and filters results to prevent duplicate detections from multi-face geometry intersections.
Processing Steps:
Duplicate Filtering: Single Mesh objects with complex geometry can generate multiple intersection results when the ray hits multiple faces. UUID-based filtering ensures each Object3D appears only once in the results, using the closest intersection.
Protected
onHandles pointer move events with throttling and over/out state management.
The pointer move event from the DOM
Processes pointer movement by performing raycasting to detect object intersections and managing hover state transitions. The method implements conditional throttling to prevent excessive raycasting during rapid pointer movements, which significantly improves performance in complex scenes.
Throttling Behavior:
The method checks throttling status (if enabled), performs raycasting, processes intersections in Z-order, updates hover targets, and emits "out"/"over" events as needed.
The method maintains a currentOver array to track hovered objects and compares new intersection results with the previous state to determine event needs.
Protected
onHandles pointer down and up events for interactive objects.
The pointer down or up event from the DOM
Processes pointer press and release events by performing raycasting to identify intersected objects and delegating the appropriate event type ("down" or "up") to their interaction handlers. The method includes viewport boundary checking for multi-viewport applications.
The method maps "pointerdown" to "down" and "pointerup" to "up" interaction events.
For "down" events, validates pointer position within configured viewport boundaries to ensure interactions only occur within the designated rendering region.
The method determines event type, validates viewport boundaries for down events, performs raycasting, and processes intersections in Z-order with early termination.
Protected
onHandles pointer cancel events for interrupted touch interactions.
The pointer cancel event containing the interrupted pointerId
Processes pointercancel events by preventing default behavior and delegating cleanup to the common cleanup method.
Browser Event Sequence: pointercancel → pointerout → pointerleave Mutual Exclusivity: pointercancel and pointerup never both occur Timing: preventDefault() called when cancelable to maintain consistent behavior
Protected
onHandles browser-generated pointerleave events for reliable cleanup.
The pointerleave event from browser
Processes pointerleave events by delegating cleanup to the common cleanup method.
Why pointerleave is optimal:
Static
onDispatches interaction events to the appropriate handler methods.
The interactive object to receive the event
The type of interaction event to dispatch
Static utility method that serves as the central event dispatcher for all interactive objects. It creates the appropriate ThreeMouseEvent and delegates to the correct handler method on the object's ButtonInteractionHandler.
Event Routing:
Direct Delegation: This method performs direct event delegation without duplicate checking or state validation. Individual ButtonInteractionHandler instances manage their own event duplicate suppression and state validation as appropriate for their specific interaction patterns.
Event Object Creation: Uses createThreeMouseEvent() to create properly formatted event objects that include the event type, interaction handler reference, and selection state (for checkbox/radio button objects).
Central event dispatcher for handling pointer interactions in Three.js scenes.
Description
MouseEventManager serves as the core interaction management system for Three.js applications, providing unified pointer interaction handling across mouse, touch, and pen input devices. It uses raycasting to detect object intersections and manages event distribution to interactive objects through a performance-optimized pipeline.
The manager listens to DOM pointer events, performs raycasting to identify intersected objects, traverses parent hierarchies to find IClickableObject3D implementations, and delegates events to appropriate ButtonInteractionHandler instances.
Performance Optimizations:
Multi-Viewport Support: Compatible with Three.js WebGLRenderer.setViewport() for applications rendering multiple scenes or cameras to different canvas regions. The manager determines the corresponding viewport for each pointer event and processes only relevant objects.
Example
Remarks
See