mcpField
T
threejs-interaction

threejs-interaction

github.com/akillness开发5354 次安装今天更新
代码仓库

关于 threejs-interaction

面向实现 3D 输入、对象拾取、相机控制和选择状态的 Three.js 开发者技能。重点包括基于画布计算坐标、明确可拾取目标,以及可靠清理交互状态。

主要功能

  1. 01对鼠标指针或触摸输入进行射线检测
  2. 02配置相机与对象控制
  3. 03转换指针在不同空间中的坐标
  4. 04管理悬停与选择状态
  5. 05限制射线检测频率并移除监听器

适用场景

  1. 01通过指针或触摸选择场景对象
  2. 02修复偏移或缩放画布上的拾取失败
  3. 03添加环绕、拖动或变换交互
  4. 04清除过期的悬停和指针状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/akillness/jeo-skills --skill threejs-interaction

安装后在 Claude Code 中输入/threejs-interaction确认已加载。

附带文件SKILL.toonevals/evals.json

详细介绍

Three.js 交互

在需要直接 3D 输入、对象拾取、相机操作和选择状态时使用此技能。语义化 HTML 控件、键盘无障碍支持和焦点管理请交由 web-accessibility 处理;游戏输入架构请交由 web-game-development 处理。

何时使用此技能

  • 对可选场景对象进行指针/触摸射线检测
  • 添加或修复相机控制、对象拖动、变换手柄或指针锁定
  • 在客户端、标准化设备、世界和屏幕坐标之间转换坐标
  • 修复点击未命中、悬停状态过期、指针捕获问题或射线检测过于频繁

指令

第 1 步:定义交互边界
  1. 确定画布元素及其 getBoundingClientRect();当画布偏移或调整大小时,绝不能基于整个窗口对指针坐标进行标准化。
  2. 明确指定可拾取集合或图层。对 scene.children 进行射线检测但不设边界,会意外命中目标,并随着场景变大增加开销。
  3. 将输入事件与视觉状态变化分开,以便独立测试和清除悬停/选择状态。
第 2 步:从实际画布发出射线
const pointer = new THREE.Vector2();
const raycaster = new THREE.Raycaster();

function pick(event) {
  const rect = renderer.domElement.getBoundingClientRect();
  pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
  pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

  raycaster.setFromCamera(pointer, camera);
  return raycaster.intersectObjects(pickables, true)[0] ?? null;
}

将嵌套命中结果解析到具有语义的可选根对象,而不要把每个子网格都作为单独的产品级目标。对画布尺寸为零的情况进行防护,并忽略画布边界以外的事件。

第 3 步:审慎选择控件和输入行为
要求适用工具
绕目标旋转OrbitControls
第一人称浏览器视角PointerLockControls
地图/平移约束MapControls
操作对象的变换TransformControls
拖动已知对象DragControls 或显式射线平面逻辑
无障碍命令/UI 操作DOM 控件以及 web-accessibility

从已安装的 Three.js 附加组件路径导入控件,并在画布/场景卸载时释放它们。不要在多个渲染循环中更新控件。

第 4 步:限制工作量并清理状态

仅在交互需要悬停时,才在指针移动时进行射线检测。对于大型场景,在考虑更复杂的加速结构之前,先使用图层、边界、宽阶段过滤或目标列表。在 pointerleave、捕获丢失、对象移除和场景拆除时清除悬停状态。

第 5 步:验证输入行为
  • 测试鼠标、触摸、键盘替代操作,以及调整大小/偏移后的画布。
  • 测试空白处点击、嵌套网格、被遮挡的对象,以及快速进入/离开事件。
  • 确认拆除时控件会释放事件监听器,并清除指针锁定/拖动状态。
  • 验证每个必须支持无指针操作的动作都具备焦点可见的 DOM 交互提示。

示例

悬停时不破坏材质

在映射表中保存每个可选对象的基准视觉状态。悬停对象变化时,先恢复旧选中对象,再应用新的高亮效果。仅当需要高亮单个网格时,避免修改共享材质颜色;应克隆材质或使用受支持的单对象信号。

将对象放置在地面上

构造一个 THREE.Plane,从指针发出射线,并使用 ray.intersectPlane。与根据屏幕坐标猜测深度相比,这种方法更可预测,且适用于任何相机。

最佳实践

  1. 根据画布矩形而不是 window.innerWidth 和 innerHeight 对坐标进行标准化。
  2. 明确指定具有语义的拾取目标,并将子对象交点解析到根对象。
  3. 拖动交互应使用指针事件和指针捕获,而不是分别实现鼠标和触摸逻辑。
  4. 按照场景生命周期释放控件并移除自定义监听器。
  5. 不要将射线检测作为触发必要产品操作的唯一方式。

参考资料

评论

支持 Markdown