useScrollProgress
useScrollProgress(target: Element, options?: { offset?: string }): Service<ScrollProgressProps>An element's progress through the viewport as it scrolls.
Props
interface ScrollProgressProps {
readonly startX: number;
readonly startY: number;
readonly endX: number;
readonly endY: number;
readonly currentX: number;
readonly currentY: number;
readonly progressX: number;
readonly progressY: number;
}start and end are the scroll positions at which the progress is 0 and 1; current is where the scroller is now.
Usage
import { Base, useScrollProgress } from '@studiometa/js-toolkit';
class Parallax extends Base {
static config = { name: 'Parallax' };
mounted() {
return useScrollProgress(this.$el).subscribe(({ progressY }) => {
this.$el.style.setProperty('--progress', String(progressY));
});
}
}The offset option
One string holding two edge pairs, separated by a /:
"<target> <viewport> / <target> <viewport>"The first pair is where the progress is 0, the second where it is 1. In each pair, the first token is an edge of the target and the second an edge of the viewport.
The default is:
useScrollProgress(el, { offset: 'start end / end start' });which reads as "0 when the target's start meets the viewport's end, 1 when the target's end meets the viewport's start" — the element travelling the full height of the viewport.
Each token is one of:
| Token | Means |
|---|---|
start | the leading edge |
center | the middle |
end | the trailing edge |
50% | a fraction of the box |
120px | an absolute offset from the edge |
20vh, 10vw, 5vmin, 5vmax | a viewport unit |
| a number | a fraction, as 0.5 |
A token that parses as nothing falls back to the edge.
The resolved offset is part of the service's key, so two callers asking for the same range on the same element share one service.
Mixin
class Parallax extends withScrollProgress(Base, { offset: 'center end / center start' }) {
scrolledInView({ progressY }) {}
}The hook is named scrolledInView.
Smoothing a progress value
Progress props carry no frame delta, and damp() takes the elapsed time as a required argument — decay is expressed in time, not in frames. So either take the delta from a useRaf() tick, or use smoothTo(), which owns its own frame subscription and releases it when the value arrives.