- Home
- Skills
- Frontend & Web Apps
- Scroll Forensics — Reverse-Engineer Scroll Animations
More screenshots
Works with the AI Agents you already use
Scroll Forensics — Reverse-Engineer Scroll Animations
Point your agent at a reference site and get the measured scroll mechanics — stack, easings, parallax factors, pin durations — plus a from-scratch rebuild plan.
$13.90
Scroll Forensics — Reverse-Engineer Scroll Animations
Example session with this skill installed
/scroll-forensics-sophismart https://lenis.dev — how is that horizontal section built? Give me the real numbers so I can rebuild it in my own project.
- Read your context and instructions
- Compiled the scroll forensics
Scroll report — lenis.dev
Analyzed Oct 13, 2026 · headless Chromium 1440×900 · 49 samples · robots.txt: allowed · pre-load instrumentation: yes
One-line verdict
Lenis smooth scroll + a sticky horizontal track: a position: sticky stage holds while a JS-written translateX scrubs
5,040 px across 9.3 viewports of scroll — linear (R² 0.996), no easing on top.
Detected stack
| Layer | Technology | Confidence | Evidence |
|---|---|---|---|
| Smooth scroll | Lenis | High | .lenis class on <html> |
| Rendering | Three.js / WebGL | Medium | 1 canvas with a WebGL context |
| Pinning | CSS sticky | High | computed position: sticky on the stage |
| Timeline library | GSAP | Not found | no window.gsap, no .pin-spacer |
Mechanics per section
Horizontal showcase
Technique: sticky stage (100vh) inside a tall wrapper; the inner track is moved with an inline transform written by JS every frame
- Scroll range: 3,809 → 12,187 px (8,378 px · 9.3 viewports)
- Animated property:
translateX0 → −5,040 px - Curve: linear (fit error 2.56%, R² 0.9962) — pure scrub
- Trigger: continuous scroll progress, no discrete state
Background layer
- Fixed layer drifts
top−539.8 → −899.6 px over 0 → 15,996 px (factor 0.0225) - Best fit
cubic-bezier(0.22, 1, 0.36, 1)(quart.out), error 1.48% — long tail: only 1.6% of the travel happens in the last 30%
Numbers extracted
| Element | Property | Start → end (scroll px) | From → to | Factor | Easing | R² |
|---|---|---|---|---|---|---|
| horizontal track | translateX | 3,809 → 12,187 | 0 → −5,040 px | 0.60 | linear | 0.996 |
| fixed background layer | top | 0 → 15,996 | −539.8 → −899.6 px | 0.0225 | quart.out | 0.690 |
| sticky section heading | top | 0 → 19,804 | 1,220 → −16,143 px | 0.88 | linear | 0.990 |
1 series discarded as plain 1:1 page movement (no effect of its own).
Instrumented before load
- 23 IntersectionObservers:
rootMargin 200px / threshold 0and0px / 1 - 8 scroll listeners, all passive
- 0 wheel
preventDefault→ no virtual-scroll hijack
Details that make it feel premium
Linear track, smooth scroll. The softness comes from Lenis, not from the curve — easing the track would make it feel slower, not richer.
- The stage height buys the scroll. The track finishes exactly as the pin releases: wrapper ≈
100vh + 8,378px.
It holds before it moves. The track stays at 0 until 3,809 px, so the section settles on screen before the motion starts.
- Transform only.
translate3dstays on the compositor: 60.2 fps at 179 rAF calls/s under scroll.
Cost & accessibility
- fps under scroll: 60.2 (headless)
- prefers-reduced-motion: ignored — Lenis and WebGL stay active with
reduceon - Mobile 390×844: pin survives, 2 sticky blocks
Reimplementation plan (your own code)
.rail { height: calc(100vh + 8378px); }
.rail__stage { position: sticky; top: 0; height: 100vh; overflow: hidden; }
.rail__track { display: flex; will-change: transform; }
@media (prefers-reduced-motion: reduce) {
.rail { height: auto; }
.rail__stage { position: static; overflow-x: auto; }
}
const rail = document.querySelector('.rail');
const track = rail.querySelector('.rail__track');
const TRAVEL = 5040; // px · measured amplitude
const RANGE = 8378; // px · measured active range
function update() {
const p = Math.min(Math.max((scrollY - rail.offsetTop) / RANGE, 0), 1);
track.style.transform = `translate3d(${-TRAVEL * p}px,0,0)`; // linear on purpose
}
addEventListener('scroll', update, { passive: true });
update();
Build order: static horizontal layout → sticky stage + wrapper height → linear scrub with the numbers above → smooth scroll on top → reduced-motion and 390 px check.
Limitations of this analysis
- Range edges resolve to one sampling step (762 px); re-run with more
--stepsfor tighter start/end values. - No measurable inertia in the sampled series; Lenis damping on real wheel input was not measured.
- Mechanism and numbers only — none of the site's code, copy, images or brand was extracted.
Connects securely to your tools. The creator never sees your data.
About this skill
Your client sends a link: "we want it to feel like this." scroll-forensics tells you exactly how that feel was built — with numbers, not guesses.
The skill opens the live page in a headless browser, instruments it before load, sweeps the scroll and samples every animated property. It then fits the motion against a catalogue of cubic-bezier curves and returns a structured report:
- Detected stack — GSAP ScrollTrigger, Lenis, Locomotive, Framer Motion or pure CSS, with confidence and evidence
- Measured numbers — active scroll range, parallax factor, easing curve with fit error, linearity (R²), lerp/damping, pin duration in viewports, IntersectionObserver threshold and rootMargin
- Mechanics per section — technique, trigger, animated properties
- Details that make it feel premium — the concrete numbers a naive rebuild gets wrong
- Cost and accessibility — fps under scroll, prefers-reduced-motion, mobile (390×844) behaviour
- Reimplementation plan — DOM structure, starting parameters, build order and pitfalls, written from scratch with your own class names
It avoids the two traps that make most "how is this built" answers wrong: time-based transitions mistaken for scrub, and the 1:1 movement that is just the page scrolling.
Ethical by design: it extracts mechanism and parameters, never the page's code, copy, images or brand. It checks robots.txt, never gets around logins, paywalls, captchas or anti-bot protection, and stops cleanly when blocked.
Requirements: Node + Playwright (Chromium) for the full measured report; Python 3.9+ (standard library only) for curve fitting. Without a shell it falls back to a clearly labelled static analysis.
Works with: Claude Code, Codex CLI.
How to use
Skills on Agensi run inside your AI agent. Copy the prompt, paste it into your agent, and it connects to Agensi and installs this skill for you. If a payment is needed, your agent shows it to you first.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill passes our trust checks below.
Security scanned
Passed our 8-point scan before listing
Fresh listing
Recently published to Agensi
Money-back guarantee
Doesn't do what its page promises? You get your money back.
Trust & safety
Security scanned
Verified clean 6 days ago
- Passed all security checks, Safe to install
Requires