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

使用PointerLockControls时如何启用鼠标点击与光标显示?

解决PointerLockControls下Three.js艺术品点击无响应的问题

问题原因

Three.js的Mesh并非DOM元素,无法直接通过addEventListener('click')绑定点击事件;加上PointerLockControls锁定鼠标后,原生鼠标事件不会关联到3D对象,必须通过**射线检测(Raycaster)**判断点击是否命中目标模型。

解决方案

通过射线检测实现3D对象的点击交互,具体步骤如下:

  1. 初始化射线检测工具与鼠标坐标向量
  2. 监听鼠标点击事件,点击时计算射线与场景对象的交点
  3. 命中艺术品时触发弹窗逻辑

修改后的完整代码

// 初始化射线检测工具和鼠标向量
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

let art2Texture = new THREE.TextureLoader().load('img/art/2.png');
        
const art2Geometry = new THREE.PlaneBufferGeometry(8, 8);
const art2Material = new THREE.MeshBasicMaterial({
    map: art2Texture
});
        
const art2 = new THREE.Mesh(art2Geometry, art2Material);
        
art2.position.z = -49.9;
art2.position.y = 3.5;
        
art2.userData = {
  name: 'Artwork 2',
  description: 'This is the description of Artwork 2',
  link: 'https://here-goes-the-link',
};

// 监听鼠标点击事件(绑定到document,适配PointerLockControls的鼠标锁定状态)
document.addEventListener('click', (event) => {
  // 将屏幕鼠标坐标转换为Three.js标准化设备坐标
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  // 更新射线的起点与方向(基于相机视角)
  raycaster.setFromCamera(mouse, camera);

  // 检测射线与场景中所有对象的交点
  const intersects = raycaster.intersectObjects(scene.children);

  // 遍历交点,判断是否命中目标艺术品
  for (let i = 0; i < intersects.length; i++) {
    const hitObject = intersects[i].object;
    if (hitObject.userData.name === 'Artwork 2') {
      console.log('Artwork 2 clicked!');
      const popup = document.createElement('div');
      popup.className = 'popup';

      const title = document.createElement('h2');
      title.textContent = hitObject.userData.name;

      const description = document.createElement('p');
      description.textContent = hitObject.userData.description;

      const link = document.createElement('a');
      link.href = hitObject.userData.link;
      link.target = '_blank';
      link.textContent = 'View on OpenSea';

      popup.appendChild(title);
      popup.appendChild(description);
      popup.appendChild(link);

      document.body.appendChild(popup);
      break; // 找到第一个命中对象后停止遍历
    }
  }
});

// CSS for the pop-up
const popupCSS = `
.popup {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  border: 2px solid black;
  padding: 16px;
  width: 300px;
  text-align: center;
  z-index: 1;
}

.popup h2 {
  margin-top: 0;
}

.popup a {
  display: block;
  margin-top: 16px;
}
`;

const popupStyle = document.createElement('style');
popupStyle.textContent = popupCSS;

document.head.appendChild(popupStyle);
scene.add(art2);

关键说明

  • Raycaster通过相机视角与鼠标坐标生成射线,精准检测场景中与射线相交的3D对象
  • 鼠标坐标需转换为标准化设备坐标(范围[-1,1]),才能匹配Three.js的坐标系逻辑
  • 点击事件绑定到document,适配PointerLockControls锁定鼠标后的事件触发规则
  • 可通过userData自定义属性批量标识艺术品,方便后续扩展多个艺术品的点击交互

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:47:51