three.js项目的代码结构规划相关的问题

目前我的threeJS项目的代码结构大概如下:

  1. index.html,其中只导入main.js。
  2. 各个种类模型的单独js文件,比如所有房间的模型room.js,调整好参数后export出来,然后在main.js中引入。
  3. main.js:包括camera,renderer,scence基础三大件,并导入第2项中所有的子js文件。

说明:这么规划的原因是如果所有的代码都写在同一个main.js中,会达到好几千行,非常难维护。

遇到的问题:

  1. 在threeJS项目中,实现单独模型的点击事件需要camera的支持,但camera只存在于main.js中。因为各个种类模型的js文件是整体引入到main.js中的,目前的代码结构只能实现某个种类所有模型的点击事件,比如房间的模型room有10个,点击事件只能监听到所有房间,无法监听到某个房间。
  2. 在模型很多的threeJS项目中,代码的结构应该怎么规划比较好,全在一起可以实现单独模型的点击事件,但代码过于庞大。像我这样分开写,点击事件就实现不了了。
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

本 答案 引用自 chatGPT:
1.将单独模型的点击事件绑定到各个种类模型的js文件中,而不是在main.js中统一处理。这样可以实现单独模型的点击事件,同时也可以保持代码结构的清晰。

2.可以在各个种类模型的js文件中,将需要camera支持的代码单独提取出来,然后在main.js中将camera作为参数传入。这样可以实现单独模型的点击事件,并且保持代码结构的清晰。

3.可以使用事件委托的方式,在main.js中统一处理所有模型的点击事件。这样可以避免在各个种类模型的js文件中处理事件,也可以实现单独模型的点击事件。具体实现方式是,在各个种类模型的js文件中,为每个模型添加一个唯一的id,然后在main.js中监听click事件,根据点击的元素的id,判断点击的是哪个模型。这种方式需要在main.js中处理所有点击事件,代码量可能会比较大,但可以保持代码结构的清晰。

以下是针对方案2的代码示例:
房间模型room.js:

import * as THREE from 'three';
function createRoom(camera) {
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
  const room = new THREE.Mesh(geometry, material);
  // 给房间模型添加点击事件
  room.addEventListener('click', function() {
    console.log('Clicked on room!');
    // 这里可以使用camera进行操作
  });
  return room;
}
export { createRoom };

main.js:

import * as THREE from 'three';
function createRoom(camera) {
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
  const room = new THREE.Mesh(geometry, material);
  // 给房间模型添加点击事件
  room.addEventListener('click', function() {
    console.log('Clicked on room!');
    // 这里可以使用camera进行操作
  });
  return room;
}
export { createRoom };

在上面的代码中,我们将camera作为参数传入createRoom函数中,然后在createRoom函数中绑定了房间模型的点击事件。这样就可以实现单独模型的点击事件,并且保持代码结构的清晰。