Skip to content

Events

Video Lecture

Section Video Links
Events Events Events

Description

Our 3D objects can respond to pointer events and if anytime their props or state was changed.

In this example we can see that our boxes respond to events indicating when your pointer is down, up, over and out. The information is logged to the console.

There are many events that you add to your Threejs objects, See the list on the official documentation.

Note that when we capture an event, a lot of information about the event is passed into the callback. Example, if an object was clicked, then we can get information about that object, the 3D vector where the click occurred, the distance from the camera of the click, which face of the object was clicked, the UV coordinate of the click, and many things.

The pointer events rely on a raycaster that is automatically created when the React Three Fiber Canvas is instantiated.

Since the information about the event is passed into the callback, we don't need to create any dedicated useRef hook for our object to read that data. All the required information referencing our object is present in case we want to use that data or inspect it further in the console.

./src/Box.jsx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'

export default function Box(props) {
  const ref = useRef()

  useFrame((_, delta) => {
    ref.current.rotation.x += 1 * delta
    ref.current.rotation.y += 0.5 * delta
  })

  return (
    <mesh
      {...props}
      ref={ref}
      onPointerDown={(e) => console.log('pointer down ' + e.object.name)}
      onPointerUp={(e) => console.log('pointer up ' + e.object.name)}
      onPointerOver={(e) => console.log('pointer over ' + e.object.name)}
      onPointerOut={(e) => console.log('pointer out ' + e.object.name)}
      onUpdate={(self) => console.log(self)}
    >
      <boxGeometry />
      <meshBasicMaterial color={0x00ff00} wireframe />
    </mesh>
  )
}

Note that If two meshes are overlapping each other, then the mouse event will also be captured by the object behind. You can prevent this behavior by using the stopPropagation() method in your event handler.

E.g.,

  onPointerDown={e => {
    e.stopPropagation()
    // ...
  }}

Working Example

<>
Events sbedit.net
Events docs.pmnd.rs
Pointer Events docs.pmnd.rs
THREE.Raycaster threejs.org

GitHub Branch

git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout events
npm install
npm start

Comments