import * as THREE from 'three'; import { getTextCanvas, renderVideo } from '/@/utils/threejs/util'; import gsap from 'gsap'; class sdFc_4 { model; modelName = 'sdFc'; group: THREE.Object3D = new THREE.Object3D(); animationTimer; direction = 1; windowsActionArr = { frontWindow1: [], frontWindow2: [], backWindow1: [], backWindow2: [], }; constructor(model) { this.model = model; // this.group.name = 'ddFc'; } // // 重置摄像头 // const resetCamera = () => { // this.model.camera.position.set(30.328, 58.993, 148.315); // this.model.camera.rotation.set(-27.88, 14.35, 7.47); // this.model.orbitControls?.update(); // this.model.camera.updateProjectionMatrix(); // }; addLight = () => {}; // 设置模型位置 setModalPosition() { this.group?.scale.set(22, 22, 22); this.group?.position.set(-35, 25, 15); } addMonitorText(selectData) { if (!this.group) { return; } const screenDownText = VENT_PARAM['modalText'] ? VENT_PARAM['modalText'] : History_Type['type'] == 'remote' ? `国能神东煤炭集团监制` : '煤科通安(北京)智控科技有限公司研制'; const screenDownTextX = 125 - (screenDownText.length - 10) * 11; const textArr = [ { text: `远程定量调节自动风窗`, font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 120, y: 90, }, { text: `${selectData.OpenDegree1 ? '前窗开度值(°)' : selectData.frontArea ? '前窗过风面积(㎡)' : '前窗过风面积(㎡)'}:`, font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 5, y: 145, }, { text: selectData.OpenDegree1 ? Number(`${selectData.OpenDegree1}`).toFixed(2) : selectData.frontArea ? Number(`${selectData.frontArea}`).toFixed(2) : '-', font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 330, y: 145, }, { text: `${selectData.OpenDegree2 ? '后窗开度值(°)' : selectData.rearArea ? '后窗过风面积(㎡)' : '后窗过风面积(㎡)'}:`, font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 5, y: 200, }, { text: selectData.OpenDegree2 ? Number(`${selectData.OpenDegree2}`).toFixed(2) : selectData.rearArea ? Number(`${selectData.rearArea}`).toFixed(2) : '-', font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 330, y: 200, }, { text: `${selectData.frontRearDP ? '风窗压差(Pa)' : selectData.windSpeed ? '风速(m/s)' : '通信状态'}:`, font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 5, y: 256, }, { text: `${ selectData.frontRearDP ? selectData.frontRearDP : selectData.windSpeed ? selectData.windSpeed : selectData.netStatus == '0' ? '断开' : '连接' }`, font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 330, y: 256, }, { text: screenDownText, font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: screenDownTextX, y: 303, }, ]; getTextCanvas(726, 546, textArr, '').then((canvas: HTMLCanvasElement) => { const textMap = new THREE.CanvasTexture(canvas); // 关键一步 const textMaterial = new THREE.MeshBasicMaterial({ // 关于材质并未讲解 实操即可熟悉 这里是漫反射类似纸张的材质,对应的就有高光类似金属的材质. map: textMap, // 设置纹理贴图 transparent: true, side: THREE.DoubleSide, // 这里是双面渲染的意思 }); textMap.dispose(); textMaterial.blending = THREE.CustomBlending; const monitorPlane = this.group?.getObjectByName('monitorText'); if (monitorPlane) { monitorPlane.material = textMaterial; } else { const planeGeometry = new THREE.PlaneGeometry(726, 546); // 平面3维几何体PlaneGeometry const planeMesh = new THREE.Mesh(planeGeometry, textMaterial); planeMesh.name = 'monitorText'; planeMesh.scale.set(0.002, 0.002, 0.002); planeMesh.position.set(4.19, 0.448, -0.27); this.group?.add(planeMesh); } }); } /* 提取风门序列帧,初始化前后门动画 */ initAnimation() { const fcGroup = this.group?.getObjectByName('ShuangDaoTiaoJieFengChuang_1'); if (fcGroup) { const fontGroup = fcGroup.getObjectByName('FengChuang_1'); const backGroup = fcGroup.getObjectByName('FengChuang_2'); const JuanLian1 = fontGroup?.getObjectByName('JuanLian_1') as THREE.Mesh; JuanLian1.scale.set(1, -1, 1); JuanLian1.position.setY(0.9); const JuanLian2 = fontGroup?.getObjectByName('JuanLian_2') as THREE.Mesh; JuanLian2.scale.set(1, -1, 1); JuanLian2.position.setY(0.9); const JuanLian3 = backGroup?.getObjectByName('JuanLian_4') as THREE.Mesh; JuanLian3.scale.set(1, -1, 1); JuanLian3.position.setY(0.9); const JuanLian4 = backGroup?.getObjectByName('JuanLian_3') as THREE.Mesh; JuanLian4.scale.set(1, -1, 1); JuanLian4.position.setY(0.9); const meshArr01: THREE.Mesh[] = [JuanLian1]; const meshArr02: THREE.Mesh[] = [JuanLian2]; const meshArr03: THREE.Mesh[] = [JuanLian3]; const meshArr04: THREE.Mesh[] = [JuanLian4]; this.windowsActionArr.frontWindow1 = meshArr01; this.windowsActionArr.frontWindow2 = meshArr02; this.windowsActionArr.backWindow1 = meshArr04; this.windowsActionArr.backWindow2 = meshArr03; } } play(handlerState, rotationParam) { if ( this.windowsActionArr.frontWindow1 && this.windowsActionArr.frontWindow2 && this.windowsActionArr.backWindow1 && this.windowsActionArr.backWindow2 ) { switch (handlerState) { case 1: // 窗1开启动画 this.windowsActionArr.frontWindow1.forEach((mesh) => { gsap.to(mesh.scale, { y: -1 + rotationParam.scaleY, duration: 10 * Math.abs(-1 + rotationParam.scaleY - mesh.scale.y), overwrite: true, }); }); break; case 2: // 窗2开启动画 this.windowsActionArr.frontWindow2.forEach((mesh) => { gsap.to(mesh.scale, { y: -1 + rotationParam.scaleY, duration: 10 * Math.abs(-1 + rotationParam.scaleY - mesh.scale.y), overwrite: true, }); }); break; case 3: // 窗3开启动画 this.windowsActionArr.backWindow1.forEach((mesh) => { gsap.to(mesh.scale, { y: -1 + rotationParam.scaleY, duration: 10 * Math.abs(-1 + rotationParam.scaleY - mesh.scale.y), overwrite: true, }); }); break; case 4: // 窗4开启动画 this.windowsActionArr.backWindow2.forEach((mesh) => { gsap.to(mesh.scale, { y: -1 + rotationParam.scaleY, duration: 10 * Math.abs(-1 + rotationParam.scaleY - mesh.scale.y), overwrite: true, }); }); break; default: } } } /* 点击风窗,风窗全屏 */ mousedownModel(intersects: THREE.Intersection>[]) { if (this.animationTimer) { clearTimeout(this.animationTimer); this.animationTimer = null; } // 判断是否点击到视频 intersects.find((intersect) => { const mesh = intersect.object; return false; }); } mouseUpModel() {} /* 风门动画 */ render() { if (!this.model) { return; } if (this.fontMixers1 && this.frontClock1.running) { this.fontMixers1.update(2); } } mountedThree() { return new Promise((resolve) => { this.model.setGLTFModel('sdFc-jz').then((gltf) => { // this.group?.add(gltf[0]); this.group = gltf[0]; this.group.name = 'sdFc'; this.setModalPosition(); this.initAnimation(); this.addLight(); resolve(null); }); }); } destroy() { this.model.clearGroup(this.group); this.windowsActionArr.frontWindow = undefined; this.model = null; this.group = null; } } export default sdFc_4;