Back to Gallery

Particle Morph Text

£5 Standard License Unlimited projects

A headline made of tens of thousands of GPU particles that dissolves in a gust and re-forms as the next word on click, while the cursor blows through the letters like wind. three.js, one shader, GSAP core.

advanced
6 more details
webgl-shaderparticle-systemmorphingtext-animationpointer-effectsclick-toggle

About This Effect

A WebGL headline built from forty thousand particles. Click, tap or press an arrow key and every particle leaves its letterform on a gust of curl noise, staggered outward from the point you clicked, and lands forming the next word. While they fly they grow, brighten and warm from the accent through white to amber, then cool as they settle; once settled the word keeps a faint ambient shimmer, never dead-still.

Read the full effect overview

The cursor is wind. Move it through the word and the particles under it are blown out of the letters in a streaked trail, tumbling in the wake, then drift back on a fixed half-life. Whip it and the whole word is blown sideways and re-forms. On touch a finger drags the same wind and a slow breeze keeps the word alive between touches. Left alone it cycles through its words every few seconds.

The words come from a plain list in your HTML, sampled into particle targets with the display font once it has loaded, and any item can point at an image silhouette instead. Without JavaScript, without WebGL or under reduced motion that same list is shown as a stacked display headline.

What's Included

10 items
  • Tens of thousands of particles in one draw call: a single THREE.Points with one ShaderMaterial, additively blended, at 40k on desktop and 12k on touch
  • A click kick: a ring of light and a shove leave the click point a beat ahead of the gust, on a GSAP expo.out ease
  • The morph is a gust, not a crossfade: a divergence-free curl-noise field carries neighbouring particles together as eddies, with each particle's timing staggered by its distance from the click point
  • Interruptible with no snap: a click mid-morph bakes every particle's current position into a float render target on the GPU and the next morph starts from exactly there
  • One activity value drives three channels together: point size, alpha and a cosine palette from the accent through white to a hot colour, both colours set from data attributes
  • The cursor is wind: the last twelve pointer samples each push with a Gaussian falloff and an age, so a stroke leaves a trail and a whip blows the whole word
  • Targets sampled from your own DOM: a list of words in the display font after document.fonts.load, or a transparent PNG silhouette per item via data-image
  • Click, tap, arrow keys and an idle auto-cycle that pauses after user input; fires a morphchange event for your own chrome
  • Frame-rate independent throughout: the wind decays on a fixed half-life and the morph is a GSAP tween, so 30, 60 and 120Hz look identical
  • Renders only while on screen, re-samples the words on resize, and disposes geometry, materials, render targets and the WebGL context itself on teardown

Perfect For

5 use cases
  • Agency and studio hero headlines that need one signature above-the-fold moment
  • Product launch pages cycling through three or four positioning words
  • Event and conference landing pages where the title is the whole first screen
  • Portfolio intros that morph between a name, a discipline and a location
  • Brand pages morphing a logotype silhouette into a word and back

How It Works

3 sections

Every particle carries two positions, where it started this morph and where it is going, plus a seed and a delay. The destination is a plain attribute the script writes from a sampled word: the word is drawn into a 2D canvas with the display font, its lit pixels indexed, and the particle positions picked from them. The start position lives in a float texture rather than an attribute. Before each morph the vertex shader is run once in a bake mode that writes every particle's current position to its own texel, so a morph started mid-flight continues from wherever the particles actually are, including their gust displacement, with no discontinuity.

The render loop runs on gsap.ticker, so GSAP is the clock and every tween on a uniform is current when the frame draws. GSAP tweens a single linear uProgress from 0 to 1 over 1.6 seconds. Each particle turns that into its own easeOutCubic inside a window offset by its delay, which is its normalised distance from the click point, so the gust spreads outward from the click. A click also sets a uKick uniform to 1 that GSAP eases back to 0 on expo.out; the shader reads it as a ring of light and a shove leaving the click point, so the ease shapes how fast the ring grows and how slowly it fades. A flight term that peaks mid-journey and is zero at both ends scales the curl-noise displacement, the point size and the palette position, which is what makes every in-flight channel settle to exactly nothing on arrival.

The wind is a uniform array of the last twelve pointer samples, each a position, a push vector from the pointer velocity and an age that halves every 0.35 seconds on the CPU. The vertex shader averages the pushes by Gaussian distance, applies them, and adds a second curl term scaled by the push so blown particles tumble rather than slide. The colour is a cosine palette whose constants are solved on init so it passes through the rest colour, white and the hot colour exactly.

Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates
£5

Premium Effect

Particle Morph Text

Purchase this effect to unlock the full source code and implementation.

£5 Standard License Unlimited projects
Browse Free Effects

Your Cart

Your cart is empty

Browse Effects