Scroll animation without a library
Sticky positioning, one shared rAF loop, and a CSS custom property will carry a surprising amount of choreography.
Sample post. This entry is placeholder content used to build out the journal. It is not a statement by or about Tecnicubes.
Reaching for an animation library is reasonable. It is also worth knowing what the platform gives away for free, because the answer has changed a lot.
Let the browser do the pinning
position: sticky pins an element without JavaScript and without forcing layout on every frame. A tall track with a sticky child is the whole mechanism behind most pinned-scene effects.
One loop, not one per scene
The cost is rarely the animation itself; it is having twenty listeners each doing their own measurement. Register scenes into one set, run one requestAnimationFrame loop, and skip anything off screen.
function tick() {
frame = 0;
const y = window.scrollY;
for (const scene of active) {
const p = clamp01((y - scene.top) / scene.travel);
scene.el.style.setProperty('--p', p.toFixed(4));
}
}Publish progress, don’t re-render
Writing a custom property lets CSS do the interpolation on the compositor. The component tree never re-renders while scrolling, which is usually the difference between smooth and not.
If your scroll handler calls setState, you have already lost the frame budget.
Respect the setting
prefers-reduced-motion is not a nice-to-have. Collapse the tracks, resolve every scene to its composed state, and let the page become an ordinary stack of panels.