Prompt
Build a reusable link component with a letter-by-letter "roll" hover effect using GSAP.
Stack: Next.js (App Router), React, TypeScript and Tailwind CSS v4. Install gsap.
COMPONENT: RollLink({ href, className, children: string }) — a client component wrapping next/link.
MARKUP
- Put aria-label={children} on the link. Inside, an aria-hidden flex span.
- Split children into characters, turning spaces into non-breaking spaces. For each character:
- Outer span: relative, inline-block, overflow hidden, line-height 1.2.
- Inner span with data-char, display block, containing the character.
- A second copy of the character, absolutely positioned at top: 100%, left 0, directly underneath.
ANIMATION (onMouseEnter only)
- gsap.to(all [data-char] in this link, { yPercent: -100, duration: 0.22, ease: "power2.inOut", stagger: 0.015 }).
- Each letter slides up out of view while its twin slides into its place, left to right.
- onComplete: gsap.set(chars, { yPercent: 0 }) to reset instantly, which looks identical.
RULES
- Keep a "playing" ref. Ignore new mouseenter events while playing, and don't reverse on mouseleave, so the roll always finishes even if the pointer leaves early.
- No color, background or opacity change on hover — the motion is the only feedback.
- The link's own className controls layout, so it works for plain nav text and for centered pill buttons (e.g. flex, 40px tall, fully rounded, centered).More in Animations
Rounded Figma-style arrow plus a lagging ring of rotating text, blended with difference mode.
Custom Cursor with Text Ring
A glowing yellow band of light that sweeps left to right through the letters — not a static glow.
Shine Sweep Text
A rounded, inset section that grows to the screen edges (and upward) as you scroll, then eases back partway as it leaves.
Scroll-Grow Section
An endless, seamless row of tech pills that fades out at both edges — pure CSS, no JavaScript.
Tech Stack Marquee
A heart that pops, rings and bursts into tiny lime and purple dots and hearts when you favorite something.