blaze-motion
← All components

Mask Text Reveal

Text

Masked text reveal — words rise out from behind a clip mask, token by token.

Installation

One command drops the source into your repo — editable, with the provider and motion pulled in automatically.

npx shadcn add https://motion.asmitsah.dev/r/mask-text-reveal.json

Usage

By word (default)

Wrap your own element — its tag + className win. Each word sits in its own overflow-hidden mask and rises y: 110% → 0, no opacity fade.

import { MaskTextReveal } from "@/components/motion/mask-text-reveal";

<MaskTextReveal>
  <h2 className="text-2xl font-semibold">Words rise from behind the mask.</h2>
</MaskTextReveal>

By line

Pass \n-separated text — each line clips and rises inside its own mask, staggered at feel.lineStagger.

<MaskTextReveal by="line">
  <p>{`Clipped per line, not per word.
No fade — a crisp, editorial rise.`}</p>
</MaskTextReveal>

With delay

Offset a strapline behind a heading so the two reveals read as a sequence.

<MaskTextReveal>
  <h1>Leads first.</h1>
</MaskTextReveal>
<MaskTextReveal delay={0.15}>
  <p className="text-muted-foreground">Follows, a beat later.</p>
</MaskTextReveal>

Trigger on mount

Play immediately instead of waiting for scroll — for above-the-fold hero text.

<MaskTextReveal trigger="mount">
  <h1>Above the fold, plays right away.</h1>
</MaskTextReveal>

Props

PropTypeDefaultDescription
childrenReactElementA single host element (h1–h6/p/span/div) wrapping plain-string text. Its tag, className + style are reused and it carries the aria-label. Required.
by"word" | "line""word"Split unit: "word" splits on whitespace; "line" splits on \n.
trigger"inView" | "mount""inView"Animate on scroll-into-view (once) or immediately on mount.
delaynumber0Seconds before the first token starts staggering in.