dedsudiyu 1 月之前
父节点
当前提交
6b349b7ac9

二进制
public/models/demo2.glb


+ 48 - 17
src/components/H5PlayerVideo/H5PlayerVideo.vue

@@ -107,23 +107,54 @@
         })
       },
       initPlayer(url, index, type) {
-        this.myPlugin.JS_Play(url,
-          {
-            playURL: url, // 流媒体播放时必传
-            mode: type?type:0 // 解码类型:0=普通模式; 1=高级模式 默认为0
-            // ...
-          },
-          index //当前窗口下标
-        ).then(
-          () => {
-            // console.info('JS_Play success')
-            // do you want...
-          },
-          (err) => {
-            // console.info('JS_Play failed:', err)
-            // do you want...
-          }
-        )
+        console.log('url');
+        if(url.indexOf('?') != -1){
+          let newUrl = url.split("?")[0]
+          let list = url.split("?")[1].split("&");
+          let timeData = {};
+          list.forEach((item) => {
+            timeData[item.split("=")[0]] = item.split("=")[1];
+          })
+          let startTime = timeData.beginTime +".000+08:00";
+          let endTime = timeData.endTime + ".000+08:00";
+          this.myPlugin.JS_Play(newUrl,
+            {
+              playURL: newUrl, // 流媒体播放时必传
+              mode: type?type:0 // 解码类型:0=普通模式; 1=高级模式 默认为0
+              // ...
+            },
+            index, //当前窗口下标
+            startTime,
+            endTime
+          ).then(
+            () => {
+              // console.info('JS_Play success')
+              // do you want...
+            },
+            (err) => {
+              // console.info('JS_Play failed:', err)
+              // do you want...
+            }
+          )
+        }else{
+          this.myPlugin.JS_Play(url,
+            {
+              playURL: url, // 流媒体播放时必传
+              mode: type?type:0 // 解码类型:0=普通模式; 1=高级模式 默认为0
+              // ...
+            },
+            index //当前窗口下标
+          ).then(
+            () => {
+              // console.info('JS_Play success')
+              // do you want...
+            },
+            (err) => {
+              // console.info('JS_Play failed:', err)
+              // do you want...
+            }
+          )
+        }
       },
       //生成随机ID
       generateRandomString() {

+ 5 - 5
src/router/index.js

@@ -53,11 +53,11 @@ export const constantRoutes = [
   //   component: (resolve) => require(['@/views/demo7'], resolve),
   //   hidden: true
   // },
-  // {
-  //   path: '/demo8',
-  //   component: (resolve) => require(['@/views/demo8'], resolve),
-  //   hidden: true
-  // },
+  {
+    path: '/demo8',
+    component: (resolve) => require(['@/views/demo8'], resolve),
+    hidden: true
+  },
 ]
 
 export default new Router({

+ 1 - 1
src/views/cengterMaxBox/videoSurveillance/pageComponent/videoComponent.vue

@@ -152,7 +152,7 @@
         //   {
         //     width:this.width,
         //     height:this.height,
-        //     url:'ws://172.16.0.68:559/openUrl/Sg0ajRK?beginTime=20250305T132000&endTime=20250305T132500',
+        //     url:'ws://172.16.0.68:559/openUrl/JMFQoNi?beginTime=2025-03-05T13:00:00&endTime=2025-03-05T13:10:00',
         //     cameraIndexCode:'f0192a7ffd014509a8f2e8f3bc0936cf',
         //   },
         // ];

+ 1 - 1
src/views/demo6.vue

@@ -240,7 +240,7 @@
       //模型加载
       loadModel() {
         const loader = new GLTFLoader();
-        loader.load('/models/demo1.glb', (gltf) => {
+        loader.load('/models/demo2.glb', (gltf) => {
           const model = gltf.scene;
           this.scene.add(model);
 

+ 232 - 139
src/views/demo8.vue

@@ -1,165 +1,258 @@
-<!-- 测试demo -->
 <template>
-  <div class="demo7">
-    <div class="map-max-big-box ">
-      <div class="map-box">
-        <canvasMap ref="canvasMap" :alarmPropsList="alarmPropsList"></canvasMap>
+  <div class="container">
+    <div ref="canvasContainer" class="canvas-container"></div>
+    <div class="buttons-container">
+      <div
+        v-for="house in houses"
+        :key="house.uuid"
+        class="house-button"
+        :style="{
+          left: `${house.screenPosition.x}px`,
+          top: `${house.screenPosition.y}px`,
+        }"
+      >
+        <button @click="changeMaterial(house)">更换材质</button>
+        <button @click="changeTexture(house)">更换贴图</button>
+        <button @click="restoreOriginalMaterial(house)">恢复材质</button>
       </div>
     </div>
   </div>
 </template>
 <script>
-  import mqtt from 'mqtt'
-  import {
-    laboratoryBigViewSelectTriggerInfo,
-  } from "@/api/index";
-  //地图模型组件
-  import canvasMap from "@/views/cengterMaxBox/canvasMap/index.vue";
+  import * as THREE from 'three';
+  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
+  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
+
+  import TWEEN from 'tween.js';
+  import { CSS2DRenderer, CSS2DObject, } from "three/examples/jsm/renderers/CSS2DRenderer";
   export default {
-    name: 'demo7',
-    components: {
-      //地图模型组件
-      canvasMap,
-    },
-    data () {
+    data() {
       return {
-        //预案MQTT
-        planOpic:'lab/risk/plan/change',
-        planClient:{},
-        //预案数据
-        alarmPropsList:[],
-        alarmPropsData:{},
-        pageType:1,
-        audioType:false,
-        alarmTitle:'',
-        //南北校区相关
-
-      }
-    },
-    created () {
+        houses: [], // 存储每个房子的信息
+        scene: null,
+        camera: null,
+        renderer: null,
+        controls: null,
+        materials: [], // 预加载的材质选项
+        textures: [], // 预加载的贴图选项
 
+        subModels: [],
+        labelRenderer:null,
+        initialCameraPosition: new THREE.Vector3(0.5, 1, 0.5),//旋转-距离-俯角
+        initialControlsTarget: new THREE.Vector3(0, 0, 0),
+      };
     },
-    mounted () {
-      //判断是否已有预警MQTT链接
-      if(!this.planClient.unsubscribe){
-        this.offPlanMQTT('on');
-      }
-      this.laboratoryBigViewSelectTriggerInfo();
+    mounted() {
+      this.initThree();
+      this.loadModel();
+      this.loadAssets();
+      this.animate();
     },
     methods: {
-      //预案-MQTT连接
-      offPlanMQTT(type){
-        let self = this;
-        if(self.planClient.unsubscribe){
-          self.planClient.unsubscribe(self.planOpic, error => {
-            if (error) {
-              // console.log('mqtt关闭连接错误:', error)
-            }
-          })
-          self.planClient.end();
-          this.$set(this,'planClient',{});
-        }
-        //判断传入参数如果存在 发起一次新的连接
-        if(type){
-          this.planMQTT();
-        }
+      initThree() {
+        // 初始化场景
+        this.scene = new THREE.Scene();
+        this.scene.background = new THREE.Color(0xdddddd);
+
+        // // 初始化相机
+        // this.camera = new THREE.PerspectiveCamera(
+        //   75,
+        //   window.innerWidth / window.innerHeight,
+        //   0.1,
+        //   1000
+        // );
+        // this.camera.position.set(0.5, 0.5, 0.5);
+
+        // 初始化渲染器
+        this.renderer = new THREE.WebGLRenderer({ antialias: true });
+        this.renderer.setSize(window.innerWidth, window.innerHeight);
+        this.$refs.canvasContainer.appendChild(this.renderer.domElement);
+
+        // 初始化相机时使用存储的位置
+        this.camera = new THREE.PerspectiveCamera(
+          75,
+          window.innerWidth / window.innerHeight,
+          0.1,
+          1000
+        );
+        this.camera.position.copy(this.initialCameraPosition);
+
+        // 初始化控制器时存储初始目标
+        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
+        this.controls.target.copy(this.initialControlsTarget);
+        // ...其他初始化代码保持不变...
+
+
+        this.labelRenderer = new CSS2DRenderer();
+        this.labelRenderer.setSize(
+          this.$refs.canvasContainer.clientWidth,
+          this.$refs.canvasContainer.clientHeight
+        );
+        this.labelRenderer.domElement.style.position = 'absolute';
+        this.labelRenderer.domElement.style.top = '0';
+        this.labelRenderer.domElement.style.pointerEvents = 'none';
+        this.$refs.canvasContainer.appendChild(this.labelRenderer.domElement);
+
+        // 初始化控制器
+        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
+        this.controls.enableDamping = true;
+        this.controls.dampingFactor = 0.05;
+
+        // 添加灯光
+        const ambientLight = new THREE.AmbientLight(0xffffff, 1);
+        this.scene.add(ambientLight);
+        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
+        directionalLight.position.set(0, 5, 5);
+        this.scene.add(directionalLight);
+
+        // 启动动画循环
+        this.animate();
       },
-      //预案-MQTT订阅
-      planMQTT(){
-        let self = this;
-        this.planClient = mqtt.connect(localStorage.getItem('mqttUrl'), {
-          username: localStorage.getItem('mqttUser'),
-          password:localStorage.getItem('mqttPassword')
+
+      async loadModel() {
+        const loader = new GLTFLoader();
+        const gltf = await loader.loadAsync('/models/demo2.glb');
+
+        // 递归查找所有Group
+        const traverseGroups = (obj) => {
+          if (obj.isGroup) {
+            this.registerHouse(obj);
+          }
+          obj.children.forEach(child => traverseGroups(child));
+        };
+
+        traverseGroups(gltf.scene);
+        this.scene.add(gltf.scene);
+      },
+
+      // 修改后的 registerHouse 方法
+      registerHouse(group) {
+        const bbox = new THREE.Box3().setFromObject(group);
+        const center = bbox.getCenter(new THREE.Vector3());
+
+        // 记录原始材质
+        const originalMaterials = [];
+        group.traverse(child => {
+          if (child.isMesh) {
+            originalMaterials.push({
+              mesh: child,
+              material: child.material.clone() // 重要:必须克隆原始材质
+            });
+          }
         });
-        this.planClient.on("connect", e =>{
-          this.planClient.subscribe(self.planOpic, (err) => {
-            if (!err) {
-              // console.log("预案-订阅成功:" + self.planOpic);
-            }else{
-              // console.log("预案-连接错误:" + err);
-            }
-          });
+
+        this.houses.push({
+          uuid: group.uuid,
+          group: group,
+          screenPosition: new THREE.Vector2(),
+          worldPosition: center,
+          originalMaterials: originalMaterials // 新增原始材质存储
         });
-        this.planClient.on("message", (topic, message) => {
-          if (message){
-            //获取预案数据
-            this.laboratoryBigViewSelectTriggerInfo();
+      },
+
+      loadAssets() {
+        // 预加载材质和贴图
+        const textureLoader = new THREE.TextureLoader();
+        this.textures = [
+          textureLoader.load('/png/alarm.png'),
+          textureLoader.load('/png/noAlarm.png'),
+        ];
+
+        this.materials = [
+          new THREE.MeshStandardMaterial({ color: 0xff0000 }),
+          new THREE.MeshStandardMaterial({ color: 0x00ff00 }),
+        ];
+      },
+
+      updateScreenPositions() {
+        const width = window.innerWidth;
+        const height = window.innerHeight;
+
+        this.houses.forEach(house => {
+          // 将三维坐标转换为屏幕坐标
+          const vector = house.worldPosition.clone().project(this.camera);
+          house.screenPosition.x = (vector.x * 0.5 + 0.5) * width;
+          house.screenPosition.y = (vector.y * -0.5 + 0.5) * height;
+        });
+      },
+
+      // 新增恢复方法
+      restoreOriginalMaterial(house) {
+        house.originalMaterials.forEach(entry => {
+          entry.mesh.material.dispose(); // 清理当前材质
+          entry.mesh.material = entry.material.clone();
+          entry.mesh.material.needsUpdate = true;
+        });
+      },
+
+      // 修改原有材质切换方法(添加清理)
+      changeMaterial(house) {
+        house.group.traverse(child => {
+          if (child.isMesh) {
+            child.material.dispose(); // 清理旧材质
+            child.material = this.materials[Math.floor(Math.random() * this.materials.length)];
           }
         });
       },
-      //查询当前正在发生的预案
-      laboratoryBigViewSelectTriggerInfo(){
-        let self = this;
-        laboratoryBigViewSelectTriggerInfo().then(response => {
-          if(response.data[0]){
-            response.data.forEach((item)=>{
-              item.triggerUploadData = JSON.parse(item.triggerUploadData);
-              item.alarmText = item.riskPlanName.split('预案');
-              item.alarmText = item.alarmText[0].split('预警');
-              item.alarmText = item.alarmText[0]+'预警';
-            })
-            //报警提示title信息
-            this.$set(this,'alarmTitle',response.data[response.data.length-1].alarmText);
-            //报警窗口数据
-            this.$set(this,'alarmPropsData',response.data[response.data.length-1]);
-            //报警窗口开启
-            this.$set(this,'pageType',2);
-            //判断报警楼栋属于南北校区
-            setTimeout(function(){
-              self.$refs['canvasMap'].alarmTrigger(response.data,response.data[response.data.length-1]);
-            },500);
-            //报警声音
-            if(this.audioType){
-              /* 报警音频播放 */
-              const audio = this.$refs.audioPlayer;
-              // 尝试静音自动播放
-              audio.play().catch(() => {
-                // 如果失败,延迟 2 秒再次尝试(趁浏览器未完全冻结)
-                setTimeout(() => audio.play(), 2000);
-              });
-              // 延迟 3 秒后尝试取消静音(需浏览器允许)
-              setTimeout(() => {
-                audio.muted = false;
-              }, 3000);
-            }
-          }else{
-            this.$set(this,'pageType',1);
-            setTimeout(function(){
-              self.$refs['canvasMap'].alarmOff();
-            },500);
+
+      changeTexture(house) {
+        const texture = this.textures[Math.floor(Math.random() * this.textures.length)];
+        texture.needsUpdate = true;
+
+        house.group.traverse(child => {
+          if (child.isMesh) {
+            child.material.map = texture;
+            child.material.needsUpdate = true;
           }
-        })
+        });
+      },
+      onWindowResize() {
+        this.camera.aspect = window.innerWidth / window.innerHeight;
+        this.camera.updateProjectionMatrix();
+        this.renderer.setSize(window.innerWidth, window.innerHeight);
+      },
+
+      animate() {
+        requestAnimationFrame(this.animate);
+        this.controls.update();
+        this.updateScreenPositions();
+        this.renderer.render(this.scene, this.camera);
       },
     },
     beforeDestroy() {
-      let self = this;
-      // MQTT预警
-      self.offPlanMQTT();
-    },
-  }
+      window.removeEventListener('resize', this.onWindowResize);
+      // 清理Three.js资源
+      this.renderer.dispose();
+    }
+  };
 </script>
-<style scoped lang="scss">
-  .demo7{
-    width: 11520px;
-    height: 2160px;
+
+<style scoped>
+  .container {
     position: relative;
-    overflow: hidden;
-    .map-max-big-box{
-      z-index: 10;
-      position: absolute;
-      width:5927px;
-      height: 2160px;
-      top:3px;
-      /*left:2760px;*/
-      left:0;
-      overflow: hidden;
-      .map-box{
-        transform:scaleX(1.4);
-        transform-origin: 50% 0;
-      }
-    }
-    .showBox{
-      z-index: 11;
-    }
+    width: 100%;
+    height: 100vh;
+  }
+
+  .canvas-container {
+    width: 100%;
+    height: 100%;
+  }
+
+  .buttons-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    pointer-events: none;
+  }
+
+  .house-button {
+    position: absolute;
+    transform: translate(-50%, -50%);
+    pointer-events: auto;
+  }
+
+  .house-button button {
+    margin: 5px;
   }
 </style>