Scroll-driven hero transitions
Two images that morph as the visitor scrolls past. Pair with
@vysmo/transitions for the shader; the
scrollPlateau envelope holds the final frame
across the middle of the section.
Three primitives that bind scroll progress to the rest of the ecosystem: createScrollProgress (raw 0–1 emitter), createScrollTransition (drives any @vysmo/transitions render), createScrollEffect (drives any @vysmo/effects params). One shared rAF-throttled observer underneath.
$ pnpm add @vysmo/scroll View on GitHub Low-level emitter — 0 when the section enters the viewport from below, 1 when it exits through the top. Remap with ease for any non-linear progress.
Scroll progress drives a transition through three zones. Entry zone: transition plays 0 → 1. Clear zone: holds at the to image. Exit zone: plays back1 → 0. The green band on the bar is the clear zone — drag the handles to reshape it.
Scroll progress drives effect params through a three-zone envelope from scrollZones(clearStart, clearEnd). Effect ramps in as the section enters, sits at identity through the clear zone, ramps back as it exits. The dark band on the bar is where the image is fully clean.
Drive any value off scroll with createScrollProgress,
or hand a @vysmo/transitions /
@vysmo/effects runner to the dedicated primitives
and let them re-render on every frame the position changes.
import { createScrollProgress } from "@vysmo/scroll";
const handle = createScrollProgress({
element: document.querySelector("#hero")!,
onProgress: (p) => element.style.opacity = String(p),
}); import { createScrollTransition, scrollPlateau } from "@vysmo/scroll";
import { Runner, crossZoom } from "@vysmo/transitions";
const runner = new Runner({ canvas });
createScrollTransition({
section,
runner,
transition: crossZoom,
from, to,
ease: scrollPlateau(0.3, 0.7), // hold the "to" image mid-section
});
Two images that morph as the visitor scrolls past. Pair with
@vysmo/transitions for the shader; the
scrollPlateau envelope holds the final frame
across the middle of the section.
Blur, pixelate, or chromatic-aberrate an image as it enters
and exits the viewport, identity in the middle. The
scrollZones bathtub envelope is purpose-built
for this — minimal eye-candy where it matters, clean where
the user is reading.
Drive @vysmo/flipbook's seek()
off scroll progress for cinematic page reveals tied to scroll
position — books and lookbooks that turn as the visitor
scrolls down the page.
Pin diagrams or charts in view, animate them as the reader progresses through the surrounding paragraphs. Scroll progress is the universal storytelling clock on the web.
Driven sequences: image fades in, gets a soft blur as the reader continues, then ramps to a different shot — without the build-your-own scroll-driven plumbing. One observer, one callback per section.
The shared rAF-throttled observer and zone helpers are useful
even if you ship your own canvas / DOM rendering — subscribe
via sharedScrollObserver() and you get the same
one-rAF batching as the rest of the ecosystem.