Mesh跟随鼠标功能在滚动时失效问题求助
问题分析与解决方案
问题根源
你当前的鼠标位置映射逻辑只基于静态视口尺寸,完全没考虑相机沿Y轴滚动时的3D空间位移。state.mouse.y的取值范围是[-1, 1],对应视口的顶部到底部,但当相机移动后,视口底部对应的3D世界Y坐标已经改变,直接用state.viewport.height计算targetY会打破鼠标位置和3D空间的映射关系,最终导致mesh在视口底部失效跳回顶部。
修复代码
改用屏幕坐标转世界坐标的方式,通过Three.js的Vector3.unproject()方法,把鼠标的屏幕位置转换成3D世界中的目标位置,这样无论相机怎么移动,都能正确匹配鼠标与mesh的位置关系:
export const Example = () => { const ref = useRef(); useFrame((state) => { // 创建基于鼠标位置的屏幕向量,z值控制深度(0=近平面,1=远平面,可按需调整) const mouseVector = new state.Three.Vector3( state.mouse.x, state.mouse.y, 0.5 ); // 将屏幕向量转换为世界坐标 mouseVector.unproject(state.camera); // 提取目标位置 const targetX = mouseVector.x; const targetY = mouseVector.y; // 平滑过渡到目标位置 ref.current.position.x += (targetX - ref.current.position.x) * 0.2; ref.current.position.y += (targetY - ref.current.position.y) * 0.2; }); return ( <mesh ref={ref}> <sphereGeometry /> <meshNormalMaterial /> </mesh> ); };
可选优化
如果需要让mesh保持固定的Z轴深度(不随鼠标深度变化),可以在转换后锁定Z坐标:
// 转换后固定Z轴位置 mouseVector.unproject(state.camera); const targetX = mouseVector.x; const targetY = mouseVector.y; const fixedZ = ref.current.position.z; // 保留mesh原有Z位置 ref.current.position.x += (targetX - ref.current.position.x) * 0.2; ref.current.position.y += (targetY - ref.current.position.y) * 0.2; ref.current.position.z = fixedZ;
修改后,无论相机如何沿Y轴滚动,mesh都会准确跟随鼠标的3D空间位置,不会再出现跳变问题。
内容的提问来源于stack exchange,提问作者Lazarusss
相关产品推荐
相关产品推荐

