All effects
Transitions

Scroll-Driven Animation

Animation progress locked to scroll position - fully reversible, pausing exactly where your scrolling stops.

AI Prompt
Bind the animation's progress to scroll position: scrolling is reversible, animation progress maps one-to-one with the scrollbar, and stopping the scroll freezes the animation at the corresponding frame (progress bar and track dot follow, with continuous hue rotation). Implement with native JS scroll events (mention CSS scroll-driven animations as progressive enhancement).

How it works

The whole system is one formula: progress p equals scrollTop divided by the scrollable height (scrollHeight minus clientHeight). A passive scroll listener reads the position, normalizes it, and writes outputs derived from p: the progress bar's height via scaleY, the dot's position via translateX along a rail, and the accent color via an hsl hue that rotates with p. Because every frame recomputes from the current scroll position rather than accumulating state, reversibility and pausing are automatic - there is no play-head to sync, only a function.

Modern browsers offer an even cleaner path: CSS scroll-driven animations, where animation-timeline: scroll() binds a keyframes animation to the scroller in pure CSS with zero JavaScript. The JS approach in this demo is the compatibility baseline that behaves identically everywhere; mention both to your AI and let it feature-detect.

How to use this prompt

Ideal for long-page storytelling: chapter progression on marketing sites, features lighting up section by section, reading progress indicators. Send the prompt listing which visuals should bind to progress - bars, parallax images, counters - and the AI generates the mapping. To target modern browsers first, add: prefer animation-timeline with a JS fallback.

Tips for better results

Do not map p linearly to visuals; wrap it in an easeOut so constant-speed scrolling produces perceived acceleration - instant premium feel. iOS rubber-band scrolling produces negative scrollTop values, so clamp p to the 0-1 range or the dot escapes the rail. Recompute scrollable height on resize, ideally through a ResizeObserver. And when dozens of elements follow the same progress, write all their values inside a single requestAnimationFrame loop instead of binding separate scroll listeners - callback count drops by an order of magnitude.