@magic-spells/scroll-progress

Scroll
Progress

High-performance scroll tracking via CSS custom properties. Configurable playhead anchors, velocity physics, and GPU-accelerated animations — no scroll event listeners.

Install npm i @magic-spells/scroll-progress
Size (gzip) ~2.2 KB

Quick Start

Import the component, wrap your content, and animate with the --scroll-progress CSS variable.

HTML
<script type="module" src="scroll-progress.js"></script>

<scroll-progress
  playhead-element-start="top"
  playhead-element-end="bottom"
  playhead-viewport-start="bottom"
  playhead-viewport-end="top">

  <div style="opacity: var(--scroll-progress)">
    Fades in as you scroll
  </div>

</scroll-progress>
JavaScript
const el = document.querySelector('scroll-progress')

// Read current progress (0–1)
el.getProgress()

// Read current velocity
el.getVelocity()

// Listen for changes
el.addEventListener('scroll-progress:update', e => {
  console.log(e.detail.progress)
})

// Pause / resume the RAF loop
el.pause()
el.resume()
"top"
"center"
"bottom"

Element Playhead

Every <scroll-progress> element has four anchor attributes that control when progress starts and ends.

playhead-element-start / end — the point on the element itself: top, center, or bottom.

playhead-viewport-start / end — the point on the viewport that triggers it: top, center, or bottom.

Progress is 0 when the element-start anchor reaches the viewport-start anchor, and 1 when the element-end anchor reaches the viewport-end anchor.

Default Playhead

Tracks from when the element enters the viewport (bottom) to when it exits (top). The progress bar fills as you scroll through.

playhead-viewport-start="bottom"
playhead-viewport-end="top"
playhead-element-start="top"
playhead-element-end="bottom"

0.18x
0.45x
0.8x
1.3x
1.7x

Transition Out

Triggered by the top of the screen — progress starts at 0 when the element is at the top and reaches 1 as it scrolls away. Great for exit animations.

playhead-viewport-start="top"
playhead-viewport-end="top"
playhead-element-start="top"
playhead-element-end="bottom"

Symmetric Playhead

Both start and end anchored to the viewport center. Text reveals from center outward as the element crosses the midpoint.

playhead-viewport-start="center"
playhead-viewport-end="center"
playhead-element-start="top"
playhead-element-end="bottom"

PROGRESS
PROGRESS

Sunset to Starlight

Sky transitions from golden hour to deep night. Mountain layers separate with parallax depth. Stars emerge in the second half.

default playhead (bottom → top)

Centered Playhead

Element center tracked against viewport edges. The ring orbits through the full color spectrum as it traverses.

playhead-viewport-start="bottom"
playhead-viewport-end="top"
playhead-element-start="center"
playhead-element-end="center"

720° rotation + oklch hue cycle

Reversed

Layers converge inward instead of separating — parallax values push elements down as progress increases.

playhead-viewport-start="bottom"
playhead-viewport-end="top"
playhead-element-start="top"
playhead-element-end="center"

0.13x
0.42x
0.83x
1.12x
1.68x

Multi-Effects

Rotation, scale, opacity, blur, clip-path, color cycling, and typography — all from a single --scroll-progress value.

default playhead (bottom → top)

rotate 720°
scale up
scale down
blur + fade
hue cycle
clip wipe
effects