Slide In Text
Animates text sliding in from the left with a fade when it enters the viewport.
Component
↓ scroll
Los Flamencos National Reserve
is a nature reserve located
in the commune of San Pedro de Atacama.
The reserve covers a total area
of 740 square kilometres.
"use client";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { useLayoutEffect, useRef } from "react";
import { cn } from "@/lib/utils";
interface SlideInTextProps {
children: React.ReactNode;
className?: string;
left?: string;
ease?: string;
scrub?: boolean | number;
start?: string;
end?: string;
}
export function SlideInText({
children,
className,
left = "-200px",
ease = "power3.out",
scrub = true,
start = "0px bottom",
end = "bottom+=400px bottom",
}: SlideInTextProps) {
const ref = useRef<HTMLParagraphElement>(null);
useLayoutEffect(() => {
gsap.registerPlugin(ScrollTrigger);
const ctx = gsap.context(() => {
gsap.from(ref.current, {
ease,
left,
opacity: 0,
scrollTrigger: {
end,
scrub,
start,
trigger: ref.current,
},
});
});
return () => ctx.revert();
}, [left, ease, scrub, start, end]);
return (
<p ref={ref} className={cn("relative", className)}>
{children}
</p>
);
}Installation
pnpm dlx shadcn@latest add "https://pulkitxm.com/components/slide-in-text.json"1. Install dependencies
pnpm add gsap2. Copy the component file
"use client";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { useLayoutEffect, useRef } from "react";
import { cn } from "@/lib/utils";
interface SlideInTextProps {
children: React.ReactNode;
className?: string;
left?: string;
ease?: string;
scrub?: boolean | number;
start?: string;
end?: string;
}
export function SlideInText({
children,
className,
left = "-200px",
ease = "power3.out",
scrub = true,
start = "0px bottom",
end = "bottom+=400px bottom",
}: SlideInTextProps) {
const ref = useRef<HTMLParagraphElement>(null);
useLayoutEffect(() => {
gsap.registerPlugin(ScrollTrigger);
const ctx = gsap.context(() => {
gsap.from(ref.current, {
ease,
left,
opacity: 0,
scrollTrigger: {
end,
scrub,
start,
trigger: ref.current,
},
});
});
return () => ctx.revert();
}, [left, ease, scrub, start, end]);
return (
<p ref={ref} className={cn("relative", className)}>
{children}
</p>
);
}3. Import and use
import { SlideInText } from "@/components/slide-in-text";
<SlideInText>Your text here</SlideInText>;Usage
Import the component
Add the SlideInText import to your file.
import { SlideInText } from "@/components/slide-in-text";Use with default props
Wrap your text in SlideInText for the default slide-in animation.
<SlideInText>Your text here</SlideInText>;Customize with props
Adjust left, scrub, start, and end to fine-tune the animation.
<SlideInText
left="-400px"
scrub={0.5}
start="top 80%"
end="bottom+=200px bottom"
>
Custom animated text
</SlideInText>;Guidelines
- Place SlideInText inside a scrollable container (e.g. your main content area or a div with overflow-y-auto).
- Use scrub: true for smooth scroll-linked animation, or a number (e.g. 0.5) for a slight delay.
- Adjust left to control how far the text slides in from (e.g. -200px, -400px).
- Customize start and end to change when the animation triggers relative to the viewport.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | Content to render inside the paragraph. |
| className | string | — | Additional CSS classes applied to the element. |
| left | string | "-200px" | CSS left offset to animate from. Passed directly to GSAP. |
| ease | string | "power3.out" | GSAP ease applied to the scrub. |
| scrub | boolean | number | true | ScrollTrigger scrub value. true = smooth, number = seconds to catch up. |
| start | string | "0px bottom" | ScrollTrigger start position. |
| end | string | "bottom+=400px bottom" | ScrollTrigger end position. |
Examples
Basic
Default usage with standard scroll range and ease.
↓ scroll
Los Flamencos National Reserve
is a nature reserve located
in the commune of San Pedro de Atacama.
The reserve covers a total area
of 740 square kilometres.
import { SlideInText } from "@/components/slide-in-text";
export function SlideInTextBasic() {
return (
<div className="space-y-8">
<SlideInText>First line of text</SlideInText>
</div>
);
}Custom offset
Slide further with a faster scrub for snappier animation.
↓ scroll
Los Flamencos National Reserve
is a nature reserve located
in the commune of San Pedro de Atacama.
The reserve covers a total area
of 740 square kilometres.
import { SlideInText } from "@/components/slide-in-text";
export function SlideInTextCustomOffset() {
return (
<SlideInText left="-400px" scrub={0.5}>
Second line
</SlideInText>
);
}Custom scroll range
Control when the animation starts and ends relative to viewport.
↓ scroll
Los Flamencos National Reserve
is a nature reserve located
in the commune of San Pedro de Atacama.
The reserve covers a total area
of 740 square kilometres.
import { SlideInText } from "@/components/slide-in-text";
export function SlideInTextCustomRange() {
return (
<SlideInText start="top 80%" end="bottom+=200px bottom">
Third line
</SlideInText>
);
}