Motion pattern

Scroll Image Reveal

A scroll image reveal uncovers an image as it enters the viewport, using a clip-path wipe, a mask, or a dissolve rather than a plain fade. The reveal is tied to scroll position so the image 'arrives' with intent. Built on GSAP ScrollTrigger, animating clip-path or a shader uniform rather than layout properties.

Updated June 2, 2026

Components

Components that solve this

Tradeoffs

Tuning the pattern

Reveal mechanism
A clip-path or mask wipe (Mask Reveal, Rectangle Text Reveal) is GPU-composited and free of texture cost, so it is the default for almost everything; the WebGL noise dissolve (Image Dissolve Scroll) pays for a context and texture upload, so reserve it for one or two signature hero images where a hard clip edge would look too mechanical.
Scrub vs trigger
Scrub-bound reveal (Mask Reveal defaults `scrub` true) ties the wipe to scroll position and reads best on full-bleed hero imagery the user dwells on; a play-once-on-enter (Rectangle Text Reveal and Element Reveal default `scrub` false) is snappier and the right call for grid tiles and screenshots that should resolve and stay put.
Direction
Bottom-up and left wipes (Rectangle Text Reveal defaults `direction` left, Mask Reveal `toward` center) read as the image rising into place and suit downward scroll; center-out and circular reveals draw more attention, so save them for the single image that carries the section rather than every visual on the page.
When

When a scroll image reveal fits

The pattern adds weight to imagery as it enters. It works when the image deserves a moment, not when you have a dense grid of thumbnails.

  • Editorial hero images that should 'land' as the user scrolls to them
  • Case-study visuals that punctuate long-form copy
  • Feature screenshots on a product page
  • Full-bleed section images between content blocks

Reveal the right number of times

A reveal on every tile in a 40-image grid is noise, not craft. Reserve the effect for the few images that carry weight; let the rest load plainly.
Mechanics

How the reveal works

The cleanest mechanism is an animated clip-path inset. The image is fully rendered; the clip-path starts collapsed and opens as scroll progresses. Because clip-path is GPU-composited, the reveal stays smooth even at full-bleed size.

script.js

For a higher-craft dissolve, render the image to a WebGL plane and scrub a noise-driven dissolve uniform instead of a clip-path. That's the Image Dissolve Scroll component's approach.

In production

Annnimate components that solve this pattern

  • The Mask Reveal component wipes a clip-path mask across an image or block on scroll-enter
  • The Rectangle Text Reveal applies the same rectangle-wipe mechanic, tuned for headlines
  • The Image Dissolve Scroll shader scrubs a noise dissolve uniform for a higher-craft reveal
  • The Element Reveal is the general-purpose scroll-enter reveal for any block, not just images
FAQ

Common questions

Should I animate clip-path or opacity for image reveals?
clip-path for a directional wipe (the image is uncovered), opacity for a plain fade. Both are GPU-friendly. clip-path reads as more intentional because it has direction and a hard edge; opacity reads as softer. For hero imagery, clip-path almost always looks more crafted.
Why does my scroll reveal jump on mobile?
Mobile address-bar resize fires scroll and resize events that shift ScrollTrigger's cached positions. Add invalidateOnRefresh: true to the trigger and call ScrollTrigger.refresh() after the layout settles. Avoid 100vh sizing on the trigger element - it changes when the address bar hides.
When is a WebGL dissolve worth it over a clip-path?
When the reveal is a signature moment and a hard clip edge looks too mechanical. A noise dissolve has an organic, filmic quality a clip-path can't match. The cost is a WebGL context and texture upload, so reserve it for one or two hero images, not a whole grid.
Related patterns

Adjacent ideas in the patterns