161

Photo Reel Zoom

£7
or the whole Vault, £99

Pinned scroll section where a small frame flicks through aligned photographs like a flipbook as it grows to full bleed, with hard colour cuts around a subject who stays put, then a closing message over the final picture.

ScrollTrigger intermediate
6 more details
pinningscrubzoomclip-pathimage-sequencescroll-storytelling

Released

About this effect

A pinned chapter that sells variety in a single gesture. A small frame sits in the middle of the stage with the headline above and below it, and scrolling flicks it through a set of aligned photographs like a flipbook. Because the pictures are registered, the subject stays exactly where she is while everything around her changes colour in hard, stop-motion cuts.

Read the full effect overview

The flicks are quick at the start and slow into longer holds as the frame grows, the stage ground snaps to a soft tint of each picture, and the growing frame shoulders the headline off the top and bottom of the stage. It lands full bleed and pixel-sharp on the last picture, then a closing heading and sentence arrive over it. The whole passage runs cleanly in both directions and releases into normal scrolling with no jump.

Photo Reel Zoom - GSAP animation effect preview

What's included

8 items
  • Hard-cut flipbook driven by scroll: any number of aligned photographs, with no cross-fades and no blank frames
  • Cuts are spaced to slow down: quick flicks while the frame is small, longer holds as it nears full size
  • The stage ground snaps to a soft tint set per image in your markup, so the whole section changes colour with each cut
  • Lands exactly full bleed at 1:1 on any screen shape, with no scaled-up raster, seams or bars
  • Every frame is decoded before the pin starts, and a slow frame is skipped rather than shown blank
  • Frames are plain img or video children, so swapping in your own set is a markup change
  • Headline and closing message are real text in their own slots, and two sections on one page run independently
  • Reduced-motion, no-JS and blocked-CDN visitors get the final picture full bleed with every word readable

Perfect for

5 use cases
  • Fashion and apparel pages showing one product in every colourway
  • Furniture, car and homeware launches where a finish or fabric is the choice being sold
  • Lookbooks and campaign pages built from a series shot on a locked-off camera
  • Before and after or time-lapse stories told as a run of aligned stills
  • Long product pages that repeat the section as chapters, each with its own photo set, headline and closing message

How it works

2 sections

A pinned ScrollTrigger scrubs one timeline across the section. The photographs are stacked at their final size and only one is visible at a time, so a cut changes nothing except which picture is showing and the colour of the ground behind it. The growing frame is a clip on that stack, which never has to scale past its true size, so the landing stays sharp.

All the frames are preloaded and decoded before the pin begins, so the flips cannot flash blank. Touch devices get a shorter pin distance, and reduced-motion visitors get a static full-bleed layout with no pin at all.

Plugins ScrollTrigger
Difficulty Intermediate
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

The Vault opens this source and the whole library.

Each product gives you the HTML, CSS and JavaScript source, the full documentation and an AI setup prompt, licensed for unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

One payment, over 300 products, and future additions to the library.

Documentation

Quick Start

1. Add to your HTML <head>:

In your downloadThe working code for this step, in index.html.

2. Add before the closing </body> tag:

In your downloadThe working code for this step, in index.html.

3. Add the section wherever it belongs on the page:

In your downloadThe working code for this step, in index.html.

Using It With Your Own Design

What the effect needs from your markup: .prz as the root, .prz__stage directly inside it, then .prz__frame wrapping .prz__media. The frames are the <img> or <video> children of .prz__media, and they play in markup order, ending on the last one. The headline, cue and payoff are all optional. Each .prz__line is one line of the headline: the first half of the lines is pushed up by the growing frame and the second half is pushed down, so one, two or more lines all work. Change the words by editing the spans.

Any image or video can go in the media slot. Only the frames in .prz__media change, so one photograph is fine too: the frame simply grows with no cuts. For a muted looping video as the landing frame, make it the last child:

In your downloadThe working code for this step, in index.html.

A video plays only while it is the frame on show, and is held still for reduced-motion visitors.

Preparing an aligned set:

  • Shoot or generate every frame from one locked-off position, so the subject stays still when the pictures flick. Check by flicking through them in any image viewer: the only thing that should move is the colour.
  • Export every frame at the same pixel size and crop. The demo uses 1672x941.
  • Keep them light, because every frame is loaded before the pin starts. Flat backdrops compress very well as WebP.
  • Give each frame a --tint in its style attribute: a soft version of its colour, for the stage ground. Keep it pale enough that --prz-ink passes 4.5:1 against it. A frame with no tint leaves the ground as it is. The ground stays on --prz-ground until the first cut.

What is only the demo's styling: the font, the * reset and body rules at the top of style.css, the colour tokens, the diagonal placement of the two headline lines, and the two-column payoff. Restyle any of them freely. The cue is optional.

CSS the effect depends on:

  • The rules under @media (prefers-reduced-motion: no-preference) with the .has-js gate. They build the pinned layout and hold the first state before the script runs, so keep the gate or the page will flash.
  • object-fit: cover on the frames, with .prz__media filling the stage. The frames must be laid out at their final size.
  • .prz__stage at a full viewport height with overflow: hidden.
  • No transform, filter or contain on an ancestor of .prz, since that changes how a pinned element is positioned.

Tokens are set on .prz and can be overridden per section:

Token Default Description
--prz-ground #ececeb Ground before the first cut
--prz-ink #141412 Headline and cue colour
--prz-payoff-ink #ffffff Payoff text colour
--prz-scrim-rgb 44 14 0 Scrim colour behind the payoff
--prz-scrim-strength 0.27, 0.38 on phones Scrim opacity. Set for the demo's picture, so raise it for a brighter one until the body text passes 4.5:1
--prz-focus 49% 50% object-position of every frame. Use it to keep the subject in the crop
--prz-start-scale 0.52 Starting frame height as a share of the stage
--prz-start-aspect 0.75 Starting frame width over its height

Options

Attribute Values Default Description
data-prz-distance Number 300 Pin distance as a percentage of the viewport height. Touch devices use 72% of this
data-prz-scrub Seconds, or true 0.6 How long the reel takes to catch up with the scroll. true or 0 locks it to the scrollbar
data-prz-rounds Whole number 2 How many times the reel runs through the set before landing. Use 1 for a large set

Accessibility

  • Reduced motion: visitors get a static layout with no pin: the headline on the ground, then the last picture full bleed with the payoff over it.
  • No JavaScript or a blocked CDN: the same static layout. The script removes .has-js when GSAP is missing.
  • Screen readers: the headline is one real heading however it is split. Hidden frames are not announced, and each frame can have its own alt text. Use alt="" where the text around it already says it.
  • Contrast: in the demo the headline passes against every tint, and the payoff text is at least 4.5:1 over the scrim. Check both against your own pictures and tints.
  • Touch: the section scrolls normally with a shorter pin distance. On phones the type is resized to fit and the payoff stacks. Set --prz-focus to keep your subject centred in the narrow crop.

Dependencies

  • GSAP 3.12+ with the ScrollTrigger plugin. The demo is pinned to 3.15.0.
  • The demo uses Schibsted Grotesk from Google Fonts. Any font works.

Also in your download: the full source, worked examples, the events and programmatic API, and the class reference.

£7