Scroll Animation
A router into ten scroll-animation patterns. All patterns except JOS are built on the same React + Framer Motion primitives — useScroll + useTransform (+ useSpring for smoothing) — so read this file first for the shared mental model, then load only the reference file(s) that match what the user wants.
Shared Mental Model (Framer Motion patterns)
Nearly every effect in this skill follows the same skeleton:
import { motion, useScroll, useSpring, useTransform } from "framer-motion";
import { useRef } from "react";
const containerRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start start", "end end"],
});
const smoothProgress = useSpring(scrollYProgress, {
damping: 25, // 20–30: higher = less bounce
stiffness: 200, // 150–300: higher = snappier
mass: 0.5, // 0.5–0.8: lower = lighter/faster
});
const someValue = useTransform(smoothProgress, [0, 1], [startVal, endVal]);
- Container height controls speed/drama. More
vh= slower, more cinematic scroll. Typical range:150vh(snappy) to400vh(meditative). position: sticky; top: 0pins content to the viewport while the tall container provides scroll room to animate through.- Always wrap raw
scrollYProgressinuseSpring— without it, motion feels robotic/linear instead of physical. - Multi-element effects (stacks, grids, orbiters) give each item a window:
start = index / total,end = start + 1 / total, then map[start, end](or a 5-point bell curve for peak-in-middle effects) to that item's transforms. - Respect
prefers-reduced-motion: fall back to a static layout or simple fade for users who request it.
Choosing a Pattern — Selection Guide
Read the matching reference file in references/ for the full component code, variants, critical rules, and troubleshooting table. Don't guess at the transform values from memory — the reference files have tuned, working numbers.
| User asks for... | Read this reference |
|---|---|
| Cards piling up / sticking as you scroll, generic "stacking cards", 3D tilt stack, multi-layer stack, horizontal card stack | references/scroll-stack.md |
| Specifically "Chronos style" stacking, aggressive cinematic card recession with shadow/radius growth | references/chronos-scroll-stack.md |
| Multi-speed depth layers, background/foreground moving at different speeds, "insane"/dramatic parallax, floating accent shapes | references/insane-parallax.md |
| Apple-style hero zoom into an image, focus-pull blur, layered text reveals over a zooming image, cinematic product launch zoom | references/immersive-scroll-zoom.md |
| Gallery images zooming in as they enter view, product focal-point zoom, grid of images with scroll-driven scale | references/image-zoom-scrolling.md |
| Image splitting into halves/quadrants and separating, diagonal shatter, agency-portfolio-style reveal with 3D tilt | references/image-split-3d.md |
| Orbiting elements, circular progress rings, radial/spiral galleries, text following a circular path | references/circular-scroll.md |
| Cards/tiles that grow/scale as they become active, bell-curve grid expansion, masonry click-to-expand | references/expanding-cards-scroll.md |
| Frame-by-frame scrubbing, "flipbook" scroll, canvas image sequences, product reveal video bound to scroll position | references/scroll-image-sequences.md |
| Simple fade/slide/zoom-in reveals, staggered reveals, NOT using React/Framer Motion, or explicitly "JOS" | references/jos-animation.md |
If the request is ambiguous or could fit several patterns (e.g. "make the hero more dynamic on scroll"), prefer insane-parallax.md or immersive-scroll-zoom.md for hero sections, and ask only if genuinely unclear — otherwise pick the closest match and note the assumption.
Cross-Cutting Rules (apply regardless of pattern)
- Framer Motion only for every pattern except JOS — no GSAP, no vanilla scroll-listener code, unless the user explicitly asks for a non-Framer-Motion implementation.
- Spring defaults that work well almost everywhere:
damping: 20–30,stiffness: 150–300,mass: 0.5–0.8. Each reference file gives the exact tuned values for that pattern — use those over these general defaults when they differ. willChange: "transform, opacity"on animated elements to keep things on the compositor thread.- z-index math for anything stacked: usually
total - indexso earlier elements sit on top while receding. - Don't over-animate. 3–8 cards/frames/layers is usually the sweet spot; more becomes fatiguing or hurts mobile performance.
- Mobile: soften scale ranges, reduce layer/frame counts, and prefer
whileInViewover long scroll-driven sequences where drama isn't essential.
Combining Patterns
These patterns compose. A landing page might use insane-parallax for the hero, scroll-stack for a features section, and jos-animation for simple staggered fade-ins elsewhere on the same page. Read each relevant reference file independently — they don't depend on each other except where noted (e.g. scroll-stack.md points to chronos-scroll-stack.md for the full cinematic variant).