How to Handle Scroll-Driven Animations in Cloned Sites with ai-website-cloner-template

Scroll-driven animations in cloned sites require detecting the original's trigger mechanism—whether IntersectionObserver, scroll-snap, sticky positioning, CSS animation-timeline, or JavaScript libraries like Lenis—then capturing both initial and scrolled CSS states before implementing the exact interaction model in your React components.

The ai-website-cloner-template treats scroll-driven interactions as a first-class "interaction model" that must be systematically inspected and reproduced. When cloning modern websites that animate on scroll, you need to move beyond static screenshots and replicate the precise behavioral triggers that create the original's dynamic feel.

Detect the Scroll Interaction Model

Before writing any code, identify how the original site triggers scroll-driven animations. According to docs/research/INSPECTION_GUIDE.md, you must manually scroll the page (or use a headless browser) and observe visual changes that occur without user clicks.

Ask these specific questions to categorize the interaction:

  • IntersectionObserver: Do elements fade in or slide up when entering the viewport?
  • Scroll-snap: Does the page lock to specific sections (scroll-snap-type on containers)?
  • Sticky positioning: Do headers or sidebars become fixed after crossing a threshold (position: sticky)?
  • CSS animation-timeline: Are keyframes tied directly to scroll progress?
  • JavaScript scroll listeners: Does the site use custom libraries like Lenis or Locomotive Scroll?

These detection steps are encoded in the cloning workflows at .opencode/commands/clone-website.md and .windsurf/workflows/clone-website.md.

Capture Before and After Styles

Once you identify the trigger mechanism, record the computed CSS at two critical states. As documented in INSPECTION_GUIDE.md (lines 103-108), capture:

  1. Scroll position 0: The initial computed styles (getComputedStyle) before any scroll interaction
  2. Post-threshold: The styles after scrolling past the trigger point (e.g., 120px)

Store these values in your component specification as a JSON block under states: {initial: …, scrolled: …}. This data feeds directly into the builder agent that constructs your React components.

Implement the Trigger Mechanism

Match your implementation to the specific scroll-driven animation type detected in the original site:

IntersectionObserver: Create a useEffect hook in src/components/<YourComponent>.tsx that observes the target element and toggles a React state (isVisible). Apply scrolled CSS via className or inline style based on this state.

Scroll-snap: Add scroll-snap-type: y mandatory to the container and scroll-snap-align: start to child panels in src/app/globals.css. This requires no JavaScript.

Position: sticky: Apply position: sticky; top: 0 to headers or sidebars in component CSS or globals.css. Optionally add background or shadow changes when scrollY exceeds your threshold.

CSS animation-timeline: Use @keyframes with animation-timeline: scroll() in globals.css for modern browsers that support scroll-linked animations.

JavaScript scroll libraries: Install Lenis or Locomotive Scroll via npm, initialize the instance in src/app/layout.tsx inside a useEffect hook, and add the library's CSS class (e.g., .lenis) to your root element.

Configure Global Styles and Dependencies

Add all scroll-related keyframes, utility classes, and global behaviors to src/app/globals.css. If the original site uses smooth-scroll libraries, install them via npm (e.g., npm i lenis) and update package.json accordingly.

The README.md (lines 90-98) emphasizes noting any libraries that need installation to ensure the cloned behavior matches the original's fluid motion.

Verify Scroll-Driven Animation Accuracy

Run the development server (npm run dev) and manually scroll through the cloned page. Verify that headers, sticky sidebars, scroll-snap sections, parallax layers, and custom scroll-driven animations match the original both visually and behaviorally. Test on different viewport sizes to ensure responsive scroll behaviors remain consistent.

Summary

  • Identify the specific scroll interaction model (IntersectionObserver, scroll-snap, sticky, animation-timeline, or JS library) before implementation
  • Record both initial and post-scroll computed CSS values to capture the exact visual states
  • Implement the matching trigger mechanism in your React components using the appropriate Next.js 18/React 19 patterns
  • Configure global styles in src/app/globals.css and install required dependencies in package.json
  • Test the scrolling experience end-to-end to ensure behavioral fidelity with the original site

Frequently Asked Questions

How do I detect if a site uses IntersectionObserver versus JavaScript scroll listeners?

Open the browser DevTools, go to the Sources tab, and search for "IntersectionObserver" in the page's JavaScript files. If found, the site likely uses the native API for viewport detection. If you see references to "lenis," "locomotive," "scroll" event listeners with requestAnimationFrame, or custom scroll physics calculations, the site uses a JavaScript library or custom scroll handler instead.

Where should I initialize Lenis or Locomotive Scroll in a Next.js project?

Initialize smooth-scroll libraries in src/app/layout.tsx inside a useEffect hook with the "use client" directive. This ensures the library runs only in the browser and affects the entire application scope. Add the library's required CSS classes (like .lenis) to the html or body element in the same file or in src/app/globals.css.

Can I use CSS scroll-snap with JavaScript-based smooth scrolling libraries?

Yes, but you must configure them carefully. Set scroll-behavior: auto on the html element when using Lenis, as the library handles smooth scrolling via JavaScript rather than native CSS smooth scrolling. Apply scroll-snap-type to your container as usual, but test thoroughly since some libraries require specific configuration to respect snap points without conflicts.

What if the original site uses CSS animation-timeline which isn't supported in all browsers?

As implemented in ai-website-cloner-template, you should implement the animation-timeline for modern browsers as the primary method, but provide a fallback using IntersectionObserver for older browsers. Capture the scrolled state CSS values and apply them via React state when the observer triggers, ensuring cross-browser compatibility while maintaining the scroll-driven animation effect.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →