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

React中Three.js平面Raycaster鼠标追踪滚动偏移问题咨询

问题:Three.js Raycaster 鼠标交互位置在页面滚动后错位

在React的useEffect中创建Three.js平面,通过Raycaster实现鼠标交互效果:全屏状态下功能正常,但页面滚动至半屏位置后,鼠标置于屏幕中间时,交互效果出现在平面半上方区域;鼠标位于平面底部、屏幕中间时,高亮的仍是屏幕中间对应的平面区域。

当前鼠标位置计算代码:

window.addEventListener('mousemove', (event) => {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
})

Raycaster调用代码:

requestAnimationFrame(animate)
renderer.render(scene, camera)
raycaster.setFromCamera(mouse, camera)

解决方案

问题根源:原代码使用window.innerHeight和event.clientY计算鼠标坐标,是基于整个浏览器视口的,但页面滚动后,Three.js渲染的Canvas元素顶部与视口顶部产生偏移,导致Y轴坐标映射错误。

修改鼠标坐标计算逻辑,基于Canvas元素的实时视口位置计算相对坐标:

window.addEventListener('mousemove', (event) => {
  const canvas = renderer.domElement;
  const rect = canvas.getBoundingClientRect();
  
  // 计算鼠标在Canvas内部的相对位置,再转换为Three.js需要的标准化设备坐标
  mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
  mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
});

关键说明

  • getBoundingClientRect()会返回Canvas元素在当前视口中的位置和尺寸(包含滚动偏移后的实时数据)
  • 通过event.clientX - rect.left得到鼠标在Canvas左侧的偏移距离,除以Canvas宽度后转换为0-1范围,再转为Three.js的标准化设备坐标(-1到1)
  • Y轴计算同理,注意Three.js的Y轴向上为正,所以需要取反

如果Canvas元素的尺寸会随窗口变化,还需监听resize事件,更新相机的aspect比例并重新计算投影矩阵:

window.addEventListener('resize', () => {
  const canvas = renderer.domElement;
  camera.aspect = canvas.clientWidth / canvas.clientHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(canvas.clientWidth, canvas.clientHeight);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:20:32