asafefe.dev
Lab

Lab/23

Text Particles

The word is drawn offscreen in the site font and sampled on a grid. Each filled sample becomes a particle with a home, pushed by the cursor and pulled back by a spring.

  • Canvas
  • Typography
  • Interaction
Move through the letters

Installation

Add Text Particles to your project with the shadcn CLI. The files land in components/lab, ready to edit.

$ pnpm dlx shadcn@latest add @soultel/lab-text-particles

Or by URL: https://asafefe.dev/r/lab-text-particles.json

Brings along

  • utils
  • @soultel/lab-canvas

Usage

example.tsx12 lines
import { useState } from "react"
import { TextParticles } from "@/components/lab/text-particles"

export function Example() {
  const [word, setWord] = useState("Hello")
  return (
    <div>
      <TextParticles text={word} className="h-80" />
      <input value={word} onChange={(e) => setWord(e.target.value)} />
    </div>
  )
}

Props

PropTypeDefaultDescription
textstring"Hello"The word. Changing it morphs the particles.
fontstring"var(--font-sans)"Font family. Falls back to the canvas's own font.
fontWeightnumber650Weight used to rasterize the word.
gapnumber4Sampling step in px. Smaller is finer.
maxParticlesnumber4500Cap. The gap grows to stay under it.
radius / strengthnumber80, 1Cursor push radius in px, and its strength.
spring / frictionnumber0.05, 0.86Pull back home, and velocity kept per frame.
scatterOnClickbooleantrueClicking blows particles away from the click.
color / accentColorstring"var(--foreground)", "var(--primary)"Settled color, and the color for displaced particles.
refRef<TextParticlesHandle>-scatter() blows every particle outward.