Newer
Older
urbanLifeline_YanAn / src / views / oneMap / BIM / WangJiaPIng.vue
@zhangzhihui zhangzhihui 1 day ago 25 KB 视频接入
<template>
  <div id="WangJiaPIng" ref="threeDom">
    <div class="YuanDian" v-for="(item, i) in labelData" :key="item.id" :id="item.id" style="display: none">
      <div class="iconBox" v-show="item.show">
        <img src="@/assets/images/ljx.png" alt="" class="iconImg" />
        <div class="ydBox">
          <el-icon color="#fff" class="iconClose" @click="closeWindow(item)"><CircleClose /></el-icon>
          <div class="YuanDianText">{{ item.name }}</div>
          <div class="ydData" v-for="(val, k) in item.data" :key="k" v-show="val.data && item.type !== 'Camera'">
            <div class="leftData">{{ val.phy + ':' }}</div>
            <div class="rightData">{{ val.data + ' ' + val.unit }}</div>
          </div>
          <div class="ydData" v-show="item.type !== 'Camera'">
            <div class="leftData">{{ '检测时间:' }}</div>
            <div class="rightData">{{ item.dataTime }}</div>
          </div>
        </div>
      </div>
      <!-- <img class="YuanDianIcon" :src="item.icon" @mouseenter="item.show = true" @mouseleave="item.show = false" /> -->
      <img class="YuanDianIcon" :src="item.icon" @click="ydClick(item)" />
    </div>
  </div>
</template>

<script setup name="WangJiaPIng">
import { ref, reactive, toRefs, onMounted } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; //控制器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; // gltf加载器
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { Water } from 'three/examples/jsm/objects/Water.js';

import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
import gsap from 'gsap';
import { CSSRulePlugin } from 'gsap/CSSRulePlugin';
import bus from '@/bus';

import { pointGetDataList } from '@/api/system/tanchuang';

const AllData = reactive({});

