使用React setState实现视差效果:滚动时图片左右移动问题求助
问题核心原因
- 你现在用布尔状态控制固定的margin数值,没法实现随滚动距离实时变化的平滑视差效果,同时加的2s过渡动画会导致偏移更新和滚动不同步,看起来就像图片不跟着动
- 只写了0300px滚动区间的逻辑,没有补充300600px区间的右移动计算
修改方案
不用布尔值控制开关,直接存储滚动的垂直偏移量,分区间动态计算图片和文本的位置,修改后的完整代码如下:
import { useState, useEffect } from 'react'; export default function App() { // 直接存储滚动垂直偏移量 const [scrollY, setScrollY] = useState(0); useEffect(() => { const handleScroll = () => { setScrollY(window.scrollY); }; window.addEventListener('scroll', handleScroll); // 组件卸载时移除监听,避免内存泄漏 return () => window.removeEventListener('scroll', handleScroll); }, []); // 分区间计算图片偏移 const getImageStyle = () => { // 以下系数都可以根据你想要的移动速度自行调整 if (scrollY <= 300) { // 0~300px滚动区间:左移+下移,匹配你已有的效果 return { marginRight: `${scrollY * 1}px`, marginTop: `${scrollY * 1}px`, transition: 'none' // 实时滚动不需要过渡,避免卡顿滞后 } } else if (scrollY <= 600) { // 300~600px滚动区间:从左向右移动 const offset = scrollY - 300; return { marginRight: `${300 - offset * 2}px`, // 系数越大右移速度越快 marginTop: `${300 + offset * 0.5}px`, transition: 'none' } } else { // 滚动超过600px后的状态,可按需求自行修改 return { marginRight: '-300px', marginTop: '450px', transition: 'none' } } } // 计算文本偏移 const getTextStyle = () => { if (scrollY <= 300) { return { marginTop: `${800 - scrollY * 1.67}px`, transition: 'none', marginLeft: '120px' } } else { return { marginTop: '300px', transition: 'none', marginLeft: '120px' } } } return ( <div className="background"> <div style={{ backgroundColor: "#0E2043", padding: "50px", height: "1000px", display: "flex", justifyContent: "center" }} > <div className="header">Vanuatu</div> <img className="image" style={getImageStyle()} alt="random" src="https://cdn.britannica.com/87/122087-050-1C269E8D/Cover-passport.jpg" /> <div className="text" style={getTextStyle()} > Minimum Investment </div> </div> </div> ) }
优化建议
如果想要更好的性能,可以用transform: translate()代替margin修改位置,浏览器对transform的动画渲染性能更高,不会触发页面重排。如果滚动监听触发太频繁,也可以加节流函数限制触发频率,减少不必要的状态更新。
内容的提问来源于stack exchange,提问作者JJM50
相关产品推荐
相关产品推荐

