React Three Fiber interaction - pointer events, controls, gestures, selection...
Check installed Fiber, Drei, and input-library versions first. Examples target Fiber 9 / React 19. Choose camera movement, object movement, and UI input owners before connecting handlers.
Mount beneath Canvas. Keep accessible DOM controls outside Canvas for important actions; mesh pointer handlers alone do not provide keyboard access.
import { useState } from 'react'
import { OrbitControls } from '@react-three/drei'
export default function Example() {
const [selected, setSelected] = useState(false)
return (
<>
<mesh
name="selectable-box"
onClick={(event) => {
event.stopPropagation()
setSelected((value) => !value)
}}
>
<boxGeometry />
<meshStandardMaterial color={selected ? 'gold' : 'coral'} />
</mesh>
<OrbitControls makeDefault />
</>
)
}
event.object is the hit object; event.eventObject is the object owning the handler.stopPropagation() blocks delivery to farther hits as well as ancestors. It changes event delivery; it does not avoid raycasts already performed. Calling it can immediately trigger pointerout on previously hovered objects behind the hit.event.point is world space. Clone values you retain and convert into the parent's local space before assigning local transforms. A plane intersection or depth reference is needed to map a 2D drag into 3D.onPointerMissed for background deselection; distinguish clicks from drags using the event's movement information and the application's gesture policy.event.target.setPointerCapture(event.pointerId) and the matching release method; also handle cancellation/lost capture.state.events.update() to refresh hover results. Call it only when needed, not as a blanket extra raycast every frame.makeDefault exposes a controls instance to helpers that coordinate with it. TransformControls can suspend default controls while dragging; verify that custom controls are also disabled/restored correctly.client coordinates can introduce offsets.useFrame for movement; subscribe only for discrete events and clean up subscriptions.useScroll belongs below it. Its normalized offset/delta are not pixel distances.Test overlapping meshes, nested groups, background deselection, dragging outside the canvas, touch, cancellation, focus loss, and keyboard alternatives. Verify camera controls recover after dragging.