Getting Started
Components
Search for a command to run...
import { Barlow_Condensed } from "next/font/google"
import { TextSkewReveal } from "@/registry/tween/text-skew-reveal"
const barlow = Barlow_Condensed({
subsets: ["latin"],
weight: ["900"],
style: ["normal"],
})
const sectionClass =
"@container/skew relative flex w-full items-center justify-center overflow-hidden px-6 text-center"
const sectionStyle = { height: "var(--preview-h, 100vh)" }
const headingClass =
"w-[min(90%,80ch)] uppercase font-black leading-[0.78] [letter-spacing:-0.02em] text-[clamp(2.25rem,9cqi,8.5rem)]"
export function TextSkewRevealDemo() {
return (
<div className={`${barlow.className} w-full`}>
<section
className={sectionClass}
style={{
...sectionStyle,
backgroundColor: "#23002b",
color: "#e894ff",
}}
>
<TextSkewReveal>
<h1 className={headingClass}>Type that arrives with a tilt</h1>
</TextSkewReveal>
</section>
<section
className={sectionClass}
style={{
...sectionStyle,
backgroundColor: "#002529",
color: "#94ffe4",
}}
>
<TextSkewReveal animateOnScroll>
<h1 className={headingClass}>
Each line skews into place as you scroll it into view
</h1>
</TextSkewReveal>
</section>
<section
className={sectionClass}
style={{
...sectionStyle,
backgroundColor: "#291900",
color: "#ffab46",
}}
>
<TextSkewReveal scrub>
<h1 className={headingClass}>Scrub it and you steer the skew</h1>
</TextSkewReveal>
</section>
</div>
)
}
import { TextSkewReveal } from "@/components/ui/text-skew-reveal"<TextSkewReveal>
<h1>Motion that reads itself in</h1>
</TextSkewReveal>
<TextSkewReveal animateOnScroll>
<h1>Replays each time it scrolls into view</h1>
</TextSkewReveal>
<TextSkewReveal scrub>
<h1>Scrubbed against scroll position</h1>
</TextSkewReveal>Each character starts offset by xFrom, skewed by skewX = skewFrom, and at opacity: 0, then tweens into place with a per-glyph stagger that resets at the start of every line. Use animateOnScroll to replay it on entry, or scrub to tie progress directly to scroll position.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Single text element to animate. The component clones it and attaches its ref. |
animateOnScroll | boolean | false | Replay the animation each time the element enters the viewport. |
scrub | boolean | false | Scrub the animation against scroll position between start and end. Mutually exclusive with animateOnScroll. |
delay | number | 0 | Delay (seconds) before the timeline starts. Ignored in scrub mode. |
stagger | number | 0.05 | Per-character delay (seconds), reset at the start of every line. |
duration | number | 0.65 | Per-character tween duration (seconds). |
ease | string | "power3.out" | Easing for the character tween. |
start | string | "top 100%" | ScrollTrigger start value (used in animateOnScroll and scrub). |
end | string | "top 45%" | ScrollTrigger end value (used in scrub). |
xFrom | number | 100 | Initial X offset (px) for each character. |
skewFrom | number | 20 | Initial skewX (deg) for each character. |
scroller | HTMLElement | string | null | — | Optional ScrollTrigger scroller; defaults to the ambient preview scroller. |
className | string | — | Merged onto the cloned child element. |