Events (v0.3.2)
You can easily handle mouse or touch events on your meshes.
TIP
To be able to handle events on ThreeJS objects, TroisJS uses raycasting.
Read more : https://threejs.org/docs/#api/en/core/Raycaster
Mesh Events
You can use the following props to handle events on a Mesh or InstancedMesh:
| Name | Description | Event type | Parameters |
|---|---|---|---|
onPointerEnter | When the pointer enters a mesh | pointerenter | { type, over: true, component, intersect } |
onPointerOver | When the pointer enters or leaves a mesh | pointerover | { type, over, component, intersect? } |
onPointerMove | When the pointer moves over a mesh | pointermove | { type, component, intersect } |
onPointerLeave | When the pointer leaves a mesh | pointerleave | { type, over: false, component } |
onClick | When the pointer clicks on a mesh | click | { type, component, intersect } |
Example :
<template>
<Renderer antialias resize="window">
<Camera :position="{ z: 10 }" />
<Scene>
<PointLight :position="{ y: 10, z: 10 }" />
<Box
@pointerEnter="onPointerEvent"
@pointerOver="onPointerOver"
@pointerMove="onPointerEvent"
@pointerLeave="onPointerEvent"
@click="onPointerEvent"
>
<LambertMaterial />
</Box>
</Scene>
</Renderer>
</template>
<script>
export default {
methods: {
onPointerEvent(event) {
console.log(event);
},
onPointerOver(event) {
event.component.mesh.material.color.set(event.over ? 0xff0000 : 0xffffff);
},
},
};
</script>
Raycaster Component
If you need to easily handle pointer events on all your scene's meshes, you can use Raycaster component :
<template>
<Renderer antialias resize="window">
<Camera :position="{ z: 10 }" />
<Raycaster
@pointerEnter="onPointerEvent"
@pointerOver="onPointerOver"
@pointerMove="onPointerEvent"
@pointerLeave="onPointerEvent"
@click="onPointerEvent"
/>
<Scene>
<PointLight :position="{ y: 10, z: 10 }" />
<Box v-for="i in 5" :position="{ x: -6 + i * 2 }">
<LambertMaterial />
</Box>
</Scene>
</Renderer>
</template>
<script>
export default {
methods: {
onPointerEvent(event) {
console.log(event);
},
onPointerOver(event) {
event.component.mesh.material.color.set(event.over ? 0xff0000 : 0xffffff);
},
},
};
</script>
intersectMode
By default, raycasting will be made on pointer move, but it can be useful to do the same on every frame.
If using mesh events, you should set pointer prop on Renderer :
<Renderer :pointer="{ intersectMode: 'frame' }">
...
</Renderer>
If using Raycaster component, you should set intersect-mode prop :
<Raycaster intersect-mode="frame" />
intersectRecursive
If present (=true), it also checks all descendants. Otherwise it only checks intersection with the object.
Default is false.
<Raycaster intersect-recursive />
Starting in v0.3.2 GLTF-models accept raycasting events as well. To make use of this you have to set intersectRecursive to true depending on your implementation:
Meshbased events (each mesh reports needs its own interaction events)
<Renderer :pointer="{ intersectRecursive: true }">
<Camera :position="{ z: 1 }" />
<Scene>
<GltfModel @click="onClick" src="..." />
</Scene>
</Renderer>
Raycasterbased implementation (one event fires no matter which object reports a collision)
<Renderer>
<Camera :position="{ z: 1 }" />
<Scene>
<Raycaster intersect-recursive @click="onClick" />
<GltfModel src="..." />
</Scene>
</Renderer>