lume
Version:
61 lines (48 loc) • 1.61 kB
text/typescript
import {untrack, onCleanup} from 'solid-js'
import {MeshBehavior, type MeshComponentType} from './MeshBehavior.js'
import type {Material} from 'three/src/materials/Material.js'
import type {BufferGeometry} from 'three/src/core/BufferGeometry.js'
/**
* @class GeometryOrMaterialBehavior
* Abstract base class for Geometry and Material behaviors, not intended for direct use.
*
* Subclasses should implement:
* _createComponent() - return a BufferGeometry or Material instance.
*
* @extends MeshBehavior
*/
export abstract class GeometryOrMaterialBehavior extends MeshBehavior {
abstract type: MeshComponentType
override connectedCallback() {
super.connectedCallback()
this.createEffect(() => this.resetMeshComponent())
}
resetMeshComponent(): void {
this.#setMeshComponent()
this.element.needsUpdate()
onCleanup(this.#disposeMeshComponent)
}
override _createComponent(): BufferGeometry | Material {
throw new Error('`_createComponent()` is not implemented by subclass.')
}
// records the initial size of the geometry, so that we have a
// reference for how much scale to apply when accepting new sizes from
// the user.
// TODO
// #initialSize: null,
#disposeMeshComponent = () => {
// TODO handle material arrays
this.meshComponent?.dispose()
this.meshComponent = null
}
#setMeshComponent() {
const newComponent = this._createComponent()
// untrack in case we make .three reactive later
untrack(() => {
// @ts-expect-error FIXME
this.element.three[this.type] = newComponent
})
// @ts-expect-error
this.meshComponent = newComponent
}
}