UNPKG

@threlte/extras

Version:

Utilities, abstractions and plugins for your Threlte apps

49 lines (48 loc) 1.85 kB
import { currentWritable, useDOM } from '@threlte/core'; import { getContext, setContext } from 'svelte'; import { Vector2, Raycaster } from 'three'; import { getDefaultComputeFunction } from './defaults'; 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], initialHits: [], hovered: new Map(), interactiveObjects: [], target, handlers: new WeakMap(), compute: options?.compute ?? getDefaultComputeFunction(target), filter: options?.filter, addInteractiveObject: (object, events) => { // check if the object is already in the list if (context.interactiveObjects.indexOf(object) > -1) { return; } context.handlers.set(object, events); context.interactiveObjects.push(object); }, removeInteractiveObject: (object) => { const index = context.interactiveObjects.indexOf(object); 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; };