import * as THREE from 'three'; import { getTextCanvas, renderVideo } from '/@/utils/threejs/util'; import gsap from 'gsap'; class doubleWindowYjl { model; modelName = 'sdFc'; group: THREE.Object3D = new THREE.Object3D(); animationTimer; isLRAnimation = true; direction = 1; windowsActionArr = { frontWindow: [], backWindow: [], }; playerStartClickTime1 = new Date().getTime(); playerStartClickTime2 = new Date().getTime(); mixers: THREE.AnimationMixer | undefined; // fmClock = new THREE.Clock(); clipActionArr = { frontDoor: null as unknown as THREE.AnimationAction, backDoor: null as unknown as THREE.AnimationAction, }; constructor(model) { this.model = model; // this.group.name = this.modelName; } // 设置模型位置 setModalPosition() { // this.group.getObjectByName(this.modelName)?.scale.set(9, 9, 9); // this.group?.scale.set(22, 22, 22); // this.group?.position.set(-15, 25, 15); } addMonitorText(selectData) { if (!this.group) { return; } const screenDownText = VENT_PARAM['modalText'] ? VENT_PARAM['modalText'] : History_Type['type'] == 'remote' ? `国能神东煤炭集团监制` : '煤炭科学技术研究院有限公司研制'; const screenDownTextX = 120 - (screenDownText.length - 10) * 6; const textArr = [ { text: `远程定量调节自动风窗`, font: 'normal 30px Arial', color: '#009900', strokeStyle: '#002200', x: 95, y: 97, }, { text: `${selectData.OpenDegree1 ? '前窗开度值(°)' : selectData.forntArea ? '前窗过风面积(㎡)' : '前窗过风面积(㎡)'}:`, font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: 5, y: 150, }, { text: selectData.OpenDegree1 ? Number(`${selectData.OpenDegree1}`).toFixed(2) : selectData.forntArea ? Number(`${selectData.forntArea}`).toFixed(2) : '-', font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: 330, y: 150, }, { text: `${selectData.OpenDegree2 ? '后窗开度值(°)' : selectData.forntArea ? '后窗过风面积(㎡)' : '后窗过风面积(㎡)'}:`, font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: 5, y: 210, }, { text: selectData.OpenDegree2 ? Number(`${selectData.OpenDegree2}`).toFixed(2) : selectData.rearArea ? Number(`${selectData.rearArea}`).toFixed(2) : '-', font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: 325, y: 210, }, { text: `${selectData.frontRearDP ? '风窗压差(Pa)' : selectData.windSpeed ? '风速(m/s)' : '通信状态'}:`, font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: 5, y: 266, }, { text: `${ selectData.frontRearDP ? selectData.frontRearDP : selectData.windSpeed ? selectData.windSpeed : selectData.netStatus == '0' ? '断开' : '连接' }`, font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: 330, y: 266, }, { text: screenDownText, font: 'normal 28px Arial', color: '#009900', strokeStyle: '#002200', x: screenDownTextX, y: 322, }, ]; getTextCanvas(570, 346, textArr, '').then((canvas: HTMLCanvasElement) => { const textMap = new THREE.CanvasTexture(canvas); // 关键一步 const textMaterial = new THREE.MeshBasicMaterial({ // 关于材质并未讲解 实操即可熟悉 这里是漫反射类似纸张的材质,对应的就有高光类似金属的材质. map: textMap, // 设置纹理贴图 transparent: true, side: THREE.DoubleSide, // 这里是双面渲染的意思 }); textMaterial.blending = THREE.CustomBlending; const monitorPlane = this.group?.getObjectByName('monitorText'); if (monitorPlane) { monitorPlane.material = textMaterial; } else { const planeGeometry = new THREE.PlaneGeometry(570, 346); // 平面3维几何体PlaneGeometry const planeMesh = new THREE.Mesh(planeGeometry, textMaterial); planeMesh.name = 'monitorText'; planeMesh.scale.set(0.0018, 0.0018, 0.0018); planeMesh.position.set(4.04, 0.178, -0.2); this.group?.add(planeMesh); } textMap.dispose(); }); } /* 风门动画 */ render() { if (!this.model) { return; } } /* 提取风门序列帧,初始化前后门动画 */ initAnimation() { const sdFcModal = this.group.getObjectByName('sdFc-yjl'); if (!sdFcModal) return; // 初始化窗的动画 const fengchuang1 = sdFcModal?.getObjectByName('FengChuang'); const fengchuang2 = sdFcModal?.getObjectByName('FengChuang1'); const meshArr01: THREE.Mesh[] = []; const meshArr02: THREE.Mesh[] = []; if (fengchuang1 && fengchuang2) { fengchuang1.getObjectByName('chuang')?.children.forEach((item: THREE.Object3D) => { item.children.forEach((obj: THREE.Mesh) => { if (obj.name && obj.name.startsWith('shanye')) { obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0); meshArr01.push(obj); } }); }); fengchuang2.getObjectByName('chuang001')?.children.forEach((item: THREE.Object3D) => { item.children.forEach((obj: THREE.Mesh) => { if (obj.name && obj.name.startsWith('d__FCshanye')) { obj.rotateOnAxis(new THREE.Vector3(0, 1, 0), 0); meshArr02.push(obj); } }); }); this.windowsActionArr.frontWindow = meshArr01; this.windowsActionArr.backWindow = meshArr02; } // // 初始化门的动画 // this.mixers = new THREE.AnimationMixer(sdFcModal); // const frontDoor = sdFcModal?.animations[0]; // const frontClipAction = this.mixers.clipAction(frontDoor, sdFcModal); // frontClipAction.clampWhenFinished = true; // frontClipAction.loop = THREE.LoopOnce; // this.clipActionArr.frontDoor = frontClipAction; // const backDoor = sdFcModal?.animations[1]; // const backClipAction = this.mixers.clipAction(backDoor, sdFcModal); // backClipAction.clampWhenFinished = true; // backClipAction.loop = THREE.LoopOnce; // this.clipActionArr.backDoor = backClipAction; } /* 点击风窗,风窗全屏 */ mousedownModel(intersects: THREE.Intersection>[]) { if (this.animationTimer) { clearTimeout(this.animationTimer); this.animationTimer = null; } // 判断是否点击到视频 intersects.find((intersect) => { const mesh = intersect.object; return false; }); } mouseUpModel() {} play(rotationParam, flag) { if (this.windowsActionArr.frontWindow.length <= 0 || this.windowsActionArr.backWindow.length <= 0) { return; } if (flag === 1) { // 前风窗动画 this.windowsActionArr.frontWindow.forEach((mesh) => { gsap.to(mesh.rotation, { y: THREE.MathUtils.degToRad(rotationParam.frontDeg1), duration: (1 / 9) * Math.abs(rotationParam.frontDeg1 - mesh.rotation.y), overwrite: true, }); }); } else if (flag === 2) { // 后风窗动画 this.windowsActionArr.backWindow.forEach((mesh) => { gsap.to(mesh.rotation, { y: THREE.MathUtils.degToRad(rotationParam.backDeg1), duration: (1 / 9) * Math.abs(rotationParam.backDeg1 - mesh.rotation.y), overwrite: true, }); }); } else if (flag === 0) { ([...this.windowsActionArr.frontWindow, ...this.windowsActionArr.backWindow] as THREE.Mesh[]).forEach((mesh) => { gsap.to(mesh.rotation, { y: 0, overwrite: true, }); }); } } // // 播放动画 // doorPlay(handlerState, timeScale = 0.01) { // if (this.clipActionArr.frontDoor && this.clipActionArr.backDoor) { // let handler = () => {}; // switch (handlerState) { // case 1: // 打开前门 // handler = () => { // this.clipActionArr.frontDoor.paused = true; // this.clipActionArr.frontDoor.reset(); // this.clipActionArr.frontDoor.time = 1.2; // this.clipActionArr.frontDoor.timeScale = timeScale; // // this.clipActionArr.frontDoor.clampWhenFinished = true; // this.clipActionArr.frontDoor.play(); // this.fmClock.start(); // }; // break; // case 2: // 关闭前门 // handler = () => { // this.clipActionArr.frontDoor.paused = true; // this.clipActionArr.frontDoor.reset(); // // this.clipActionArr.frontDoor.time = 3; // this.clipActionArr.frontDoor.timeScale = -timeScale; // // this.clipActionArr.frontDoor.clampWhenFinished = true; // this.clipActionArr.frontDoor.play(); // this.fmClock.start(); // }; // break; // case 3: // 打开后门 // handler = () => { // this.clipActionArr.backDoor.paused = true; // this.clipActionArr.backDoor.reset(); // this.clipActionArr.backDoor.time = 1.2; // this.clipActionArr.backDoor.timeScale = timeScale; // // this.clipActionArr.backDoor.clampWhenFinished = true; // this.clipActionArr.backDoor.play(); // this.fmClock.start(); // }; // break; // case 4: // 关闭后门 // handler = () => { // this.clipActionArr.backDoor.paused = true; // this.clipActionArr.backDoor.reset(); // this.clipActionArr.backDoor.time = 3; // this.clipActionArr.backDoor.timeScale = -timeScale; // // this.clipActionArr.backDoor.clampWhenFinished = true; // this.clipActionArr.backDoor.play(); // this.fmClock.start(); // }; // break; // // case 5: // 打开前后门 // // handler = () => { // // this.clipActionArr.backDoor.paused = true; // // this.clipActionArr.frontDoor.paused = true; // // this.clipActionArr.frontDoor.reset(); // // this.clipActionArr.frontDoor.time = 0; // // this.clipActionArr.frontDoor.timeScale = 0.01; // // this.clipActionArr.frontDoor.clampWhenFinished = true; // // this.clipActionArr.frontDoor.play(); // // this.clipActionArr.backDoor.reset(); // // this.clipActionArr.backDoor.time = 0; // // this.clipActionArr.backDoor.timeScale = 0.01; // // this.clipActionArr.backDoor.clampWhenFinished = true; // // this.clipActionArr.backDoor.play(); // // this.frontClock.start(); // // this.backClock.start(); // // }; // // break; // // case 6: // 关闭前后门 // // handler = () => { // // debugger; // // this.clipActionArr.backDoor.paused = true; // // this.clipActionArr.frontDoor.paused = true; // // this.clipActionArr.frontDoor.reset(); // // this.clipActionArr.frontDoor.time = 4; // // this.clipActionArr.frontDoor.timeScale = -0.01; // // this.clipActionArr.frontDoor.clampWhenFinished = true; // // this.clipActionArr.frontDoor.play(); // // this.clipActionArr.backDoor.reset(); // // this.clipActionArr.backDoor.time = 4; // // this.clipActionArr.backDoor.timeScale = -0.01; // // this.clipActionArr.backDoor.clampWhenFinished = true; // // this.clipActionArr.backDoor.play(); // // this.frontClock.start(); // // this.backClock.start(); // // }; // // break; // default: // } // handler(); // // model.clock.start(); // // const honglvdeng = group.getObjectByName('honglvdeng'); // // const material = honglvdeng.material; // // setTimeout(() => { // // if (handlerState === 2 || handlerState === 4 || handlerState === 6) { // // material.color = new THREE.Color(0x00ff00); // // } else { // // material.color = new THREE.Color(0xff0000); // // } // // }, 1000); // } // } mountedThree(playerDom) { return new Promise((resolve) => { this.model.setGLTFModel(['sdFc-yjl'], this.group).then(() => { console.log(this.group); this.setModalPosition(); this.initAnimation(); resolve(null); }); }); } destroy() { this.model.clearGroup(this.group); this.windowsActionArr.frontWindow = []; this.windowsActionArr.backWindow = []; this.model = null; this.group = null; } } export default doubleWindowYjl;