GSAP Pinned Statement Hero with Expanding Photo
Overview
A poster-style hero: a giant serif statement over a hand of service cards. It pins as you scroll; the lines slide apart trailing motion blur, the cards fan wider and the photo at the centre opens up to fill the screen, coming into colour as the type turns light.
The opening section of a page. On load the statement's lines slide up out of their masks, the photo settles into its frame, the service cards deal out behind it like a hand and the small print fades in. Then the hero pins for two and a half screens of scroll before letting the page carry on.
Details
- Category
- Scroll
- Interaction
- On Load + On Scroll
- Trigger
- On Load
- Languages
- React, TypeScript, Tailwind
(01)Keep exploring
All 21 componentsBuilt with the same techniques
No. 019 / Scroll
GSAP Pinned Service Cards with Animated Reveals
On Scroll · On Hover · Mouse Move · On Click
No. 018 / Scroll
GSAP WebGL Knockout Dive & Aperture Scroll Section
On Scroll · On Load · Mouse Move · On Hover
No. 020 / Preloader
GSAP Column Preloader & Blooming Lily Hero Section
On Load · On Scroll · Mouse Move · On Hover
(02)FAQ
GSAP Pinned Statement Hero with Expanding Photo — FAQ
01What do I need to install?
npm install gsap @gsap/react, plus lenis if you keep the optional smooth scroll. ScrollTrigger comes with gsap. It's built for Next.js (it uses next/image) with Tailwind CSS v4.
02How do I change the statement?
Pass a lines array, one entry per line: its text, an optional word from it to set in italic in the accent colour, an optional indent in vw (phones, then wider screens) and a shift, how far the line slides while the hero is pinned, in vw. Give neighbouring lines opposite signs so they slide apart. The eyebrow, blurb and scrollLabel props set the small print.
03How do I add my own services and photo?
Pass services: a title, a colour and a portrait photo (2:3 suits the cards) for each. Four read best; the fan, the dots, the list down the right and the colour washes behind them all follow the array. The photo prop takes src, width and height (a static import works as it is), because the hero needs the aspect ratio to crop it as the frame opens up. A portrait with the face near the top suits the crop.
04Which fonts does it use?
The statement is set in Bodoni Moda: load it with next/font as the --font-bodoni-moda variable, with axes: ["opsz"] for the hairline cut at display sizes. It falls back to a system Didone. Everything else uses your page's sans; the demo uses Manrope.
05Can I put other sections above and below it?
Yes. It pins when its top reaches the top of the screen, stays for two and a half screens of scroll (pin in config.ts) while the photo opens up, then lets the page carry on.
06Does it work with Lenis?
Yes. Render the SmoothScroll that comes with it once on the page. If your page runs its own Lenis, connect it with lenis.on("scroll", ScrollTrigger.update) and drive it from gsap.ticker.
07How do I tune it?
The colours (ink, paper, the canvas behind it and the accent), how long it stays pinned and the smooth scroll's lerp are in config.ts. The intro's timings and the pinned timeline are in statement-hero.tsx.