@threlte/extras
Version:
Utilities, abstractions and plugins for your Threlte apps
49 lines (48 loc) • 1.85 kB
JavaScript
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;
};