Adding a particle layer
A particle-geometry component creates a layer, writes positions into it, and disposes it on unmount. It renders nothing itself.
See Particles for the layer API.
The shape of one
Section titled “The shape of one”export function Star({ points }: StarProps) { const ctx = useFabric() effect(() => { const g = ctx.gpu(); if (!g) return const style = untrack(() => ({ /* one-time reads */ })) const layer = createParticleLayer(g, capacity, style) cleanup(() => disposeParticleLayer(g, layer)) }) return null}The untrack is required. The create effect reads style props once to
build the layer. If those props are reactive — flux accessors are — reading
them inside the effect tracks them, and moving a style slider re-runs the
effect, which disposes the layer and re-creates it empty. Nothing pushes the
geometry again, so the points disappear. untrack makes the effect depend on
ctx.gpu() only; the layer’s own wire() handles later style changes.
The data signal is the exception. samples is the redraw trigger and is
meant to be tracked. Only one-time setup reads go inside untrack.
The constraints
Section titled “The constraints”- Keep it small. Layer components are statically imported, so they land in the eager chunk rather than a lazy one.
- Add no WGSL. Reuse the shared particle pipeline. A new shader would make the component a build-tooling concern.
- Never add a
type:field. The build scans for it to decide which SDF primitives survive, and yours would pin one nothing uses. - Do not add region markers unless you mean them.
- Do not call
initParticles. Boot already created the primary buffers, and a second caller destroying them conflicts with the first.
Data comes in as a prop
Section titled “Data comes in as a prop”Take geometry data as a prop and let the layout file own the subscription. A component that imports the transport layer couples the library to it and blocks extraction.