Scroll this panel. The reader's scroll position is the timeline: the trail draws itself, the sun climbs, and three layers parallax at different speeds.
Instead of a clock, the animation progress comes from how far you've scrolled (0 → 1). Keep scrolling and watch the lime trail extend.
The trail is one path. We set stroke-dasharray = length and move stroke-dashoffset from length to 0 as progress goes 0 → 1 — the Part 6 line-drawing trick, scrubbed by scroll.
#trail {
stroke-dasharray: var(--len);
stroke-dashoffset: var(--len);
animation: draw linear both;
animation-timeline: scroll(root); /* progress = page scroll */
}
@keyframes draw { to { stroke-dashoffset: 0; } }Three mountain layers translate at different rates — far moves least, near moves most. That speed difference is the entire illusion of depth.
const p = scrollTop / (scrollHeight - clientHeight); // 0..1
trail.style.strokeDashoffset = len * (1 - p);
far.style.transform = `translateX(${-20 * p}px)`;
near.style.transform = `translateX(${-80 * p}px)`;At full scroll the trail completes, the hiker reaches the peak, and the sun is high. Scroll back up to play it in reverse — scroll timelines are inherently scrubize.
Bar at the very top is a native animation-timeline: scroll() progress indicator (in supporting browsers).