REFERENCE
- Gallery page: https://magpui.com/en/i/character-by-character-text-animations-274738
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/character-by-character-text-animations-274738/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/character-by-character-text-animations-274738/clip.mp4
- Original post: https://x.com/codrops/status/2117557620747690372 by @codrops
Before building, download the first frame and look at it. If ffmpeg is available, download the clip and extract frames (ffmpeg -i clip.mp4 -vf fps=2 frame-%02d.png), then study the motion frame by frame. Match what you see; the text below describes it, the frames are the truth.
BUILD: A single dark scrolling page that is a showcase of character-by-character text animations. Each full-height section has a small numbered label with the variation name and a Replay link, a short five-line story paragraph, and one big uppercase headline. When a section scrolls into view its text plays an animation that borrows a metaphor from a real interface: a cursor that scrambles glyphs ahead of it, a proofreader rubbing out and rewriting letters, a telegram printing character by character, T9 predictive typing, autocomplete ghost text, multiple cursors typing at once, find-all highlights, a speed reader flashing one word at a time, a voice note waveform turning into letters, a photocopy smear, and a few WebGL ones (caustic light, a glowing filament, a magnifier loupe). It should feel quiet, precise and typographic, with a single hot accent color.
DESIGN SYSTEM: Background #0b0b0b with a soft radial light at the top center (rgba(200,204,212,0.17) fading out by 60%) and a tiled film grain at 30% opacity. Body text in a clean humanist sans at 13-15px, color rgba(255,255,255,0.5); strong text rgba(255,255,255,0.88); guessed or ghost text rgba(255,255,255,0.4); hairlines rgba(255,255,255,0.12). Headlines in a wide grotesk, uppercase, weight 300-400, around clamp(48px, 7vw, 110px), tight letter-spacing, left aligned on a 15px margin grid. Single accent #e23e1d (red orange) for cursors, highlight boxes, ink blots, waveform bars and outlined frames. Inverted highlight: white #f2f2f2 block behind black letters. No radii except the outlined capsule frame (about 6px radius, 1.5px accent stroke).
MOTION: Split every paragraph and headline into characters (and words where needed). Each variation runs once on enter (ScrollTrigger start 'top 70%') and again on Replay or click. Examples: (1) Cursor scramble: a 2px accent caret moves left to right at about 25ms per character; 3-5 characters ahead of it show random glyphs that resolve into the real letter as the caret passes. (2) Proofread: a word fades to 30%, a small accent blot scales from 0 to 1 over it (300ms, cubic-bezier(0.34,1.56,0.64,1)), then the correct letters type in. (3) Telegram: characters appear one by one with a 40ms stagger and a monospace tick, no easing. (4) Find all: matching words get the inverted white highlight, each box scaling in from scaleX 0 with transform-origin left, 250ms, stagger 80ms. (5) Voice note: 5-12 thin accent bars bounce in height (random 8-40px, 120ms steps) then collapse into the headline letters. (6) Scatter: letters break into small accent rectangles that drift, then snap back with Flip, 700ms cubic-bezier(0.22,1,0.36,1). (7) Outline: an accent capsule frame draws around the active line while text inside types. WebGL variants render the headline into a texture and apply caustic light, a glowing filament or a loupe magnification following the pointer. Smooth scroll on the whole page.
SECTIONS: Header with title, all-demos and source links, a numbered index 01-19 linking to each variation, and a hint line. Hero with one huge word in the accent color. Then one section per variation: label row (number, name, Replay), story paragraph, big headline. Footer with credits.
IMPLEMENTATION: GSAP with SplitText (chars, words, lines with masks), ScrollTrigger to play each variation on enter, Flip for letters that move between layouts, ScrollSmoother or Lenis for smooth scroll. Keep every variation in its own module exporting play() and reset(). WebGL ones with a small OGL or three.js plane that samples a canvas texture of the text; keep the real DOM text underneath for accessibility. Use aria-label on split elements with the full sentence so screen readers read words, not letters. prefers-reduced-motion: show final text immediately, no scramble. Replay buttons are real buttons with visible focus rings. Revert splits on resize and only animate sections near the viewport.
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, components and fonts; map colors to the closest existing tokens; never copy logos, brand names, photos or illustrations from the original; use placeholder copy.
SUCCESS CHECK:
- At least eight clearly different per-character variations play on scroll and replay on click without layout shift.
- Screen readers announce whole sentences and reduced motion shows final text instantly.
- Scrolling and animations stay at 60fps on a mid-range laptop.