import * as THREE from 'three'; import { CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer'; import { setModalCenter } from '/@/utils/threejs/util'; // import { setModalCenter } from '/@/utils/threejs/util'; // 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 = 'spray-upper'; // modelName = 'spray-ts'; // modelName = 'dedust'; group: THREE.Object3D | null = null; /** 本模型内支持的锚点位置数组 */ anchors: [number, number, number][] = [ [1.5, 0.5, 1.6], // [0, 0, 0], // 右侧传感器 [1.3, 0.5, 1.6], // [-25.847, 8.783, 3.267], // [31.142, 8.783, 3.267], ]; /** 本模型显示的css详情元素数组 */ cssSprites: CSS3DSprite[] = []; /** 初始化时用到的摄像头位置参数,可以供外部访问或初始化时使用 */ cameraPostion = { x: 2.0063999826191625, y: 0.3963997081529602, z: 3.275298992446514, }; /** 初始化时用到的滑轨目标参数,可以供外部访问或初始化时使用,配合摄像头可以实现更精确的控制 */ orbitTarget = { x: 2.023679325280445, y: -0.1461634482645532, z: 0.04677126793423104, }; constructor(model) { this.model = model; } addLight() { const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2); directionalLight.position.set(6.3, 28, 20); this.group?.add(directionalLight); directionalLight.target = this.group as THREE.Object3D; const pointLight = new THREE.PointLight(0xffffff, 1, 1000); pointLight.position.set(45, 51, -4.1); pointLight.shadow.bias = 0.05; this.model.scene.add(pointLight); } /** 初始化css元素,将css元素选择器传入,该方法会将这些元素按顺序放入本模型支持的锚点中 */ initCssElement(selectors: string[]) { 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.002, 0.002, 0.002); // 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 < this.anchors.length) { const [x, y, z] = this.anchors[index]; css3D.position.set(x, y, z); this.group?.add(css3D); } else { console.warn(`指定的元素${selector}没有合适的位置放置`); } } }); } /** 清除css元素 */ clearCssElement() { this.cssSprites.forEach((sprite) => { this.group?.remove(sprite); }); this.cssSprites = []; } mountedThree() { return new Promise((resolve) => { this.model.setGLTFModel([this.modelName]).then(async (gltf) => { this.group = gltf[0]; if (this.group) { setModalCenter(this.group); resolve(null); // this.addLight(); } }); }); } destroy() { if (this.model) { this.model.clearGroup(this.group); this.model = null; this.group = null; } } } export default ModelContext;