UNPKG

@pmndrs/uikit

Version:

Build performant 3D user interfaces with Three.js and yoga.

60 lines (59 loc) 2.46 kB
import { Mesh, MeshBasicMaterial } from 'three'; import { createParentContextSignal, setupParentContextSignal, bindHandlers, Component } from './utils.js'; import { effect, signal, untracked } from '@preact/signals-core'; import { createCustomContainerState, setupCustomContainer } from '../components/index.js'; import { panelGeometry } from '../panel/index.js'; export class CustomContainer extends Component { styleSignal = signal(undefined); propertiesSignal; defaultPropertiesSignal; parentContextSignal = createParentContextSignal(); unsubscribe; material = new MeshBasicMaterial(); internals; constructor(properties, defaultProperties) { super(); //TODO make the container the mesh this.matrixAutoUpdate = false; setupParentContextSignal(this.parentContextSignal, this); this.propertiesSignal = signal(properties); this.defaultPropertiesSignal = signal(defaultProperties); const mesh = new Mesh(panelGeometry, this.material); super.add(mesh); this.unsubscribe = effect(() => { const parentContext = this.parentContextSignal.value?.value; if (parentContext == null) { return; } const abortController = new AbortController(); this.internals = createCustomContainerState(parentContext, this.styleSignal, this.propertiesSignal, this.defaultPropertiesSignal); setupCustomContainer(this.internals, parentContext, this.styleSignal, this.propertiesSignal, this, mesh, abortController.signal); //setup events bindHandlers(this.internals.handlers, this, abortController.signal); return () => { this.remove(mesh); abortController.abort(); }; }); } getComputedProperty(key) { return untracked(() => this.internals.mergedProperties?.value.read(key, undefined)); } getStyle() { return this.styleSignal.peek(); } setStyle(style, replace) { this.styleSignal.value = replace ? style : { ...this.styleSignal.value, ...style }; } setProperties(properties) { this.propertiesSignal.value = properties; } setDefaultProperties(properties) { this.defaultPropertiesSignal.value = properties; } destroy() { this.parent?.remove(this); this.unsubscribe(); this.material.dispose(); } }