More screenshots

    Works with the AI Agents you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseDotsDots+22 more

    Scroll Forensics — Reverse-Engineer Scroll Animations

    1

    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

    Secure checkout via Stripe

    Money-back guarantee

    Converts to your local currency at checkout

    Security scanned
    Scroll Forensics — Reverse-Engineer Scroll Animations

    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

    LayerTechnologyConfidenceEvidence
    Smooth scrollLenisHigh.lenis class on <html>
    RenderingThree.js / WebGLMedium1 canvas with a WebGL context
    PinningCSS stickyHighcomputed position: sticky on the stage
    Timeline libraryGSAPNot foundno 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: translateX 0 → −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

    ElementPropertyStart → end (scroll px)From → toFactorEasingR²
    horizontal tracktranslateX3,809 → 12,1870 → −5,040 px0.60linear0.996
    fixed background layertop0 → 15,996−539.8 → −899.6 px0.0225quart.out0.690
    sticky section headingtop0 → 19,8041,220 → −16,143 px0.88linear0.990

    1 series discarded as plain 1:1 page movement (no effect of its own).

    Instrumented before load

    • 23 IntersectionObservers: rootMargin 200px / threshold 0 and 0px / 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. translate3d stays 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 reduce on
    • 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 --steps for 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

    playwright
    Node.js
    Python

    Listed6 days ago
    Updated4 days ago

    What's inside

    Frequently Asked Questions