The gradient bar above tracks your scroll position. Cards below reveal with inView() + animate().
scroll() — progress callback
0
% scrolled
One callback, three effects
scroll(fn) calls fn with a progress value (0–1) on every scroll frame. The progress bar, parallax orb, and this counter all update from the same single callback.
scroll() — parallax
Glow drifts upward
Moves at 40% of page scroll speed via progress × −80px
inView() + animate() — entrance
inView(selector, callback)
Fires once when the element enters the viewport. Return the cleanup function to auto-disconnect after first play.
animate(target, keyframes)
Drives WAAPI directly. Pass a selector string, element, or NodeList. Keyframes use the same syntax as CSS.
easing: [0.22, 1, 0.36, 1]
Cubic-bezier array shorthand. Fast in, soft landing — a good default for entrance animations.
margin option
margin: '0px 0px -15% 0px' shrinks the root margin — fires when the element is 15% inside the viewport, not at the edge.
The code
// scroll() — progress 0–1 in callback
scroll(function(p) {
bar.style.transform = 'scaleX(' + p + ')';
orb.style.transform = 'translateY(' + (-80 * p) + 'px)';
pct.textContent = Math.round(p * 100);
});
// inView() + animate() — entrance on scroll
inView('.reveal-card', function(info) {
animate(info.target, { opacity: [0, 1], y: [20, 0] },
{ duration: 0.5, easing: [0.22, 1, 0.36, 1] });
}, { margin: '0px 0px -15% 0px' });