gsap-animations-lionel
v0.1.0
Published
Reusable GSAP-powered animation primitives for React: scroll parallax, scroll-reveal, custom particle cursor, and Lenis smooth scroll.
Maintainers
Readme
gsap-animations
Reusable GSAP-powered animation primitives for React, extracted from a production portfolio site: scroll parallax, scroll-reveal, a custom particle cursor, and Lenis-driven smooth scroll.
Install
npm install gsap-animations gsap @gsap/react lenis react react-domgsap, @gsap/react, lenis, react, and react-dom are peer
dependencies — install the versions your app already uses.
ParallaxSection
Two-layer scroll parallax: a background layer moves faster than the content
layer, creating depth. Speed auto-reduces on mobile and is skipped for
prefers-reduced-motion.
import { ParallaxSection } from "gsap-animations";
<ParallaxSection bgImage="/hero.jpg" bgSpeed={0.4} contentSpeed={0.15}>
<h1>Hello</h1>
</ParallaxSection>useScrollReveal
Reveals every element matching a selector as it scrolls into view, tied to
scroll position (not a one-shot replay). Pass a deps array to safely
rebind when the underlying list changes (e.g. a filtered grid) — it tears
down old triggers and refreshes the rest of the page's trigger positions.
import { useScrollReveal } from "gsap-animations";
function Cards({ items }: { items: Item[] }) {
useScrollReveal(
"[data-animate='card']",
{ from: { opacity: 0, y: 30 }, to: { opacity: 1, y: 0 }, staggerDelay: 0.05 },
[items]
);
return (
<div>
{items.map((item) => (
<div key={item.id} data-animate="card">{item.title}</div>
))}
</div>
);
}useTimelineReveal
A one-shot cascading entrance timeline (e.g. a hero section), with overlapping offsets via GSAP's timeline position parameter.
import { useTimelineReveal } from "gsap-animations";
useTimelineReveal([
{ selector: "[data-animate='title']", from: { opacity: 0, y: 40 }, to: { opacity: 1, y: 0 } },
{ selector: "[data-animate='text']", from: { opacity: 0, y: 30 }, to: { opacity: 1, y: 0 }, position: "-=0.6" },
]);CustomCursor
A glowing dot + trailing ring that replaces the native cursor, with a
sparkle particle trail on move/scroll. Disabled on touch devices and for
prefers-reduced-motion. Mount once near the root of your app.
import { CustomCursor } from "gsap-animations";
<CustomCursor />To hide the native OS cursor while it's active, add to your global CSS:
html.custom-cursor-active,
html.custom-cursor-active * {
cursor: none !important;
}SmoothScrollProvider + useLenis
Wraps Lenis smooth scroll, synced to GSAP's ticker so ScrollTrigger-based animations stay in lockstep. Mount once near the root.
import { SmoothScrollProvider, useLenis } from "gsap-animations";
<SmoothScrollProvider>
<App />
</SmoothScrollProvider>;
// anywhere inside, in an event handler:
function Nav() {
const lenisRef = useLenis();
return (
<a onClick={(e) => { e.preventDefault(); lenisRef?.current?.scrollTo("#section"); }}>
Jump
</a>
);
}Notes
- Components assume Tailwind CSS utility classes are available in the consuming app (used for layout/positioning, not a hard dependency to import).
- All scroll-driven effects respect
prefers-reduced-motion. ParallaxSectionandCustomCursorare framework-agnostic (no Next.js dependency) — they render a plain<img>and DOM nodes respectively.
Build
npm install
npm run build # emits dist/ (ESM + CJS + .d.ts) via tsup