scroll·free
Parallax
Scrub-linked vertical parallax for images and blocks.
speed 0.15
speed 0.4
speed 0.7
Installation
terminal
pnpm add gsap @gsap/reactThen copy the component below into src/components/motion/parallax.tsx. It expects @/lib/gsap (plugin registration) and @/lib/utils (cn).
Source
src/components/motion/parallax.tsx
"use client";
import { useRef, type ReactNode } from "react";
import { gsap, useGSAP } from "@/lib/gsap";
import { cn } from "@/lib/utils";
export interface ParallaxProps {
children: ReactNode;
className?: string;
/** Positive moves slower than scroll (background feel); negative moves faster. Range -1..1. */
speed?: number;
}
export function Parallax({ children, className, speed = 0.3 }: ParallaxProps) {
const ref = useRef<HTMLDivElement>(null);
useGSAP(
() => {
const el = ref.current;
if (!el) return;
const travel = window.innerHeight * speed;
gsap.fromTo(
el,
{ y: -travel / 2 },
{
y: travel / 2,
ease: "none",
scrollTrigger: { trigger: el, start: "top bottom", end: "bottom top", scrub: true },
}
);
},
{ scope: ref, dependencies: [speed] }
);
return (
<div ref={ref} className={cn("will-change-transform", className)}>
{children}
</div>
);
}