1.pointer-events.md 4.6 KB


title: Pointer Events

description: Explore the TresJS pointer events system powered by @pmndrs/pointer-events.

TresJS provides a comprehensive pointer events system that allows you to interact with 3D objects using mouse, touch, and other pointer devices. The event system is built on top of the powerful @pmndrs/pointer-events package, providing framework-agnostic pointer event handling for Three.js objects.

Basic Usage

Pointer events are automatically enabled in TresCanvas and work seamlessly with all 3D objects. Simply add event listeners directly to your TresJS components:

::examples-pointer-events ::

<script setup lang="ts">
import { ref } from 'vue'

const boxRef = ref()

function onPointerEnter() {
  console.log('Pointer entered the box!')
}

function onPointerLeave() {
  console.log('Pointer left the box!')
}

function onClick() {
  console.log('Box clicked!')
}
</script>

<template>
  <TresCanvas>
    <TresMesh
      ref="boxRef"
      @pointerenter="onPointerEnter"
      @pointerleave="onPointerLeave"
      @click="onClick"
    >
      <TresBoxGeometry />
      <TresMeshNormalMaterial />
    </TresMesh>
  </TresCanvas>
</template>

Available Events

TresJS supports all standard pointer events that you can listen to on any 3D object:

Mouse Events

  • @click - Fired when the object is clicked
  • @doubleclick - Fired when the object is double-clicked
  • @contextmenu - Fired when right-clicking the object
  • @pointerdown - Fired when pointer is pressed down on the object
  • @pointerup - Fired when pointer is released over the object

Hover Events

  • @pointerenter - Fired when pointer enters the object's bounds
  • @pointerleave - Fired when pointer leaves the object's bounds
  • @pointerover - Fired when pointer is over the object
  • @pointerout - Fired when pointer moves away from the object
  • @pointermove - Fired when pointer moves while over the object

Drag Events

  • @pointercancel - Fired when pointer interaction is cancelled

Event Objects

Event handlers receive a PointerEvent object with useful information:

<script setup lang="ts">
function onPointerMove(event) {
  console.log('Pointer position:', event.point) // 3D world position
  console.log('Screen coordinates:', event.xy) // 2D screen coordinates
  console.log('Object hit:', event.object) // The Three.js object that was hit
  console.log('Distance:', event.distance) // Distance from camera to hit point
  console.log('Face:', event.face) // The face that was intersected
  console.log('UV coordinates:', event.uv) // UV coordinates at hit point
}
</script>

<template>
  <TresMesh @pointermove="onPointerMove">
    <TresBoxGeometry />
    <TresMeshNormalMaterial />
  </TresMesh>
</template>

Pointer Missed Events

You can listen for events when the pointer misses all objects (clicks on empty space) by adding the @pointermissed event directly to the TresCanvas component:

<script setup lang="ts">
function onPointerMissed(event) {
  console.log('Clicked on empty space')
  // Useful for deselecting objects, closing menus, etc.
}
</script>

<template>
  <TresCanvas @pointermissed="onPointerMissed">
    <!-- Your 3D objects here -->
    <TresMesh>
      <TresBoxGeometry />
      <TresMeshNormalMaterial />
    </TresMesh>
  </TresCanvas>
</template>

Event Propagation

Events bubble up through the 3D object hierarchy. You can stop propagation using the standard event methods:

::examples-pointer-events-propagation ::

<script setup lang="ts">
function onChildClick(event) {
  event.stopPropagation() // Prevents parent from receiving the event
  console.log('Child clicked!')
}

function onParentClick() {
  console.log('Parent clicked!') // Won't fire if child stops propagation
}
</script>

<template>
  <TresGroup @click="onParentClick">
    <TresMesh @click="onChildClick">
      <TresBoxGeometry />
      <TresMeshNormalMaterial />
    </TresMesh>
  </TresGroup>
</template>

Performance Considerations

  • Events are automatically optimized using raycasting
  • Only objects with event listeners are tested for intersections
  • Use pointer-events: none in CSS to disable interaction on specific objects
  • Consider using object pooling for scenes with many interactive objects

TypeScript Support

TresJS provides full TypeScript support for pointer events:

import type { PointerEvent } from '@pmndrs/pointer-events'

function handlePointerEvent(event: PointerEvent<MouseEvent>) {
  // Full type safety for event properties
  console.log(event.point) // Vector3
  console.log(event.object) // Object3D
  console.log(event.xy) // [number, number]
}