@threlte/xr

<Hand>

<Hands /> instantiates XRHand inputs for devices that allow hand tracking.

<Hand left />
<Hand right />

It will by default load a hand model.

Default hand models are fetched from the immersive web group’s webxr input profile repo. If you are developing an offline app, you should download and provide any anticipated models.

<Hand> can accept a snippet to replace the default model.

<Hand left>
  <T.Mesh>
    <T.IcosahedronGeometry args={[0.2]} />
    <T.MeshStandardMaterial color="turquoise" />
  </T.Mesh>
</Hand>

A snippet, wrist, will place any children within the wrist space of the hand:

<Hand left>
  {#snippet wrist()}
    <T.Mesh>
      <T.IcosahedronGeometry args={[0.2]} />
      <T.MeshStandardMaterial color="hotpink" />
    </T.Mesh>
  {/snippet}
</Hand>

To trigger reactive changes based on whether hand input is or is not present, the useXR hook provides a currentWritable store:

const { isHandTracking } = useXR()

Hand tracking can serve as a powerful input device, as any joint position, and not just the wrist, can be read from in real time:

Component Signature

Events

name
payload
description

connected
XRHandEvent<'connected', null>
Fired when the hand connects.

disconnected
XRHandEvent<'connected', null>
Fired when the hand disconnects.

pinchstart
XRHandEvent<'pinchstart', THREE.XRHandSpace>
Fired when a pinch gesture begins.

pinchend
XRHandEvent<'pinchend', THREE.XRHandSpace>
Fired when a pinch gesture ends.