spray.three.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import * as THREE from 'three';
  2. import UseThree from '../../../../utils/threejs/useThree';
  3. import ModelContext from './spray.threejs.base';
  4. import { animateCamera } from '/@/utils/threejs/util';
  5. import useEvent from '../../../../utils/threejs/useEvent';
  6. /** 模型总控制器 */
  7. let model: UseThree;
  8. /** 当前展示的具体模型的 Object3D 对象 */
  9. let group: THREE.Object3D;
  10. /** 具体模型内容列表,包含此模型总控制器下的所有可用的具体模型内容 */
  11. const modelContextList: {
  12. /** 当前模型类型,在控制器下有多个具体模型时分辨它们 */
  13. type: string;
  14. /** 模型的具体内容,即负责模型导入、绘制的上下文对象,一个控制器可以新建多个 */
  15. context?: ModelContext;
  16. }[] = [];
  17. const { mouseDownFn } = useEvent();
  18. /** 分发鼠标事件到具体实现方法 */
  19. function dispatchMouseEvent(event) {
  20. if (event.button == 0 && model && group) {
  21. mouseDownFn(model, group, event, () => {});
  22. }
  23. }
  24. /** 初始化模型CSS展示框的鼠标事件,应该在模型总控制器初始化后调用 */
  25. function initEventListender() {
  26. if (!model) return;
  27. model.canvasContainer?.addEventListener('mousedown', (e) => dispatchMouseEvent(e));
  28. // model.orbitControls?.addEventListener('change', () => {});
  29. }
  30. /** 渲染并更新总模型 */
  31. // function render() {
  32. // if (model && model.isRender && model.renderer) {
  33. // // model.animationId = requestAnimationFrame(render);
  34. // model.css3dRender?.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
  35. // model.renderer.render(model.scene as THREE.Scene, model.camera as THREE.PerspectiveCamera);
  36. // model.stats?.update();
  37. // }
  38. // }
  39. /** 刷新(再渲染)总模型 */
  40. // export function refreshModal() {
  41. // render();
  42. // // modelContextList.forEach((item) => {
  43. // // if (item.context) {
  44. // // item.context.render();
  45. // // }
  46. // // });
  47. // }
  48. /** 设置模型类型并切换,不同的类型通常对应不同的具体模型,在模型总控制器下的具体模型会根据传入的参数彼此交互、切换 */
  49. export function setModelType(modelType: 'spray') {
  50. return new Promise((resolve, reject) => {
  51. if (!model) return reject('模型未初始化');
  52. modelContextList.forEach(({ type, context }) => {
  53. if (!context) return reject('模型未初始化');
  54. if (modelType === type) {
  55. group = context?.group as THREE.Object3D;
  56. setTimeout(async () => {
  57. if (!model.scene?.getObjectByName(group.name) && group) {
  58. model.scene?.add(group);
  59. }
  60. await animateCamera({ x: -693, y: 474, z: 398 }, { x: 0, y: 0, z: 0 }, context.cameraPostion, context.orbitTarget, model, 0.8);
  61. resolve(null);
  62. }, 400);
  63. }
  64. });
  65. });
  66. }
  67. /** 挂载模型控制器,sceneSelctor表示放置模型的元素选择器,cssSelectors表示放置类似详情框的元素选择器,其中第一项需要是根元素选择器 */
  68. export function mountedThree(sceneSelctor: string, cssSelectors: string[]) {
  69. return new Promise(async (resolve) => {
  70. const [rootSelector, ...selectors] = cssSelectors;
  71. model = new UseThree(sceneSelctor, rootSelector);
  72. model.setEnvMap('test1.hdr');
  73. /** @ts-ignore-next-line */
  74. model.renderer.toneMappingExposure = 1.0;
  75. const model1 = new ModelContext(model);
  76. await model1.mountedThree();
  77. model1.initCssElement(selectors);
  78. modelContextList.push({
  79. type: 'spray',
  80. context: model1,
  81. });
  82. initEventListender();
  83. model.animate();
  84. resolve(null);
  85. });
  86. }
  87. export const destroy = () => {
  88. if (!model) return;
  89. model.isRender = false;
  90. modelContextList.forEach((item) => {
  91. if (item.context) item.context.destroy();
  92. });
  93. model.destroy();
  94. };