You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

集成react locomotive scroll与framer-motion滚动触发动画时出现闪烁及双滚动条问题

解决方案:react-locomotive-scroll 双滚动条+底部闪烁问题

一、先解决双滚动条冲突

  • 全局禁用原生滚动条,在全局样式文件中添加:
    html, body {
      overflow: hidden;
      margin: 0;
      padding: 0;
    }
    
  • 初始化react-locomotive-scroll时,确保滚动容器高度占满视口,避免原生滚动区域残留:
    import { LocomotiveScrollProvider } from 'react-locomotive-scroll';
    
    function App() {
      return (
        <LocomotiveScrollProvider
          options={{
            smooth: true,
            scrollbar: true,
          }}
          watch={[]}
        >
          <div data-scroll-container style={{ height: '100vh', overflow: 'hidden' }}>
            {/* 页面内容 */}
          </div>
        </LocomotiveScrollProvider>
      );
    }
    

二、修复底部闪烁问题

  • 同步framer-motion与locomotive-scroll的滚动上下文:
    locomotive-scroll是模拟滚动,framer-motion默认监听原生滚动事件,需将滚动目标指向locomotive的容器:
    import { useScroll, useTransform } from 'framer-motion';
    import { useLocomotiveScroll } from 'react-locomotive-scroll';
    
    function AnimatedSection() {
      const { scroll } = useLocomotiveScroll();
      const { scrollYProgress } = useScroll({
        target: scroll?.el, // 绑定locomotive滚动容器
        offset: ["start start", "end end"]
      });
      const opacity = useTransform(scrollYProgress, [0, 1], [0, 1]);
    
      return <section style={{ opacity }}>...</section>;
    }
    
  • 调整平滑滚动参数:
    降低缓动系数减少滚动帧不同步,缓解闪烁:
    <LocomotiveScrollProvider
      options={{
        smooth: true,
        lerp: 0.05, // 默认0.1,调小降低滚动延迟
        scrollbar: true,
      }}
    >
      {/* ... */}
    </LocomotiveScrollProvider>
    
  • 修正容器高度计算:
    动态内容(如图片)加载后会改变页面高度,需刷新locomotive的滚动计算:
    const { scroll } = useLocomotiveScroll();
    
    useEffect(() => {
      const handleImageLoad = () => scroll?.update();
      const images = document.querySelectorAll('img');
      images.forEach(img => img.addEventListener('load', handleImageLoad));
      return () => images.forEach(img => img.removeEventListener('load', handleImageLoad));
    }, [scroll]);
    

三、替代思路

  • 直接使用原生locomotive-scroll:
    放弃封装库,手动初始化销毁,规避封装带来的兼容问题:
    import LocomotiveScroll from 'locomotive-scroll';
    import { useEffect, useRef } from 'react';
    
    function App() {
      const containerRef = useRef(null);
      const scrollRef = useRef(null);
    
      useEffect(() => {
        if (containerRef.current) {
          scrollRef.current = new LocomotiveScroll({
            el: containerRef.current,
            smooth: true,
            scrollbar: true,
          });
        }
        return () => scrollRef.current?.destroy();
      }, []);
    
      return (
        <div ref={containerRef} data-scroll-container style={{ height: '100vh', overflow: 'hidden' }}>
          {/* 页面内容 */}
        </div>
      );
    }
    
  • 自定义滚动触发动画逻辑:
    监听locomotive的滚动事件,手动控制framer-motion动画:
    import { useAnimation } from 'framer-motion';
    
    function AnimatedSection() {
      const controls = useAnimation();
      const { scroll } = useLocomotiveScroll();
    
      useEffect(() => {
        const handleScroll = ({ scrollY }) => {
          controls.start({ opacity: scrollY > 500 ? 1 : 0 });
        };
        scroll?.on('scroll', handleScroll);
        return () => scroll?.off('scroll', handleScroll);
      }, [scroll, controls]);
    
      return <section animate={controls} initial={{ opacity: 0 }}>...</section>;
    }
    

内容的提问来源于stack exchange,提问作者user17443811

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:40:37