useCursor
A hook that sets the css cursor property according to the hover state of a mesh, so that you can give the user visual feedback.
If a context is present, the cursor property will be set on the DOM element of the renderer, otherwise it will be set on the body element.
<script lang="ts"> import { Canvas } from '@threlte/core' import Scene from './Scene.svelte'</script>
<div> <Canvas> <Scene /> </Canvas></div>
<style> div { height: 100%; }</style><script lang="ts"> import { T, useThrelte } from '@threlte/core' import { interactivity, Text, useCursor } from '@threlte/extras' import { DEG2RAD } from 'three/src/math/MathUtils.js'
const { hovering, onPointerEnter, onPointerLeave } = useCursor()
interactivity()
const { size } = useThrelte()
const color = $derived($hovering ? '#dddddd' : '#FE3D00') const zoom = $derived($size.width / 7)</script>
<T.OrthographicCamera {zoom} position={[5, 5, 5]} oncreate={(ref) => { ref.lookAt(0, 0, 0) }} makeDefault/>
<T.DirectionalLight position.y={10} position.x={5}/><T.AmbientLight intensity={0.2} />
<Text text="HOVER" interactive onpointerenter={onPointerEnter} onpointerleave={onPointerLeave} fontSize={0.5} anchorY="100%" anchorX="50%" rotation.y={90 * DEG2RAD} position.y={1} position.x={-1} {color}/>
<T.Mesh onpointerenter={onPointerEnter} onpointerleave={onPointerLeave}> <T.MeshStandardMaterial {color} /> <T.BoxGeometry args={[2, 2, 2]} /></T.Mesh>Examples
Section titled “Examples”Simple Usage
Section titled “Simple Usage”Provide arguments to determine the cursor style. The defaults are'pointer' for onPointerOver and 'auto' for onPointerOut. useCursor returns event handlers that you can use to set the hovering state:
<script lang="ts"> import { T } from '@threlte/core' import { useCursor } from '@threlte/extras' import { BoxGeometry, MeshBasicMaterial } from 'three'
// Set the cursor to 'grab' if the pointer is // hovering over the mesh and to 'crosshair' // if the pointer is outside the mesh const { onPointerEnter, onPointerLeave } = useCursor('grab', 'crosshair')</script>
<T.Mesh onpointerenter={onPointerEnter} geometry={new BoxGeometry()} material={new MeshBasicMaterial()}/>Renaming Event Handlers
Section titled “Renaming Event Handlers”You can rename the event handlers to resolve naming conflicts. Additionally Svelte allows binding multiple event handlers to the same event:
<script lang="ts"> import { T } from '@threlte/core' import { useCursor } from '@threlte/extras' import { BoxGeometry, MeshBasicMaterial } from 'three'
const { onPointerEnter: cursorEnter, onPointerLeave: cursorLeave } = useCursor()
const onPointerEnter = () => { console.log('Pointer entered!') } const onPointerLeave = () => { console.log('Pointer left!') }</script>
<T.Mesh onpointerenter={cursorEnter} onpointerenter={onPointerEnter} geometry={new BoxGeometry()} material={new MeshBasicMaterial()}/>Store Usage
Section titled “Store Usage”If you want to implement custom logic, you can use the returned svelte store to set the hovering state:
<script lang="ts"> import { T } from '@threlte/core' import { useCursor } from '@threlte/extras' import { BoxGeometry, MeshBasicMaterial } from 'three'
const { hovering } = useCursor()</script>
<T.Mesh onpointerenter={() => ($hovering = true)} onpointerleave={() => ($hovering = false)} geometry={new BoxGeometry()} material={new MeshBasicMaterial()}/>Change the Cursor Style
Section titled “Change the Cursor Style”Provide svelte stores to change the cursor style also while hovering:
<script lang="ts"> import { T } from '@threlte/core' import { useCursor } from '@threlte/extras' import { BoxGeometry, MeshBasicMaterial } from 'three' import { writable } from 'svelte/store'
const onPointerOverCursor = writable('grab')
const { onPointerEnter, onPointerLeave } = useCursor(onPointerOverCursor)
// somewhere in your application … onPointerOverCursor.set('grabbing')</script>
<T.Mesh onpointerenter={onPointerEnter} geometry={new BoxGeometry()} material={new MeshBasicMaterial()}/>