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

Vite项目中Framer-Motion useScroll组件动画失效问题排查

解决Framer Motion scrollYProgress始终为0导致组件透明度不更新的问题

你的问题核心是scrollYProgress的current值始终为0,导致motion.div的透明度无法变化。从代码和日志来看,问题集中在useScroll参数配置和滚动上下文识别上,以下是具体解决方案:


1. 修正offset参数配置

Framer Motion的offset定义了滚动进度的起始/结束触发条件,格式为[startTrigger, endTrigger],每个触发值是"元素位置 视口位置"(0=顶部,1=底部)。

你当前的offset: ["0 1", "1.33 1"]触发范围过窄,甚至可能元素初始状态就已超出结束范围,导致进度始终为0。建议修改为覆盖元素从进入到离开视口的完整周期:

const { scrollYProgress } = useScroll({
  target: ref,
  // 元素顶部进入视口底部时开始,元素底部离开视口顶部时结束
  offset: ["start end", "end start"], 
})

也可自定义触发范围,比如元素进入视口一半时开始,完全离开时结束:

offset: ["0.5 1", "1 0"]

2. 确认滚动容器上下文

如果滚动是基于父容器(比如content-projects设置了overflow-y: scroll),需给useScroll指定container参数,让它监听容器滚动而非全局窗口:

父组件Projects.jsx修改:

import React, { useRef } from 'react'
import './index.css'
import Project from './components/Project'
import projectsData from '../../../data/projectsData'

const Projects = () => {
  const containerRef = useRef(null)

  return (
      <section 
          className="content-projects"
          id='projects'
          ref={containerRef}
      >
          <h1>Projects</h1>
          {
              projectsData.map((project, index) => (
                  <Project
                      key={index}
                      {...project}
                      containerRef={containerRef}
                  />
              ))
          }
      </section>
  )
}

export default Projects

子组件Project.jsx修改:

const Project = ({ name, description, imageUrl, tech, link, containerRef }) => {
    const ref = useRef(null)
    const { scrollYProgress } = useScroll({
        target: ref,
        container: containerRef,
        offset: ["start end", "end start"],
    })
    // 其余代码不变
}

3. 用useTransform明确值映射(可选)

如果直接绑定scrollYProgress到透明度仍有问题,可通过useTransform明确将进度值映射到0-1的透明度范围:

import { motion, useScroll, useTransform } from 'framer-motion'

const Project = ({ ...props }) => {
    const ref = useRef(null)
    const { scrollYProgress } = useScroll({
        target: ref,
        offset: ["start end", "end start"],
    })
    // 将滚动进度0-1映射为透明度0-1
    const opacity = useTransform(scrollYProgress, [0, 1], [0, 1])

    return (
        <motion.div
            ref={ref}
            className='individual-project-container'
            style={{ opacity }}
        >
            {/* 其余代码不变 */}
        </motion.div>
    );
}

4. 验证元素高度与滚动范围

确保individual-project-container有足够高度,让滚动过程能触发offset的范围。可临时给元素添加背景色,观察它在视口中的滚动过程,确认offset触发时机是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:44:55