const show = ref('');
const width = ref(null);
const height = ref(null);
const Camera = ref(null);
const Renderer = ref(null);
const Controls = ref(null);
const granaryArr = ref([]);
const LabelRenderer = ref(null);
const animationFrameId = ref(null);
let Twater = null;
const labelData = ref([
  {
    name: '静力水准仪',
    id: `YuanDian1`,
    type: 'noCamera', //  Camera
    position: {
      x: -0.5,
      y: 0,
      z: -0.5,
    },
    icon: '/Three/icon/jlszy_icon.png',
    data: [],
    show: false,
    pointCode: 'WL62zX5',
    dataTime: '',
    toP: {
      x: -2.6309215167693845,
      y: 4.332423113638442,
      z: 21.572960056289727,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 5.2676576739806205,
      y: 1.083337105388434,
      z: -19.44099716858533,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '静力水准仪',
    id: `YuanDian2`,
    type: 'noCamera',
    position: {
      x: -40,
      y: 0,
      z: -0.5,
    },
    icon: '/Three/icon/jlszy_icon.png',
    data: [],
    show: false,
    pointCode: 'qGxgnkX',
    dataTime: '',
    toP: {
      x: -58.221584999469584,
      y: 6.590211176632594,
      z: 9.665579736149148,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 1,
      y: 1,
      z: -20,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '应变计',
    id: `YuanDian3`,
    type: 'noCamera',
    position: {
      x: -37.5,
      y: 0,
      z: -0.2,
    },
    icon: '/Three/icon/ybj_icon.png',
    data: [],
    show: false,
    // dsZCOmK
    pointCode: 'dsZCOmK',
    dataTime: '',
    toP: {
      x: -51.3485606944383,
      y: 5.243577935608563,
      z: 8.991560624060426,
      duration: 3,
      ease: 'power4.out',
    },
    toC: { x: 1, y: 1, z: -20, duration: 3, ease: 'power4.out' },
  },
  {
    name: '应变计',
    id: `YuanDian4`,
    type: 'noCamera',
    position: {
      x: 37,
      y: 0,
      z: -0.2,
    },
    icon: '/Three/icon/ybj_icon.png',
    data: [],
    show: false,
    pointCode: 'yKBFH23',
    dataTime: '',
    toP: {
      x: 22.461896619811345,
      y: 4.9018705165338625,
      z: 11.610714039725684,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 46.94567624487662,
      y: 1.9550975524650114,
      z: -5.473227670824349,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '加速度计',
    id: `YuanDian5`,
    type: 'noCamera',
    position: {
      x: 0.5,
      y: 0,
      z: -0.5,
    },
    icon: '/Three/icon/jsdj_icon.png',
    data: [],
    show: false,
    pointCode: 'nS34TXN',
    dataTime: '',
    toP: {
      x: -2.6309215167693845,
      y: 4.332423113638442,
      z: 21.572960056289727,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 5.2676576739806205,
      y: 1.083337105388434,
      z: -19.44099716858533,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '加速度计',
    id: `YuanDian6`,
    type: 'noCamera',
    position: {
      x: -1.5,
      y: 0,
      z: -0.5,
    },
    icon: '/Three/icon/jsdj_icon.png',
    data: [],
    show: false,
    pointCode: 'a60toBt',
    dataTime: '',
    toP: {
      x: -2.6309215167693845,
      y: 4.332423113638442,
      z: 21.572960056289727,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 5.2676576739806205,
      y: 1.083337105388434,
      z: -19.44099716858533,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '风速风向仪',
    id: `YuanDian7`,
    type: 'noCamera',
    position: {
      x: -45.5,
      y: 2.5,
      z: -0.2,
    },
    icon: '/Three/icon/fsfx_icon.png',
    data: [],
    show: false,
    pointCode: 'W5gfQor',
    dataTime: '',
    toP: {
      x: -58.221584999469584,
      y: 6.590211176632594,
      z: 9.665579736149148,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 1,
      y: 1,
      z: -20,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '裂缝计',
    id: `YuanDian8`,
    type: 'noCamera',
    position: {
      x: -43.5,
      y: -0.3,
      z: 2,
    },
    icon: '/Three/icon/lfj_mx.png',
    data: [],
    show: false,
    pointCode: 'tbd1HZw',
    dataTime: '',
    toP: {
      x: -57.02391699702596,
      y: 4.679545725497521,
      z: 12.416539848914276,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: 2.197668002974112,
      y: -0.9106652745024885,
      z: -17.24904015108576,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '彩虹桥延安中学方向摄像机',
    id: `YuanDian9`,
    type: 'Camera',
    position: {
      x: -50.5,
      y: 4,
      z: -5,
    },
    icon: '/Three/icon/sxj_icon.png',
    data: [],
    show: false,
    pointCode: '7H0961CPAN77924',
    dataTime: '',
    toP: {
      x: -70.27433095597907,
      y: 8.753833164595864,
      z: -5.218871727447189,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: -1.1466023223195003,
      y: -1.8988402785746414,
      z: -3.2914248069834957,
      duration: 2,
      ease: 'power4.out',
    },
  },
  {
    name: '彩虹桥纪念馆方向摄像机',
    id: `YuanDian10`,
    type: 'Camera',
    position: {
      x: 50.5,
      y: 4,
      z: -5,
    },
    icon: '/Three/icon/sxj_icon.png',
    data: [],
    show: false,
    pointCode: '8L06A0DPAN0754B',
    dataTime: '',
    toP: {
      x: 69.1252383332412,
      y: 8.632133195958298,
      z: -4.822438477532835,
      duration: 2,
      ease: 'power4.out',
    },
    toC: {
      x: -0.38725392744080417,
      y: 0.8244778362443704,
      z: -6.522822745737244,
      duration: 2,
      ease: 'power4.out',
    },
  },
]);
const deviceCode = ref(null);
const stCode = ref(null);
const MiMa = ref(null);
const dialogVisible = ref(false);
const loading = ref(false);
const status = ref(false);
const timer = ref(null);

const Scene = new THREE.Scene();
const clock = new THREE.Clock();
const threeDom = ref(null);
const cameraPosition = {
  // x: 457.66301930145875,
  // y: 397.5473109836439,
  // z: 943.8703438418463,
  x: -58.221584999469584,
  y: 6.590211176632594,
  z: 9.665579736149148,
};
const cameraLookat = {
  x: 1,
  y: 1,
  z: -20,
};
const closeWindow = item => {
  item.show = false;
  // 摄像机位置
  gsap.to(Camera.value.position, cameraPosition);
  // 视角
  gsap.to(Controls.value.target, cameraLookat);
};
// 点位点击
const ydClick = point => {
  // 清除其他点位 再开
  labelData.value.forEach(item => {
    item.show = false;
  });
  point.show = true;

  // 摄像机位置
  gsap.to(Camera.value.position, point.toP);
  // 视角
  gsap.to(Controls.value.target, point.toC);

  if (point.type == 'Camera') {
    let data = {
      title: point.name,
      comIDs: ['Imou'],
      getSiteId: point.pointCode,
    };
    bus.emit('publicDialog', data);
  }
};

/**
 * 初始化模态对话框
 * @param {string} name - 模型的名称
 * @param {string} url - 模型的URL
 */
const initModal = (name, url) => {
  const Gltfloader = new GLTFLoader();
  var dracoLoader = new DRACOLoader();
  // dracoLoader.setDecoderPath("https://zhzz.hongshan.gov.cn:8865/file/hongshan/Three_Gltf/"); //设置解压库文件路径
  dracoLoader.setDecoderPath('/draco/'); //设置解压库文件路径
  Gltfloader.setDRACOLoader(dracoLoader);
  Gltfloader.load(
    url,
    gltf => {
      gltf.scene.name = name;
      gltf.scene.scale.set(1, 1, 1);
      // gltf.scene.position.x = -70;
      gltf.scene.position.y = 2;
      cameraReset(cameraPosition, cameraLookat);
      // Scene.add(gltf.scene);
      Scene.traverse(function (child) {
        if (child.isMesh) {
          child.frustumCulled = false;
          child.material.side = THREE.DoubleSide;
          granaryArr.value.push(child);
        }
      });
      console.log(gltf);
      // gltf.scene.forEach((element) => {
      //   if ((element.name = "布尔")) {
      //     let material = new THREE.MeshBasicMaterial({ color: 0xCCCCCC }); // 设置路面颜色为灰色
      //     element.children[0]
      //     // 路面
      //     // element.children
      //   }
      // });
      // 遍历模型中的所有网格
      gltf.scene.traverse(child => {
        if (child.name == '立方体1' || child.name == '立方体2') {
          // 修改或替换材质
          // child.material = new THREE.MeshBasicMaterial({ color: 0x545d0c}); // 将材质替换为红色基本材质
        }
      });

      // 将模型添加到场景中
      Scene.add(gltf.scene);
      LoadWater();
    },
    function (xhr) {
      // console.log(Math.floor((xhr.loaded / xhr.total) * 100));
    }
  );
};

/**
 * 恢复相机位置和视角
 *
 * 此函数通过GSAP动画库来调整相机的位置和视角,以实现 Smooth Transition
 *
 * @param {Object} position - 相机的新位置,包含x, y, z坐标
 * @param {Object} lookAt - 相机的新视角目标,包含x, y, z坐标,目前未使用
 * @param {number} time - 动画过渡时间,单位为秒,默认为3秒
 */
const cameraReset = (position, lookAt, time = 3) => {
  gsap.to(Camera.value.position, {
    x: position.x,
    y: position.y,
    z: position.z,
    duration: time,
    ease: 'power4.out',
  });
  // gsap.to(Camera.value.lookAt, {
  //   x: lookAt.x,
  //   y: lookAt.y,
  //   z: lookAt.z,
  //   duration: time,
  //   ease: "power4.out",
  // });
  gsap.to(Controls.value.target, {
    x: lookAt.x,
    y: lookAt.y,
    z: lookAt.z,
    duration: time,
    ease: 'power4.out',
  });
};

/**
 * 初始化渲染器
 * 该函数负责创建和配置Three.js的WebGL渲染器,包括设置视口大小、抗锯齿、阴影、像素比、色调映射等
 */
const initRenderer = () => {
  width.value = document.getElementById('WangJiaPIng').clientWidth;
  height.value = document.getElementById('WangJiaPIng').clientHeight;
  Renderer.value = new THREE.WebGLRenderer({
    antialias: true,
    // alpha: true, //开启alpha
  });
  Renderer.value.shadowMap.enabled = true;
  Renderer.value.setPixelRatio(window.devicePixelRatio);
  Renderer.value.setSize(width.value, height.value, true);
  // Renderer.value.toneMapping = THREE.ACESFilmicToneMapping;
  Renderer.value.toneMappingExposure = 1; // 曝光系数
  threeDom.value.appendChild(Renderer.value.domElement);
};

/**
 * 初始化标签渲染器
 * 该函数用于创建和配置一个CSS3D渲染器,用于渲染标签对象
 * 它设置了渲染器的大小,位置,并将其添加到三维场景的DOM元素中
 */
const initLabelRenderer = () => {
  LabelRenderer.value = new CSS3DRenderer();
  LabelRenderer.value.setSize(width.value, height.value);
  LabelRenderer.value.domElement.style.position = 'absolute';
  LabelRenderer.value.domElement.style.top = '0px';
  threeDom.value.appendChild(LabelRenderer.value.domElement);
  // LabelRenderer.value.domElement.addEventListener("click", meshOnClick);
};

/**
 * 初始化摄像机
 * 创建一个透视摄像机,并设置其位置
 */
const initCamera = () => {
  Camera.value = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 4000);
  Camera.value.position.set(500, 500, 500);
};

/**
 * 初始化控制对象
 * 设置相机控制属性,以实现特定的相机行为
 */
const initControls = () => {
  Controls.value = new OrbitControls(Camera.value, LabelRenderer.value.domElement);
  //上下翻转的最大角度
  Controls.value.maxPolarAngle = 1.5;
  // //上下翻转的最小角度
  Controls.value.minPolarAngle = 0.2;
  // 使动画循环使用时阻尼或自转 意思是否有惯性
  Controls.value.enableDamping = false;
  // 动态阻尼系数 就是鼠标拖拽旋转灵敏度
  Controls.value.dampingFactor = 0.04;
  // 是否可以旋转
  Controls.value.enableRotate = true;
  // 是否可以缩放与速度
  Controls.value.enableZoom = true;
  // 设置相机距离原点的最远距离
  Controls.value.minDistance = 30;
  // 设置相机距离原点的最远距离
  Controls.value.maxDistance = 3000;
  // 是否开启右键拖拽
  Controls.value.enablePan = true;
  // AxesHelper:辅助观察的坐标系
  // const axesHelper = new THREE.AxesHelper(3000);
  // Scene.add(axesHelper);
};

/**
 * 初始化灯光
 * 创建并添加环境光到场景中,以模拟全局照明效果
 */
const initLight = () => {
  // // // 设置场景的背景颜色,即天空颜色
  // // Scene.background = new THREE.Color(0x999999); // 设置背景,可以更换为你想要的颜色
  // // // 设置天空的雾气颜色和雾气近距离
  // Scene.fog = new THREE.Fog(0xffffff, 50, 200); // 距离10开始,到200结束
  // // //  创建平行光源
  // const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
  // Scene.add(directionalLight);
  // // 创建环境光
  // const ambientLight = new THREE.AmbientLight("#fff", 0.8);
  // Scene.add(ambientLight);
  // // // 创建平行光辅助线
  // // const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 0.5);
  // // Scene.add(directionalLightHelper);
  // // 创建点光源
  // const PointLight = new THREE.PointLight(0x1784f9, 1, 300);
  // PointLight.position.set(100, -100, 10);
  // Scene.add(PointLight);
};

/**
 * 初始化天空盒
 * 使用PMREMGenerator生成环境贴图,并设置为场景的环境光和背景
 * 通过RGBELoader加载HDR纹理,用于创建环境贴图
 * 注意:此函数未使用TextureLoader加载背景图片,而是使用HDR纹理
 */
const initSky = () => {
  var pmremGenerator = new THREE.PMREMGenerator(Renderer.value); // 使用hdr作为背景色
  pmremGenerator.compileEquirectangularShader();
  new RGBELoader().load('/Gltf/Skey_1K.hdr', function (texture) {
    const envMap = pmremGenerator.fromEquirectangular(texture).texture;
    envMap.isPmremTexture = true;
    Scene.environment = envMap;
    Scene.background = envMap;
    pmremGenerator.dispose();
  });
  // new THREE.TextureLoader().load("/Gltf/bg.png", function (texture) {
  //   Scene.background = texture;
  // });
};

/**
 * 渲染函数,用于不断更新和渲染场景
 */

const Render = () => {
  animationFrameId.value = requestAnimationFrame(Render);
  Controls.value.update(); // 轨道控制器的更新
  Renderer.value.clear(); // 清除画布
  updateLabelOrientation(Camera.value.position);
  Renderer.value.render(Scene, Camera.value);
  LabelRenderer.value.render(Scene, Camera.value);
  const delta = clock.getDelta();
  // 如需调试请打开这个获取Camera,Controls 的值
  // console.log('Camera.value', Camera.value);
  // console.log('Controls.value', Controls.value);
};

// 创建气泡窗
function createLable() {
  labelData.value.forEach((item, index) => {
    let labelCSS3D = Scene.getObjectByName(`YuanDian${index + 1}`);
    if (labelCSS3D === undefined) {
      let lableDiv = document.getElementById(`YuanDian${index + 1}`);
      lableDiv.style.display = 'block';
      labelCSS3D = new CSS3DObject(lableDiv);
      labelCSS3D.position.set(item.position.x, item.position.y, item.position.z);
      labelCSS3D.scale.set(0.1, 0.1, 0.1);
      labelCSS3D.name = `YuanDian${index + 1}`;
      // labelCSS3D.rotation.y = - Math.PI / 6; // 30度转换为弧度
      Scene.add(labelCSS3D);
    } else {
      labelCSS3D.visible = true;
    }
  });
}

/**
 * 更新所有气泡框的方向,使其始终面向相机
 */
function updateLabelOrientation(cameraPosition) {
  labelData.value.forEach((item, index) => {
    let labelCSS3D = Scene.getObjectByName(`YuanDian${index + 1}`);
    if (labelCSS3D) {
      const direction = new THREE.Vector3();
      direction.subVectors(cameraPosition, labelCSS3D.position).normalize();
      const angle = Math.atan2(direction.x, direction.z);
      labelCSS3D.rotation.y = angle; // 调整角度使其始终面向相机
    }
  });
}
const flyTo = data => {
  // 静立水准仪
  if (data.name[0] == '静力水准仪') {
    // 摄像机位置
    gsap.to(Camera.value.position, {
      x: -57.41155667894531,
      y: 6.7641604399912865,
      z: 11.781994826043844,
      duration: 3,
      ease: 'power4.out',
    });
    // 视角
    gsap.to(Controls.value.target, {
      x: -0.6994858490355302,
      y: 0.5764769980367779,
      z: -15.294633781993175,
      duration: 3,
      ease: 'power4.out',
    });
  } else if (data.name[0] == '应变计') {
    // 摄像机位置
    gsap.to(Camera.value.position, {
      x: -53.61576836842107,
      y: 7.710859842105263,
      z: 17.230486105263143,
      duration: 3,
      ease: 'power4.out',
    });
    // 视角
    gsap.to(Controls.value.target, {
      x: 29.03625918562505,
      y: -0.3313374072727649,
      z: -29.291435662949137,
      duration: 3,
      ease: 'power4.out',
    });
  } else if (data.name.includes('加速度计')) {
    gsap.to(Camera.value.position, {
      x: -11.465032004199559,
      y: 5.053503359128684,
      z: 15.647675383755246,
      duration: 3,
      ease: 'power4.out',
    });
    gsap.to(Controls.value.target, {
      x: 12.070445610968184,
      y: -0.5540312430818636,
      z: -12.12358097277393,
      duration: 3,
      ease: 'power4.out',
    });
  } else if (data.name.includes('风速风向仪')) {
    gsap.to(Camera.value.position, {
      x: -58.221584999469584,
      y: 6.590211176632594,
      z: 9.665579736149148,
      duration: 3,
      ease: 'power4.out',
    });
    gsap.to(Controls.value.target, {
      x: 1,
      y: 1,
      z: -20,
      duration: 3,
      ease: 'power4.out',
    });
  } else if (data.name.includes('裂缝计')) {
    gsap.to(Camera.value.position, {
      x: -57.02391699702596,
      y: 4.679545725497521,
      z: 12.416539848914276,
      duration: 3,
      ease: 'power4.out',
    });
    gsap.to(Controls.value.target, {
      x: 2.197668002974112,
      y: -0.9106652745024885,
      z: -17.24904015108576,
      duration: 3,
      ease: 'power4.out',
    });
  } else if (data.name.includes('摄像机')) {
    gsap.to(Camera.value.position, {
      x: -74.57145168733881,
      y: 14.5437957001853,
      z: 18.62897991542918,
      duration: 3,
      ease: 'power4.out',
    });
    gsap.to(Controls.value.target, {
      x: 0.6482923084213158,
      y: -1.5888868202391535,
      z: -19.59950474716774,
      duration: 3,
      ease: 'power4.out',
    });
  }
  // x: -74.57145168733881, y: 14.5437957001853, z: 18.62897991542918,
  // x: 0.6482923084213158, y: -1.5888868202391535, z: -19.59950474716774,

  // 打开弹窗
  labelData.value.forEach(element => {
    let val = element.type == 'Camera' ? '摄像机' : element.name;
    if (data.name.includes(val)) {
      element.show = true;
    } else {
      element.show = false;
    }
  });
};
// const BIMClick = () => {
//   console.log("触发点击事件,隐藏弹窗");
//   labelData.value.forEach((element) => {
//     element.show = false;
//   });
// };

// 获取点位信息
const getPonintInfo = () => {
  const promises = labelData.value.map(item => {
    return pointGetDataList({ pointCode: item.pointCode }).then(res => {
      // 检测时间
      const timeWithDate = res.data.find(time => time.dataTime);
      if (timeWithDate) {
        item.dataTime = timeWithDate.dataTime;
      }
      return { ...item, data: res.data };
    });
  });

  Promise.all(promises)
    .then(updatedItems => {
      labelData.value = updatedItems;
    })
    .catch(error => {
      console.error('请求出错:labelData.value', error);
    });
};
// 加入水体
const LoadWater = () => {
  const waterGeometry = new THREE.PlaneGeometry(100, 330, 32, 32); //水体大小 长宽
  Twater = new Water(waterGeometry, {
    textureWidth: 512,
    textureHeight: 512,
    waterNormals: new THREE.TextureLoader().load('/Gltf/waternormals.jpg', function (texture) {
      texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
    }),
    sunDirection: new THREE.Vector3(),
    sunColor: 0xffffff,
    waterColor: 0x001e0f,
    distortionScale: 1,
    fog: Scene.fog !== undefined,
  });
  Twater.position.set(0, -1.5, 0); //水体位置x
  Twater.rotation.x = -Math.PI / 2;
  // Twater.rotateZ(-110);
  Scene.add(Twater);
  animate();
};
const animate = () => {
  // 配置动画
  requestAnimationFrame(animate);
  Twater.material.uniforms['time'].value += 1.0 / 100.0;
};
onBeforeMount(() => {
  //   initGltfFloor();
  // initModal('ChangJing', '/Gltf/ChuWangCheng.gltf');
  // initModal('ChangJing', '/Gltf/qiaoliang.glb');
  // initModal('daqiao', 'https://newfiber-cloud-1255570142.cos.ap-chengdu.myqcloud.com/yanan/daqiao.glb');
  initModal('daqiao', 'https://newfiber-cloud-1255570142.cos.ap-chengdu.myqcloud.com/yanan/daqiao.gltf');
  // 共同弹窗触发事件
  bus.on('WJP_BIM_flyTo', params => {
    // 打开弹窗
    flyTo(params);
  });
});
onMounted(() => {
  getPonintInfo();
  nextTick(() => {
    if (document.readyState === 'complete') {
      createLable();
      // createWaterLevel();
    }
  });
  initRenderer();
  initLabelRenderer();
  initCamera();
  initControls();
  initLight();
  initSky();
  createLable();
  Render();
  // 添加点击事件
  //监听点击事件
  // window.addEventListener("click", BIMClick, false);
});

onBeforeUnmount(() => {
  cancelAnimationFrame(animationFrameId.value);
  bus.off('WJP_BIM_flyTo');
  // window.removeEventListener("click", BIMClick);

  // document.removeEventListener('click', meshOnClick);
  // window.removeEventListener("resize", onWindowResize, false);

  Scene.traverse(e => {
    if (e.BufferGeometry) e.BufferGeometry.dispose();
    if (e.material) {
      if (Array.isArray(e.material)) {
        e.material.forEach(m => {
          m.dispose();
        });
      } else {
        e.material.dispose();
      }
    }
    if (e.isMesh) {
      e.remove();
    }
  });
  Scene.remove();
  Renderer.value.dispose();
  Renderer.value.content = null;
  clearInterval(timer.value);

  // 清理渲染器和相机
  Camera.value = null;
});
</script>

<style lang="scss" scoped>
#WangJiaPIng {
  width: 100%;
  height: 100%;
  position: absolute;
  // background: url("@/assets/images/Sponge_screen/QiaoLiang/BIM.png") no-repeat center center;

  .YuanDian {
    z-index: 9999 !important;
    position: relative;
    // min-height: 20px;
    .iconBox {
      position: relative;
      // border: 1px solid red;
    }
    .iconImg {
      position: absolute;
      left: 50%;
      // transform: translateX(-50%);
      bottom: 5px;
      width: 19px;
      height: 12px;
    }
    .ydBox {
      // width: 134px;
      // height: 70px;
      position: absolute;
      left: calc(50% + 19px);
      bottom: 8px;
      width: 60px;
      // height: 26px;
      background: linear-gradient(0deg, rgba(12, 54, 92, 0.6) 0%, rgba(12, 54, 92, 0.6) 100%);
      border-radius: 2px;
      border: 1px solid #04d8ff;
      .iconClose {
        width: 5px;
        height: 5px;
        position: absolute;
        right: 1px;
        top: 0;
        cursor: pointer;
      }
      .ydData {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0 3px;
        font-size: 3px;
        height: 7px;
        line-height: 7px;
        color: #04d8ff;
        // .leftData {
        // }
        // .rightData {
        // }
      }
    }
    .YuanDianText {
      // padding-bottom: 10px;
      height: 7px;
      line-height: 7px;
      color: #fff;
      text-shadow: 0px 1px 3px rgba(0, 0, 0, 0.9);
      white-space: nowrap;
      word-break: keep-all;
      // cursor: pointer;
      pointer-events: none;
      font-size: 3px;
      text-align: center;
      background: linear-gradient(90deg, rgba(4, 216, 255, 0.8) 0%, rgba(4, 216, 255, 0.2) 100%);
    }

    .YuanDianIcon {
      width: 10px;
      height: 10px;
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      bottom: 0;
      pointer-events: auto;
      cursor: pointer;
    }
  }
}
</style>