webdevpuneet.com

Text Particles HTML CSS JS — Canvas Particle Text

Text Particles · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

<div class="app">
  <canvas id="canvas"></canvas>
  <div class="controls">
    <input type="text" id="textInput" value="HELLO" maxlength="10" placeholder="Enter text..." spellcheck="false">
    <button id="applyBtn">Apply</button>
    <button id="toggleBtn">Explode</button>
    <span class="hint">Click canvas to toggle</span>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Offscreen text sampling: fillText plus getImageData reads glyph pixels into target points
Alpha thresholding: pixels with alpha over 128 on a stride become particles
Spring physics: velocity accelerates toward the target in proportion to distance
Damping: a sub-1 factor bleeds velocity so particles settle without endless oscillation
FORM and EXPLODE state machine: click scatters particles, then they reform
Explosion with gravity: random outward velocity plus per-frame gravity for a burst
fillRect rendering: cheap 2px squares keep thousands of particles at 60fps
Hue-by-position color: x position maps to an HSL hue for a rainbow gradient
Smooth word morphing: particles keep positions and receive new targets on text change
requestAnimationFrame loop: refresh-synced animation with no libraries

About this UI Snippet

How to Build a Canvas Particle Text Effect with Spring Physics

Screenshot of the Text Particles snippet rendered live

A particle text effect renders a word as thousands of tiny dots that fly in, assemble into the letters, hold the shape, and can scatter apart on click before reforming. It is one of the most eye-catching canvas effects and, despite looking complex, comes down to two ideas: sampling glyph pixels from an offscreen canvas to find target positions, and spring physics to move particles toward those targets. This walkthrough explains the whole pipeline, built with the HTML5 Canvas 2D API and requestAnimationFrame, no libraries.

Sampling text into target points

The particles need to know where the letters are. To find out, the code draws the word onto a hidden offscreen canvas with a large bold font using fillText, then calls getImageData to read back the entire pixel buffer. The returned Uint8ClampedArray holds four bytes per pixel (R, G, B, A). The code scans this buffer on a stride — stepping several pixels at a time in both x and y rather than every pixel — and for each sampled location checks the alpha byte: if data[index + 3] > 128, that pixel is part of a letter and becomes a particle target. The stride controls density: a smaller stride yields more particles and crisper text at higher cost, a larger stride is sparser and faster. Roughly three thousand particles at a stride of a few pixels gives a clean word while staying smooth.

Each detected text pixel produces a target position (tx, ty). Existing particles are reused and assigned new targets when the word changes, and extra particles are spawned or trimmed so the count matches the new glyph's pixel count.

The particle and spring physics

Every particle stores a current position (x, y), a velocity (vx, vy) and its target (tx, ty). The motion toward the target is a damped spring, the classic ease-with-overshoot integrator:

vx += (tx - x) * SPRING vy += (ty - y) * SPRING vx *= DAMPING vy *= DAMPING x += vx y += vy

The spring term accelerates the particle in proportion to how far it is from its target, like a rubber band — far particles rush in fast, close particles slow down. The damping factor (slightly less than 1) bleeds off velocity each frame so particles settle instead of oscillating forever. Tuning SPRING and DAMPING changes the feel from snappy to floaty. Because every particle runs this independently, the cloud organically converges into readable text.

The state machine: FORM and EXPLODE

The effect is driven by a small state machine. In the FORM state, particles spring toward their text targets and the word assembles. On click (or a timed trigger), it switches to EXPLODE: each particle is given a random outward velocity — a random angle and speed pushing it away from its position — and gravity is added each frame (vy += GRAVITY) so the particles burst and arc downward like fireworks. After a short interval the state flips back to FORM, the spring physics re-engages, and the particles fly home to rebuild the word. This explode-and-reform loop is what makes the effect feel alive.

Rendering efficiently

In the animation loop, the canvas is cleared (or faded for a trail), then every particle is drawn. For performance with thousands of particles, each is rendered as a tiny filled square via fillRect(x, y, 2, 2) rather than arc, because rectangles skip the path and circle math that would dominate the frame budget. Color is assigned per particle from its horizontal position — mapping x across the canvas width to a hue in HSL — so the assembled word shows a smooth left-to-right rainbow gradient that follows the particles even as they move. Drawing flat 2px squares keeps roughly three thousand particles comfortably at 60fps.

Changing the word

A text input lets users type a new word. On apply, the offscreen canvas is recleared, the new text is drawn and re-sampled into a fresh set of targets, and the particle array is reconciled to the new target count. Because particles keep their current positions and simply receive new targets, the transition from one word to the next is itself a smooth animated morph rather than a hard cut.

Why this approach scales

The key insight is decoupling the *what* from the *how*: the offscreen canvas and getImageData answer where the text is, producing a list of target points, while the spring-and-damping integrator answers how particles get there. Neither part needs to know about the other. That separation, plus drawing cheap squares and using requestAnimationFrame, lets a few lines of math animate thousands of particles into any text you type, all on the client with no dependencies.

Step by step

How to Use

  1. 1
    Watch it formOn load, scattered particles spring inward and assemble into the word.
  2. 2
    Click to explodeClick the canvas to scatter the particles outward with gravity before they reform.
  3. 3
    Type new textEnter a different word in the input field, up to the character limit.
  4. 4
    Apply the wordPress apply or Enter to re-sample the new glyphs and morph the particles into them.
  5. 5
    Observe the gradientNotice the left-to-right hue gradient that colors particles by their x position.
  6. 6
    Tune the feelAdjust SPRING, DAMPING and the sampling stride in the JS to change density and motion.

Real-world uses

Common Use Cases

✨
Animated hero titles
Assemble a brand name from thousands of dots that fly in, hold the shape and scatter on click before reforming.
🌠
Landing page intros
Open a site with text that forms, holds and dissolves, using spring physics with damping so particles settle without endless oscillation.
🎆
Event countdowns and reveals
Explode and reform a date or tagline, then compare with a mechanical take in the split flap display.
🎮
Game title screens
Give game titles and victory text a physical, playful entrance, sampling glyph pixels offscreen with getImageData.
⌨️
Interactive word demos
Let visitors type their own word and watch it form, with a hue shift recolouring particles and physics balls offering a complementary toy.

Got questions?

Frequently Asked Questions

The word is drawn to a hidden canvas and read back with getImageData. The code scans the pixel buffer on a stride and any pixel whose alpha exceeds a threshold becomes a target position for a particle.

Each particle uses a damped spring: its velocity gains a push toward the target proportional to the remaining distance, then is multiplied by a damping factor under 1 so it eases in and settles instead of overshooting forever.

fillRect is much cheaper than building an arc path per particle. With thousands of particles, skipping the circle math is what keeps the animation at a smooth frame rate.

On click the state switches to EXPLODE and each particle gets a random outward velocity plus gravity added every frame, so they burst and arc down. After a brief delay the state returns to FORM and the spring physics pulls them back into the word.

Yes. Lower the sampling stride to test more pixels, producing more particles and crisper letters at a higher CPU cost, or raise it for a sparser, faster effect. The particle count automatically follows the number of sampled pixels.

Yes. The JSX, Vue, Angular, and Tailwind exports convert the snippet automatically. In React, run the canvas particle loop in useEffect with cancelAnimationFrame cleanup, store the particle array in a ref, and re-sample the text pixels whenever the displayed word prop changes.