I am using Drei’s Html component to create some objects in my scene, such as the following code snippet. However none of the mouse events work. Is there sometihng I am missing? Is it possible to have mouse events on a Html component and, if not, is there a workaround ?
<Html
onClick={(a) => console.log('click')} //these dont work
onPointerDown={(a) => console.log('mouse down') // these dont work
center
>
<span style={{
backgroundColor: 'red',
display: 'inline-block',
width: '100px',
height: '100px',
borderRadius: '50%'
}}></span>
</Html>
Yes - the way you’re doing it is correct. Is there something else that’s affecting user input, besides this component? OrbitControls? CSS styling of pointer events? Some transparent fullscreen overlay that may be covering the html element?
I do use OrbitControls, but not the others you mentioned, no overlays nor CSS styling. I don’t know if this is useful or not, but if I replace the with something like or then the mouse events work fine.
you are still in the threejs reconciler with the drei <Html>
components, so all events go against geometry. <Html>
is a portal into react-dom, it has no threejs geometry, events on it will do nothing. instead put them on the span, the actual html, and you’ll have regular react-dom events since everything inside <Html>
is being rendered by react-dom.
<Html center>
<span
onClick={(a) => console.log('click')}
onPointerDown={(a) => console.log('mouse down')
style={{ ...
btw, in order for both html and canvas to receive events according to the dom api both the canvas and the html elements must share the same parent. otherwise either the canvas will take events away from the html, or html from the canvas. fiber makes this easy:
example using drei/html https://codesandbox.io/p/sandbox/the-three-graces-0n9it
example using canvas + regular html https://codesandbox.io/p/sandbox/canvas-text-p9umgf
<Canvas eventSource={document.getElementById('root')} eventPrefix="client">
the prefix tells it which events to use. offsetX/Y or clientX/Y, screen etc. each even type works differently but that’s all just the dom api.
2 Likes
ps, there’s a library on pmndrs now that can render html/css/tailwind into threejs, as instanced meshes and glyphs, so you don’t have to use clunky html on top of the canvas no more. the ui is an actual part of the scene with this: GitHub - pmndrs/uikit: 🎨 user interfaces for react-three-fiber
even a html → uikit converter https://html23.com/
and one for figma → uikit for good measure https://www.f2r3.com/
1 Like
Thank you so much for the help and thorough explanation! That fixed the problem!