useScrollProgress
@sushindustries/uiHow far one element has travelled up the viewport, 0 to 1, once per frame. Gated by an observer so an off-screen element costs nothing.
finishAt is measured from the bottom of the screen
It is a fraction of viewport height, not of the element's own height. 0.55
means progress reaches 1 once the element's top has climbed to 55% up the
screen from the bottom - short of dead centre on purpose, because an
animation that finishes exactly as it arrives at the middle was never seen
finishing. Raise it towards 1 to have the animation complete earlier, while
the element is still lower on the screen.
It needs room to travel in
The element itself does not need explicit height, but its scroll container
does: progressProgressThe native progress element, restyled - omit value and the indeterminate state is real.@sushindustries/ui · content is computed from getBoundingClientRect() against
window.innerHeight, so a page - or a stageRef element - with nothing
below the fold to scroll through never produces a value past 0.
whenVisible is a cost cut, not a feature
With it on (the default), an IntersectionObserver gates the scroll
listener so an element nobody can see is never measured. Turning it off
means onProgress runs on every scroll and resize regardless of where the
element is, which is only worth it if the callback needs to run before the
element is anywhere near the viewport.
Reduced motion skips straight to finished
Under prefers-reduced-motion: reduce, onProgress(1) fires once and no
listener is ever attached. Whatever this drives ends up in its arrived
state immediately rather than a frozen mid-transition one - the preference
asks for less movement, not a broken layout.