fanLocalDual.threejs.base.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. import * as THREE from 'three';
  2. // import { setModalCenter } from '/@/utils/threejs/util';
  3. import Smoke from '../../comment/threejs/Smoke';
  4. import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer';
  5. // import * as dat from 'dat.gui';
  6. // const gui = new dat.GUI();
  7. // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
  8. class ModelContext {
  9. model;
  10. // modelName = 'jbfj-hd';
  11. modelName = 'jbfj-dual';
  12. /** 本模型的根3D对象 */
  13. group?: THREE.Object3D;
  14. /** 本模型所包含的所有元素合集 */
  15. private elements: unknown[] = [];
  16. /** 本模型支持的 Object3DGroup 模块 */
  17. private modules: {
  18. /** 模块名称 */
  19. name: string;
  20. /** 控制该模块所用的上下文 */
  21. context: THREE.Object3D;
  22. /** 控制时行为声明 */
  23. behavior: (context: THREE.Object3D) => void;
  24. }[] = [];
  25. constructor(model) {
  26. this.model = model;
  27. }
  28. addLight() {
  29. // optional implementation
  30. }
  31. /** 设置模型类型并切换,不同的类型通常对应不同的具体模型,在模型总控制器下的具体模型会根据传入的参数彼此交互、切换 */
  32. setModelType(modelType: string) {
  33. this.modules.forEach(({ name, context, behavior }) => {
  34. if (name === modelType) {
  35. behavior(context);
  36. }
  37. });
  38. }
  39. /** 初始化css元素,将css元素选择器传入,该方法会将这些元素按顺序放入传入的锚点中 */
  40. initCssElement() {
  41. // selectors.forEach((selector, index) => {
  42. // const element = document.querySelector(selector) as HTMLElement;
  43. // if (element) {
  44. // const css3D = new CSS3DSprite(element);
  45. // this.cssSprites.push(css3D);
  46. // css3D.name = selector;
  47. // css3D.scale.set(0.05, 0.05, 0.05);
  48. // // const ff = gui.addFolder(`css元素${index}`);
  49. // // ff.add(css3D.position, 'x', -100, 100);
  50. // // ff.add(css3D.position, 'y', -100, 100);
  51. // // ff.add(css3D.position, 'z', -100, 100);
  52. // if (index < anchors.length) {
  53. // const [x, y, z] = anchors[index];
  54. // css3D.position.set(x, y, z);
  55. // this.group?.add(css3D);
  56. // } else {
  57. // console.warn(`指定的元素${selector}没有合适的位置放置`);
  58. // }
  59. // }
  60. // });
  61. }
  62. mountedThree() {
  63. return new Promise((resolve) => {
  64. this.model.setGLTFModel([this.modelName]).then(async (gltf) => {
  65. this.group = gltf[0];
  66. if (this.group) {
  67. // setModalCenter(this.group);
  68. this.addLight();
  69. this.setModelPosition();
  70. this.initModules();
  71. this.startAnimation(this.elements);
  72. resolve(null);
  73. }
  74. });
  75. });
  76. }
  77. destroy() {
  78. if (!this.model) return;
  79. this.elements.forEach((element) => {
  80. this.model.clearGroup(element);
  81. });
  82. }
  83. // 设置模型位置
  84. setModelPosition() {
  85. if (!this.group) return;
  86. this.group.scale.set(0.6, 0.6, 0.6);
  87. // const ff = gui.addFolder(`位置调整`);
  88. // ff.add(this.group.position, 'x', -100, 100);
  89. // ff.add(this.group.position, 'y', -100, 100);
  90. // ff.add(this.group.position, 'z', -100, 100);
  91. this.group.position.set(0, 0, -60);
  92. this.group.rotation.y = Math.PI / 2;
  93. }
  94. // hideElements(eles: THREE.Object3D[]) {
  95. // eles.forEach((g) => {
  96. // g.visible = false;
  97. // });
  98. // }
  99. // showElements(eles: THREE.Object3D[]) {
  100. // eles.forEach((g) => {
  101. // g.visible = true;
  102. // });
  103. // }
  104. weakElements(eles: unknown[]) {
  105. eles.forEach((g) => {
  106. if (g instanceof Smoke) {
  107. g.opacityFactor = 0.4;
  108. }
  109. if (g instanceof CSS3DObject) {
  110. g.element.style.setProperty('opacity', '0.5');
  111. }
  112. });
  113. }
  114. strongElements(eles: unknown[]) {
  115. eles.forEach((g) => {
  116. if (g instanceof Smoke) {
  117. g.opacityFactor = 0.75;
  118. }
  119. if (g instanceof CSS3DObject) {
  120. g.element.style.setProperty('opacity', '1');
  121. }
  122. });
  123. }
  124. startAnimation(eles: unknown[]) {
  125. eles.forEach((g) => {
  126. if (g instanceof Smoke) {
  127. g.startSmoke();
  128. }
  129. });
  130. }
  131. stopAnimation(eles: unknown[]) {
  132. eles.forEach((g) => {
  133. if (g instanceof Smoke) {
  134. g.stopSmoke();
  135. }
  136. });
  137. }
  138. /** 核心方法,初始化本模型的各个模块,这些模块可以实现特定场景的展示、控制等功能 */
  139. initModules() {
  140. if (this.elements.length > 0) return;
  141. // 右侧风机-主风机进风
  142. const curveFan1Right = [
  143. {
  144. path0: new THREE.Vector3(-85.685, 4.208, 43.895),
  145. path1: new THREE.Vector3(-85.685, 2.208, 41.895),
  146. isSpread: true,
  147. spreadDirection: -1, // 1是由小变大,-1是由大变小
  148. },
  149. {
  150. path0: new THREE.Vector3(-85.685, 2.208, 41.895),
  151. path1: new THREE.Vector3(-85.685, 2.188, 35.327),
  152. isSpread: false,
  153. spreadDirection: 1,
  154. },
  155. {
  156. path0: new THREE.Vector3(-85.685, 2.188, 35.327),
  157. path1: new THREE.Vector3(-85.685, 0.784, 33.086),
  158. isSpread: false,
  159. spreadDirection: 1,
  160. },
  161. ];
  162. const group1 = new THREE.Group();
  163. const smoke1 = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.75, 0.5, 400);
  164. smoke1.setPath(curveFan1Right);
  165. this.elements.push(smoke1);
  166. smoke1.setPoints().then(() => {
  167. this.group?.add(smoke1.points);
  168. });
  169. // const element = document.getElementById('inputBox') as HTMLElement;
  170. // if (element) {
  171. // const fanLocalCSS3D = new CSS3DObject(element);
  172. // fanLocalCSS3D.name = 'text1';
  173. // fanLocalCSS3D.scale.set(0.04, 0.04, 0.04);
  174. // fanLocalCSS3D.rotation.y = -Math.PI / 2;
  175. // fanLocalCSS3D.position.set(-85.68, 5.97, -3.39);
  176. // group1.add(fanLocalCSS3D);
  177. // this.elements.push(fanLocalCSS3D);
  178. // }
  179. this.modules.push({
  180. name: 'state1',
  181. context: group1,
  182. behavior: () => {
  183. this.weakElements(this.elements);
  184. this.strongElements([smoke1]);
  185. },
  186. });
  187. }
  188. }
  189. export default ModelContext;