UNPKG

@threlte/extras

Version:

Utilities, abstractions and plugins for your Threlte apps

58 lines (57 loc) 2.43 kB
import { currentWritable, useDOM } from '@threlte/core'; import { getContext, setContext } from 'svelte'; import { Raycaster, Vector2 } from 'three'; import { getDefaultComputeFunction } from './defaults.svelte.js'; const contextKey = Symbol('interactivity-context'); export const getInteractivityContext = () => { return getContext(contextKey); }; export const setInteractivityContext = (options) => { const target = currentWritable(options?.target ?? useDOM().dom); const context = { enabled: currentWritable(options?.enabled ?? true), pointer: currentWritable(new Vector2()), pointerOverTarget: currentWritable(false), lastEvent: undefined, raycaster: new Raycaster(), initialClick: [0, 0], initialClickTime: 0, initialHits: [], hovered: new Map(), interactiveObjects: [], target, handlers: new WeakMap(), compute: options?.compute ?? getDefaultComputeFunction(target), filter: options?.filter, clickDistanceThreshold: options?.clickDistanceThreshold ?? 8, clickTimeThreshold: options?.clickTimeThreshold ?? Number.POSITIVE_INFINITY, eventOptions: options?.eventOptions, addInteractiveObject: (object, events) => { // Always update handlers so re-registration picks up new callbacks, // even if the object is already in the list. context.handlers.set(object, events); if (context.interactiveObjects.indexOf(object) === -1) { context.interactiveObjects.push(object); } }, removeInteractiveObject: (object) => { const index = context.interactiveObjects.indexOf(object); // Guard against double-removal: indexOf returns -1 when the object // isn't in the list, and splice(-1, 1) would silently remove the // last element — corrupting an unrelated registration. if (index === -1) return; context.interactiveObjects.splice(index, 1); context.handlers.delete(object); } }; setContext(contextKey, context); return context; }; export const useInteractivity = () => { const context = getInteractivityContext(); if (!context) { throw new Error('No interactivity context found. Did you forget to implement interactivity()?'); } return context; };