import * as THREE from 'three'; // import { setModalCenter } from '/@/utils/threejs/util'; import Smoke from '../../comment/threejs/Smoke'; import { CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer'; // import * as dat from 'dat.gui'; // const gui = new dat.GUI(); // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999'; class ModelContext { model; // modelName = 'jbfj-hd'; modelName = 'jbfj-dual'; /** 本模型的根3D对象 */ group?: THREE.Object3D; /** 本模型所包含的所有元素合集 */ private elements: unknown[] = []; /** 本模型支持的 Object3DGroup 模块 */ private modules: { /** 模块名称 */ name: string; /** 控制该模块所用的上下文 */ context: THREE.Object3D; /** 控制时行为声明 */ behavior: (context: THREE.Object3D) => void; }[] = []; constructor(model) { this.model = model; } addLight() { // optional implementation } /** 设置模型类型并切换,不同的类型通常对应不同的具体模型,在模型总控制器下的具体模型会根据传入的参数彼此交互、切换 */ setModelType(modelType: string) { this.modules.forEach(({ name, context, behavior }) => { if (name === modelType) { behavior(context); } }); } /** 初始化css元素,将css元素选择器传入,该方法会将这些元素按顺序放入传入的锚点中 */ initCssElement() { // selectors.forEach((selector, index) => { // const element = document.querySelector(selector) as HTMLElement; // if (element) { // const css3D = new CSS3DSprite(element); // this.cssSprites.push(css3D); // css3D.name = selector; // css3D.scale.set(0.05, 0.05, 0.05); // // const ff = gui.addFolder(`css元素${index}`); // // ff.add(css3D.position, 'x', -100, 100); // // ff.add(css3D.position, 'y', -100, 100); // // ff.add(css3D.position, 'z', -100, 100); // if (index < anchors.length) { // const [x, y, z] = anchors[index]; // css3D.position.set(x, y, z); // this.group?.add(css3D); // } else { // console.warn(`指定的元素${selector}没有合适的位置放置`); // } // } // }); } mountedThree() { return new Promise((resolve) => { this.model.setGLTFModel([this.modelName]).then(async (gltf) => { this.group = gltf[0]; if (this.group) { // setModalCenter(this.group); this.addLight(); this.setModelPosition(); this.initModules(); this.startAnimation(this.elements); resolve(null); } }); }); } destroy() { if (!this.model) return; this.elements.forEach((element) => { this.model.clearGroup(element); }); } // 设置模型位置 setModelPosition() { if (!this.group) return; this.group.scale.set(0.6, 0.6, 0.6); // const ff = gui.addFolder(`位置调整`); // ff.add(this.group.position, 'x', -100, 100); // ff.add(this.group.position, 'y', -100, 100); // ff.add(this.group.position, 'z', -100, 100); this.group.position.set(0, 0, -60); this.group.rotation.y = Math.PI / 2; } // hideElements(eles: THREE.Object3D[]) { // eles.forEach((g) => { // g.visible = false; // }); // } // showElements(eles: THREE.Object3D[]) { // eles.forEach((g) => { // g.visible = true; // }); // } weakElements(eles: unknown[]) { eles.forEach((g) => { if (g instanceof Smoke) { g.opacityFactor = 0.4; } if (g instanceof CSS3DObject) { g.element.style.setProperty('opacity', '0.5'); } }); } strongElements(eles: unknown[]) { eles.forEach((g) => { if (g instanceof Smoke) { g.opacityFactor = 0.75; } if (g instanceof CSS3DObject) { g.element.style.setProperty('opacity', '1'); } }); } startAnimation(eles: unknown[]) { eles.forEach((g) => { if (g instanceof Smoke) { g.startSmoke(); } }); } stopAnimation(eles: unknown[]) { eles.forEach((g) => { if (g instanceof Smoke) { g.stopSmoke(); } }); } /** 核心方法,初始化本模型的各个模块,这些模块可以实现特定场景的展示、控制等功能 */ initModules() { if (this.elements.length > 0) return; // 右侧风机-主风机进风 const curveFan1Right = [ { path0: new THREE.Vector3(-85.685, 4.208, 43.895), path1: new THREE.Vector3(-85.685, 2.208, 41.895), isSpread: true, spreadDirection: -1, // 1是由小变大,-1是由大变小 }, { path0: new THREE.Vector3(-85.685, 2.208, 41.895), path1: new THREE.Vector3(-85.685, 2.188, 35.327), isSpread: false, spreadDirection: 1, }, { path0: new THREE.Vector3(-85.685, 2.188, 35.327), path1: new THREE.Vector3(-85.685, 0.784, 33.086), isSpread: false, spreadDirection: 1, }, ]; const group1 = new THREE.Group(); const smoke1 = new Smoke('/model/img/texture-smoke.png', '#ffffff', 0, 0.75, 0.5, 400); smoke1.setPath(curveFan1Right); this.elements.push(smoke1); smoke1.setPoints().then(() => { this.group?.add(smoke1.points); }); // const element = document.getElementById('inputBox') as HTMLElement; // if (element) { // const fanLocalCSS3D = new CSS3DObject(element); // fanLocalCSS3D.name = 'text1'; // fanLocalCSS3D.scale.set(0.04, 0.04, 0.04); // fanLocalCSS3D.rotation.y = -Math.PI / 2; // fanLocalCSS3D.position.set(-85.68, 5.97, -3.39); // group1.add(fanLocalCSS3D); // this.elements.push(fanLocalCSS3D); // } this.modules.push({ name: 'state1', context: group1, behavior: () => { this.weakElements(this.elements); this.strongElements([smoke1]); }, }); } } export default ModelContext;