Skip to content
animorio
IT
Back to the library

The hour that covers the photo

Scroll down and the strip moves sideways; when a panel with the time arrives, the slide before it stays still and shrinks while the panel covers it.

Scroll, Images, TextGSAPAdvancedLifetime

Scroll inside the preview

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN.

The code for this animation is part of lifetime access.

The preview stays open: watch it, slow it down, try it on your phone.

Lifetime access

What it does

The page is a strip of slides in a row: texts, photographs, a title with a photo in the middle. Scrolling down moves the strip sideways, and every photo also slides inside its frame, a little slower. Then a panel as wide as the screen arrives with a huge time: the slide in front of it does not leave, it stays still on screen and shrinks away while the panel slides over it, and the digits of the time rise one at a time out of their mask.

How it works

The strip

A screen as tall as the window with position: sticky and overflow: hidden; inside, a flex track as wide as all the slides. The section is as tall as the track's travel plus one screen, and a single scrubbed timeline moves the track one pixel left for every pixel scrolled. It is linear (ease none): the other effects need it that way.

Hooked effects

Every other ScrollTrigger uses containerAnimation: the track's timeline. So start and end are written horizontally, for instance 'left right' (the element's left edge touches the screen's right edge) to 'right left'.

The photo in its frame

Inside each frame there is a layer 120% wide. While the frame crosses the screen the layer goes from a negative x (as much as it overhangs) to zero: the photo seems farther away than the page.

The panel that covers

While the panel goes from 'left right' to 'left left', the slide before it moves right by the panel's width: the track carries it left, it moves right, and on screen it stands still. In the first quarter of that travel its content goes to scale 0.86 and disappears; then the digits of the time rise out of their masks one after another.

Values to change

NameFileDefaultWhat it changes
RIMPICCIOLISCEscript.js0.86How far the covered slide shrinks while it disappears.
SPARISCEscript.js0.25At what fraction of the panel's travel the covered slide has already gone.
PARALLASSEscript.jstruePhotos slide inside their frame. With false they stay still.
data-oraindex.htmlsul pannelloAny slide with data-ora covers the one before it. It can hold a time, a title, a big number.

When to use it

For a photo story that runs like a roll of film: a reportage, a day, a collection. The covering panel is a chapter change without changing page.

On phones

The strip stays horizontal and is driven by the finger just like the wheel: frames and titles adapt to the screen height.

With reduced motion

No strip: the slides sit one below the other, the photos are still and the time panels are ordinary sections.

Pitfalls

  • The track timeline must have ease none: containerAnimation computes horizontal positions assuming linear movement.
  • The section height must be recomputed before every refresh (refreshInit event): if the track width changes, so does how far you need to scroll.
  • The covered slide's offset must be a function (x: () => panel width) with invalidateOnRefresh, or after a resize the slide drifts away.
  • Do not put transforms on the sticky screen: a transform on an ancestor breaks position: sticky.

Libraries

GSAP 3.15.0, ScrollTrigger (GSAP) 3.15.0, Mona Sans (font variabile) 5.3.0.

Weight: 24 KB of our own files.

Testing

Tested on 27 September 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: Done

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All animations