Wawa Sensei logo

Events

Starter pack

Let's discover how to handle mouse, keyboard and touch events in React Three Fiber to make our 3D scene more interactive and immersive.

Mouse

Meshes have a few events that we can use to handle mouse events.

To detect when the mouse is over a mesh, we can use the onPointerEnter and onPointerLeave events.

Let's change the color of our sphere when the mouse is over it.

We start by creating a state to store if the mouse is over the sphere or not:

const [hovered, setHovered] = useState(false);

Then, we add the onPointerEnter and onPointerLeave events on the <mesh /> component:

<mesh
  {...props}
  onPointerEnter={() => setHovered(true)}
  onPointerLeave={() => setHovered(false)}
>
  {/* ... */}
</mesh>

Finally, we conditionally change the color of the material based on the hovered state value:

<meshStandardMaterial color={hovered ? "pink" : "white"} />

Change color on hover

Now, the sphere turns pink when the mouse is over it.

We can also detect when the mouse is clicked on a mesh using the onClick event.

We add a state to store if the sphere is selected or not:

const [selected, setSelected] = useState(false);

Then, we add the onClick event on the <mesh /> component:

<mesh
  {...props}
  onPointerEnter={() => setHovered(true)}
  onPointerLeave={() => setHovered(false)}
  onClick={() => setSelected(!selected)}
>
  {/* ... */}
</mesh>

We set the selected state to the opposite of its current value.

Finally, we conditionally change the color of the material based on the active state value:

let color = hovered ? "pink" : "white";
if (selected) {
  color = "hotpink";
}

return (
  <mesh
    {...props}
    onPointerEnter={() => setHovered(true)}
    onPointerLeave={() => setHovered(false)}
    onClick={() => setSelected(!selected)}
  >
    <sphereGeometry args={[0.5, 64, 64]} />
    <meshStandardMaterial color={color} />
  </mesh>
);

I decided to use a variable to store the color to make the code more readable than using two ternary operators.

Bubbling events

Let's add a big sphere behind our three spheres.

// ...

export const Experience = () => {
  return (
    <>
      <MoveableSphere scale={3} position-z={-10} />
      <MoveableSphere />
      <MoveableSphere position-x={-2} />
      <MoveableSphere position-x={2} />
      <ContactShadows
        rotation-x={Math.PI / 2}
        position={[0, -1.6, 0]}
        opacity={0.42}
      />

      <Environment preset="sunset" />
    </>
  );
};

If we hover the middle sphere, we can see that the big sphere is also affected by the onPointerEnter and onPointerLeave events. It's because those events are bubbling.

The casted ray used by React Three Fiber to detect the mouse events goes through the middle sphere and then through the big sphere.

bubbleEvent

To prevent the event from bubbling, we can use the stopPropagation on the event.

End of lesson preview

To get access to the entire lesson, you need to purchase the course.