@dilukangelo/particlemorph
v0.2.0
Published
GPU particles that form text, logos, and images — assemble, scatter, flee the cursor. Zero deps, WebGL2.
Maintainers
Readme
particlemorph
|
|
|
|---|---|
Tens of thousands of GPU particles that assemble into words, logos, and images — scatter on command, flee the cursor, morph between targets. Zero dependencies, WebGL2, TypeScript, no three.js.
npm install @dilukangelo/particlemorphimport { createMorph, textTarget, imageTarget } from '@dilukangelo/particlemorph'
const morph = createMorph(canvas, {
count: 20000,
targets: [textTarget('HELLO'), imageTarget('/logo.png')],
color: '#8ecff5',
})
morph.morphTo(1) // reassemble into the logo — image targets carry their own colors
morph.scatter() // burst apartAPI
createMorph(canvas, {
count: 20000, // particle count (30k+ fine on integrated GPUs)
targets: [...], // textTarget(str, {font, weight, span}) | imageTarget(src, {span, colors})
color: '#8ecff5', // global tint (image targets override per-particle)
blend: 'additive', // glow on dark backgrounds; 'normal' for light pages
pointer: true, // cursor repulsion
})
morph.morphTo(indexOrTarget) // async — image URLs load on demand
morph.scatter(strength?) // burst + free-float until next morphTo
morph.setColor('#f0f')
morph.params.attraction = 20 // live-tunable: attraction, damping, drift, size,
// pointerStrength, pointerRadius, trails
morph.params.trails = 0.85 // motion streaks (0 = off)
morph.pause(); morph.resume(); morph.destroy()How it works: particle positions+velocities live in a ping-pong RGBA32F texture; one
fragment pass integrates spring-to-target + drift + cursor repulsion; the vertex shader
fetches its texel by gl_VertexID and draws round sprites. No attributes, no libraries.
Free behavior: DPR/resize handling, tab-visibility and off-viewport pause,
prefers-reduced-motion respected, SSR-safe imports, destroy() releases everything.
Framework adapters & CDN
import { MorphCanvas } from '@dilukangelo/particlemorph/react' // React
import { MorphCanvas } from '@dilukangelo/particlemorph/vue' // Vue 3 (:options + @ready)
import { morph } from '@dilukangelo/particlemorph/svelte' // Svelte: <canvas use:morph={{...}} /><script src="https://unpkg.com/@dilukangelo/particlemorph/dist/particlemorph.iife.js"></script>
<script> particlemorph.createMorph(canvas, { targets: [particlemorph.textTarget('HI')] }) </script>Resizes rebuild the current target automatically, so text stays undistorted.
Requires WebGL2 + EXT_color_buffer_float.
MIT · by Diluk Angelo · siblings: fluidkit, meshglow
