chenlei 8 月之前
父节点
当前提交
725e549c4f

二进制
hotspot/assets/images/syjy/icon-left-min.png


二进制
hotspot/assets/images/syjy/icon-right-min.png


+ 41 - 14
hotspot/views/hotspot/index.syjy.scss

@@ -5,9 +5,9 @@
   right: 0;
   bottom: 0;
   display: flex;
-  flex-direction: column;
   align-items: center;
   justify-content: center;
+  gap: 40px;
   padding: 22px 0 71px;
   z-index: var(--z-index-popper);
 
@@ -24,37 +24,40 @@
   }
   &-info {
     color: #333333;
-    max-width: 1320px;
-    width: calc(100vw - 30vw);
 
     h3 {
       margin-bottom: 18px;
       font-size: 18px;
       font-weight: 700;
-      text-align: center;
       color: #9d222d;
     }
     div {
-      margin: 0 auto;
-      width: 80%;
       font-size: 18px;
       line-height: 32px;
       text-indent: 2em;
     }
   }
 
+  &-scrollbar {
+    flex: 1;
+    flex-shrink: 0;
+    padding-right: 20px;
+    min-width: 230px;
+    max-width: 700px;
+    height: 600px;
+  }
+
   &-container {
     position: relative;
     flex: 1;
-    flex-shrink: 1;
-    height: 0;
+    width: 0;
     display: flex;
     flex-direction: column;
     align-items: center;
     padding: 9vh 20px;
-    max-width: 1320px;
-    min-width: 400px;
     width: auto;
+    max-width: 1020px;
+    max-height: 800px;
     box-sizing: border-box;
   }
 
@@ -70,12 +73,12 @@
       z-index: 1;
     }
     &__left {
-      left: -70px;
+      left: -10px;
       background: url('@hotspot/assets/images/syjy/icon-previous-min.png') no-repeat center /
         contain;
     }
     &__right {
-      right: -70px;
+      right: -10px;
       background: url('@hotspot/assets/images/syjy/icon-next-min.png') no-repeat center / contain;
     }
   }
@@ -92,10 +95,12 @@
     display: flex;
     align-items: center;
     justify-content: center;
+    height: 100%;
   }
   &-video {
+    width: 100%;
     height: 100%;
-    max-height: 100%;
+    max-height: 623px;
   }
   &-img {
     display: flex;
@@ -103,6 +108,9 @@
     justify-content: center;
     height: inherit;
 
+    .el-image img {
+      max-height: 623px;
+    }
     &-swiper {
       flex: 1;
       width: 100%;
@@ -147,10 +155,11 @@ span.el-image-viewer__close {
 @media only screen and (max-width: 600px) {
   .hotspot-page {
     padding-bottom: 0;
+    flex-direction: column;
 
     .el-scrollbar {
       flex: 1;
-      width: 100%;
+      width: 100% !important;
       height: 0 !important;
       background: #9d222d;
       border-radius: 17px 17px 0px 0px;
@@ -176,7 +185,9 @@ span.el-image-viewer__close {
     }
     &-container {
       max-width: 100%;
+      min-width: 100%;
       width: 100%;
+      height: 0;
       background: none;
     }
     &-swiper {
@@ -210,6 +221,22 @@ span.el-image-viewer__close {
         height: 48px;
       }
     }
+    &-swiper {
+      &__left,
+      &__right {
+        top: 45%;
+        width: 19px;
+        height: 38px;
+      }
+      &__left {
+        left: 0;
+        background: url('@hotspot/assets/images/syjy/icon-left-min.png') no-repeat center / contain;
+      }
+      &__right {
+        right: 0;
+        background: url('@hotspot/assets/images/syjy/icon-right-min.png') no-repeat center / contain;
+      }
+    }
   }
   span.el-image-viewer__close {
     top: 20px;

+ 7 - 4
hotspot/views/hotspot/index.syjy.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="hotspot-page">
-    <div class="hotspot-page-container">
+    <div v-if="myType !== 'text'" class="hotspot-page-container">
       <!-- 音频播放器 -->
       <audio
         id="myAudio"
@@ -48,8 +48,7 @@
           <div class="hotspot-page-img">
             <el-image
               :src="item"
-              fit="contain"
-              style="width: 100%; height: 100%"
+              fit="scale-down"
               preview-teleported
               :preview-src-list="curList"
               :initial-index="idx"
@@ -93,7 +92,10 @@
       </div>
     </div>
 
-    <el-scrollbar :height="150" style="margin-top: 20px; height: 150px; flex-shrink: 0">
+    <el-scrollbar
+      class="hotspot-page-scrollbar"
+      :style="{ width: myType !== 'text' ? '230px' : '80%' }"
+    >
       <div class="hotspot-page-info">
         <h3>{{ myTitle }}</h3>
         <div v-html="myTxt" />
@@ -231,6 +233,7 @@
           if (resData.model) this.myType = 'model';
           else if (resData.video) this.myType = 'video';
           else if (resData.images) this.myType = 'img';
+          else this.myType = 'text';
 
           this.myTitle = resData.title || '';
           this.myTxt = resData.content || '';

二进制
public/images/arrow.png


+ 287 - 0
public/js/manage.js

@@ -63,6 +63,7 @@ var g_weixinObj = {
 };
 
 var settings = {
+  markerHeight: 0.05,//距离地板高出多少,
   hotClickEvent: {
     video: {
       playAndPause: true,
@@ -1582,6 +1583,290 @@ function initByTHREE(THREE) {
   }
   window.RoomLabel = RoomLabel;
 
+  window.initRouteArrow = ()=>{
+    if(window.isEdit)return
+    
+   
+    
+    
+    
+    if(!window.DATA.route?.data || Object.keys(window.DATA.route.data).length == 0)return
+    
+    let {hide, gradualShow, opacityShine, data={}} = window.DATA.route || {}      //hide 默认是否隐藏,若隐藏也可以通过函数展示
+    
+    let panos = player.model.panos 
+    panos.routeNextMap = {} //下一个
+    panos.routePreMap = {} //上一个
+    panos.list.forEach((pano,i)=>{
+        panos.routePreMap[pano.id] = []  
+        panos.routeNextMap[pano.id] = data[pano.id] ? data[pano.id].map(id=>panos.get(id)) : []   
+    })
+    for(let panoId in data){
+        data[panoId].forEach(id=>{
+            panos.routePreMap[id].push(panos.get(panoId)) 
+        }) 
+    }
+    
+    var arrowInfo = { 
+        animateDur : 5000,
+        showDur: 1000,
+        minOpa: 0.2,
+        maxOpa: 0.5 
+         
+    }
+    
+  
+    let arrowTex = Texture.load('images/arrow.png') 
+        arrowTex.anisotropy = 4
+        
+        
+    let arrowMat = new THREE.MeshBasicMaterial({
+        name: 'arrow',
+        transparent:true,
+        map:arrowTex,
+        side:2,
+        opacity: arrowInfo.maxOpa,
+        //depthTest:false
+        depthWrite:false, //防止和导览路线重叠闪烁
+    }) 
+    let mats = {
+        default: arrowMat,
+        fadeIn: arrowMat.clone()
+    }
+    mats.fadeIn.name = 'fadeInArrow'
+    let plane = new THREE.PlaneBufferGeometry(1,1)
+   
+    
+    let arrows = new THREE.Object3D; arrows.name = 'groundArrows'
+      
+    player.model.add(arrows)
+  
+    
+    var createArrow = function(mat){
+      
+        var arrow = new THREE.Mesh(plane, mat)
+        arrow.name = 'arrow'
+        
+        let s = 0.15
+        arrow.scale.set(s,s,s)
+         
+        arrows.add(arrow)
+        return arrow
+    }
+  
+  
+  
+    
+    
+     
+    
+    var updateArrowPose = function(from, to, mat ){
+         
+        var vec = to.floorPosition.clone().clone().sub(from.floorPosition).setY(0);
+        let spaceDis = 0.4//箭头之间的间距
+        let margin = 0.3 //marker端需要留一点距离
+        let sliceCount = Math.max(2, Math.round((vec.length()-margin) / spaceDis)) //分段  
+        let arrowCount = sliceCount - 1
+        
+        let dir = vec.clone().normalize()
+        let dir2d = new THREE.Vector2(dir.x, dir.z)
+        let angle = dir2d.angle() - Math.PI/2
+        let sliceLen = (vec.length()-margin) / sliceCount 
+        let i = arrowCount
+        
+        while(i>0){
+            
+            let pos = from.floorPosition.clone().add(dir.clone().multiplyScalar(margin/2 + i*sliceLen))
+                pos.y+=settings.markerHeight 
+            let arrow = createArrow(mat)
+                arrow.name = 'arrow:'+from.id+"-"+to.id+"|"+i
+            arrow.rotation.set(Math.PI/2, 0, angle);
+            arrow.position.copy(pos)
+            i--
+        } 
+        
+    }
+     
+    var updateArrowOpacity = function(e){//不停更新所有arrow的透明度
+        var transition = function(a){
+            if(!arrows.visible)return
+            
+            var opa = a > 0.5 ? 2-a*2 : 2*a ;
+            opa = arrowInfo.maxOpa*opa+ arrowInfo.minOpa*(1-opa)
+            
+            mats.default.opacity = opa
+            mats.fadeIn.opacity = opa * mats.fadeIn.opacity2
+                
+        }
+        transitions.start(transition, arrowInfo.animateDur, updateArrowOpacity, 0, easing.easeInOutCubic, "updateArrowOpacity")
+    }
+  
+    var fadeInArrow = function(){
+        
+        transitions.cancelById('updateArrowOpacity2')
+        var arrows_ = arrows.children.filter(e=> e.material == mats.fadeIn)
+        if(arrows_.length == 0)return
+        
+        
+        mats.fadeIn.opacity = 0 
+        
+        var transition = function(a){ 
+            if(!opacityShine) mats.fadeIn.opacity = a * arrowInfo.maxOpa
+            else mats.fadeIn.opacity2 = a
+        } 
+        transitions.start(transition, arrowInfo.showDur, function done(){
+            arrows_.forEach(e=>e.material = mats.default)
+        }, 0, easing.easeInOutCubic, "updateArrowOpacity", "updateArrowOpacity2")
+    }
+  
+    var lastArrowPanos = []
+    var updateArrow = function(){//根据当前pano更新
+        
+        if(player.mode != 'panorama' || hide){ //飞出 
+            arrows.visible = false           
+            lastArrowPanos = []
+            return;
+        }
+        arrows.visible = true
+        let currentPano = player.currentPano
+        
+        
+        //先获取所有需要箭头的pano
+        var maxDistance = 6;//该距离内pano可见箭头
+        var maxPathCount = 8;
+        var dis = 0
+        var curPano = currentPano;
+        var panos_ = [];
+        
+        var getAngle = function(pano1,pano2){
+            let dir = new THREE.Vector3().subVectors(pano1.position,pano2.position)
+            dir = new THREE.Vector2(dir.x, dir.z)
+            return dir.angle()
+        }
+        var search = function(pano, path=[pano], angles=[]){//多分支搜寻
+            
+            var neighbor = panos.routeNextMap[pano.id];
+            if(!neighbor || !neighbor.length)return //path.length>1 && console.log('branchPath',path);
+            
+            
+            neighbor.forEach(e=>{
+                let branchPath = path.slice(), angles_ = angles.slice() 
+                if(panos_.find(arr=>arr[0]==e))return //console.log('不回头branchPath',branchPath); //不回头
+                dis = e.floorPosition.distanceTo(currentPano.floorPosition)
+                
+                branchPath.push(e)
+                if(branchPath.length>2){//不折回,否则感觉在面前饶了一圈回来很难看
+                    let i=0
+                    while(i<branchPath.length-1){ //补全angles
+                        if(angles_[i] == void 0){
+                            angles_[i] = getAngle(branchPath[i], branchPath[i+1]) 
+                        }
+                        i++
+                    }
+                    let lastAngle = angles_[branchPath.length-2]//getAngle(branchPath[i],  e)
+                    let reverse = angles_.find((angle, n)=> {
+                        let angleDiff = Math.abs(( lastAngle - angle) % (Math.PI*2) ) //越远限制越大
+                        let minDiff = math.linearClamp(branchPath.length,[3,6],[0.2,0.5])
+                        if(Math.abs(angleDiff - Math.PI ) < minDiff){
+                            //console.log('因为折回而提前结束', n, branchPath)
+                            return true
+                        } 
+                    })
+                    if(reverse != void 0){
+                        return
+                    } 
+                }
+                
+                
+                if(branchPath.length<3 || dis < maxDistance){
+                    panos_.push([pano, e]) 
+                    search(e, branchPath, angles_)
+                }else{
+                    //console.log('branchPath',branchPath)
+                }
+            })
+            
+        }
+        
+        //search(currentPano)
+        let disMap = new Map, cosMap = new Map
+        let camDir = player.getDirection()
+        let neighbors = currentPano.neighbourUUIDs.map(e=>panos.get(e))
+                        .filter(p=>{
+                            let dir = new THREE.Vector3().subVectors(p.position, currentPano.position)
+                            let d = dir.lengthSq()
+                            if(d < 15){//最大距离
+                                disMap.set(p, d);
+                                cosMap.set(p, dir.normalize().dot(camDir)) 
+                                return true
+                            }
+                        }).sort((a,b)=>{ 
+                            let score = disMap.get(a) - disMap.get(b) 
+                            score += (cosMap.get(b) - cosMap.get(a)) * 5
+                            return score
+                        })//从近到远,尽量在前方
+                        
+        let seedPanos = [currentPano, ...neighbors]//如果没有从当前点出发的箭头,就展示隔壁点的(缺点是隔壁点可能是指向当前点的,原规则是不展示来的路径的,所以会有点奇怪。虽然也可以在search后剔除啦)
+        for(let seed of seedPanos){
+            search(seed)
+            if(panos_.length != 0){
+                break;
+            }
+        }
+         
+        
+        arrows.children.slice().forEach(child=>arrows.remove(child))
+        
+        
+        panos_.forEach((panoArr,i)=>{
+            var isNew = !lastArrowPanos.find(e=>e[0]==panoArr[0] && e[1]==panoArr[1])//新出现的点  渐变出现
+            updateArrowPose(panoArr[0], panoArr[1], isNew ? mats.fadeIn : mats.default )//更新位置
+            
+        })
+        
+        fadeInArrow()
+        
+         
+        
+        lastArrowPanos = panos_
+    }
+  
+    let inited
+    let init = ()=>{
+        if(inited)return
+        if(gradualShow){
+            player.on("flying.ended", updateArrow )  
+        }else{ 
+            //展示全部
+            for(let id1 in panos.routeNextMap){
+                for(let pano2 of panos.routeNextMap[id1]){ 
+                    updateArrowPose(panos.get(id1), pano2, mats.default) 
+                }  
+            } 
+            
+            player.on("mode.changed", ()=>{
+                if(hide)return
+                arrows.visible = player.mode == 'panorama'
+            })
+        }
+        opacityShine && updateArrowOpacity()
+        inited = true
+    }
+     
+    
+    {//ui控制显示
+        let changeShow = (e)=>{ 
+            hide = !e.show 
+            e.show && init()
+            gradualShow ? updateArrow() : (arrows.visible = e.show)
+        }
+        
+        player.on('changeArrowShow',changeShow) 
+        changeShow({show:!hide})
+    }
+    
+  }
+
   let f = () => {
     window.bus.removeEventListener('playerAndModelReady', f);
 
@@ -1606,6 +1891,8 @@ function initByTHREE(THREE) {
     });
 
     player.model.hotGroup.children.length ? logSth() : player.on('gotHotAndStartload', logSth);
+
+    initRouteArrow()
   };
   window.bus.addEventListener('playerAndModelReady', f); //player model currentPano都已有
 

二进制
src/assets/images/syjy/icon-zhanban-min.png


+ 1 - 1
src/views/home/components/menu/index.syjy.scss

@@ -154,7 +154,7 @@
     &.right {
       position: fixed;
       right: 8px;
-      top: 120px;
+      top: 12px;
       bottom: unset;
 
       &.playing {

+ 180 - 0
src/views/home/constants.syjy.ts

@@ -0,0 +1,180 @@
+export const data = [
+  { id: 98, path: [0] },
+  { id: 100, path: [0] },
+  { id: 97, path: [0] },
+  { id: 101, path: [0] },
+  { id: 102, path: [0] },
+  { id: 103, path: [0] },
+  { id: 104, path: [0] },
+  { id: 105, path: [0] },
+  { id: 99, path: [0] },
+  { id: 108, path: [1,0,0] },
+  { id: 109, path: [1,0,0] },
+  { id: 106, path: [1,0,1] },
+  { id: 107, path: [1,0,1] },
+  { id: 111, path: [1,0,2] },
+  { id: 112, path: [1,1,0] },
+  { id: 143, path: [1,1,0] },
+  { id: 144, path: [1,1,0] },
+  { id: 147, path: [1,1,1] },
+  { id: 148, path: [1,1,1] },
+  { id: 145, path: [1,2,0] },
+  { id: 146, path: [1,2,0] },
+  { id: 149, path: [1,2,0] },
+  { id: 150, path: [1,2,1] },
+  { id: 151, path: [1,2,1] },
+  { id: 152, path: [1,3,0] },
+  { id: 153, path: [1,3,0] },
+  { id: 154, path: [1,3,0] },
+  { id: 155, path: [1,3,1] },
+  { id: 156, path: [1,3,1] },
+  { id: 157, path: [1,3,1] },
+  { id: 158, path: [1,3,1] },
+  { id: 159, path: [1,3,1] },
+  { id: 161, path: [1,4,0] },
+  { id: 160, path: [1,4,0] },
+  { id: 165, path: [2,0,0] },
+  { id: 164, path: [2,0,0] },
+  { id: 163, path: [2,0,0] },
+  { id: 162, path: [2,0,0] },
+  { id: 166, path: [2,0,0] },
+  { id: 167, path: [2,0,0] },
+  { id: 171, path: [2,0,1] },
+  { id: 169, path: [2,1,0] },
+  { id: 168, path: [2,1,0] },
+  { id: 170, path: [2,1,0] },
+  { id: 172, path: [2,1,1] },
+  { id: 174, path: [2,1,1] },
+  { id: 173, path: [2,1,1] },
+  { id: 176, path: [2,2,0] },
+  { id: 177, path: [2,2,0] },
+  { id: 178, path: [2,2,0] },
+  { id: 175, path: [2,2,1] },
+  { id: 179, path: [2,2,1] },
+  { id: 180, path: [2,2,1] },
+  { id: 181, path: [2,2,1] },
+  { id: 182, path: [2,2,1] },
+  { id: 183, path: [2,2,1] },
+  { id: 184, path: [2,3,0] },
+  { id: 185, path: [2,3,0] },
+  { id: 186, path: [2,3,0] },
+  { id: 187, path: [2,3,0] },
+  { id: 142, path: [2,3,0] },
+  { id: 188, path: [2,3,0] },
+  { id: 92, path: [2,3,0] },
+  { id: 139, path: [2,3,1] },
+  { id: 141, path: [2,3,1] },
+  { id: 140, path: [2,3,1] },
+  { id: 91, path: [2,3,1] },
+  { id: 138, path: [2,3,1] },
+  { id: 137, path: [2,3,1] },
+  { id: 136, path: [2,3,1] },
+  { id: 135, path: [2,3,1] },
+  { id: 134, path: [2,4,0] },
+  { id: 133, path: [2,4,0] },
+  { id: 132, path: [2,4,0] },
+  { id: 90, path: [2,4,0] },
+  { id: 11, path: [3,0,0] },
+  { id: 1, path: [3,0,0] },
+  { id: 0, path: [3,0,0] },
+  { id: 10, path: [3,0,0] },
+  { id: 9, path: [3,0,0] },
+  { id: 8, path: [3,0,0] },
+  { id: 7, path: [3,0,0] },
+  { id: 6, path: [3,0,0] },
+  { id: 2, path: [3,0,0] },
+  { id: 3, path: [3,0,0] },
+  { id: 4, path: [3,0,0] },
+  { id: 12, path: [3,0,0] },
+  { id: 5, path: [3,0,0] },
+  { id: 17, path: [3,0,1] },
+  { id: 16, path: [3,0,1] },
+  { id: 15, path: [3,0,1] },
+  { id: 38, path: [3,1,0] },
+  { id: 40, path: [3,1,0] },
+  { id: 41, path: [3,1,0] },
+  { id: 14, path: [3,1,1] },
+  { id: 13, path: [3,1,1] },
+  { id: 18, path: [3,1,1] },
+  { id: 19, path: [3,1,1] },
+  { id: 20, path: [3,1,1] },
+  { id: 21, path: [3,2,0] },
+  { id: 22, path: [3,2,0] },
+  { id: 27, path: [3,2,0] },
+  { id: 23, path: [3,2,0] },
+  { id: 24, path: [3,2,0] },
+  { id: 28, path: [3,2,0] },
+  { id: 25, path: [3,2,0] },
+  { id: 33, path: [3,2,1] },
+  { id: 34, path: [3,2,1] },
+  { id: 35, path: [3,2,1] },
+  { id: 36, path: [3,2,1] },
+  { id: 37, path: [3,2,1] },
+  { id: 39, path: [3,2,1] },
+  { id: 47, path: [3,2,1] },
+  { id: 46, path: [3,2,1] },
+  { id: 45, path: [3,2,1] },
+  { id: 42, path: [3,3,0] },
+  { id: 43, path: [3,3,0] },
+  { id: 44, path: [3,3,0] },
+  { id: 29, path: [3,3,0] },
+  { id: 30, path: [3,3,0] },
+  { id: 32, path: [3,3,0] },
+  { id: 31, path: [3,4,0] },
+  { id: 48, path: [3,4,0] },
+  { id: 49, path: [3,4,0] },
+  { id: 50, path: [3,4,0] },
+  { id: 51, path: [3,4,0] },
+  { id: 53, path: [3,4,1] },
+  { id: 54, path: [3,4,1] },
+  { id: 52, path: [3,4,2] },
+  { id: 55, path: [3,4,2] },
+  { id: 56, path: [3,4,2] },
+  { id: 57, path: [3,4,2] },
+  { id: 58, path: [3,4,2] },
+  { id: 60, path: [3,5,0] },
+  { id: 59, path: [3,5,0] },
+  { id: 61, path: [3,5,1] },
+  { id: 62, path: [3,5,1] },
+  { id: 63, path: [4,0,0] },
+  { id: 67, path: [4,0,0] },
+  { id: 69, path: [4,0,0] },
+  { id: 68, path: [4,0,0] },
+  { id: 72, path: [4,0,0] },
+  { id: 70, path: [4,0,0] },
+  { id: 71, path: [4,0,0] },
+  { id: 73, path: [4,0,1] },
+  { id: 74, path: [4,0,1] },
+  { id: 75, path: [4,0,1] },
+  { id: 76, path: [4,0,1] },
+  { id: 77, path: [4,0,1] },
+  { id: 81, path: [4,0,1] },
+  { id: 66, path: [4,0,1] },
+  { id: 64, path: [4,1,0] },
+  { id: 65, path: [4,1,0] },
+  { id: 82, path: [4,1,0] },
+  { id: 84, path: [4,1,0] },
+  { id: 85, path: [4,1,0] },
+  { id: 86, path: [4,1,0] },
+  { id: 83, path: [4,1,0] },
+  { id: 87, path: [4,2,0] },
+  { id: 89, path: [4,2,0] },
+  { id: 88, path: [4,2,0] },
+  { id: 113, path: [4,2,0] },
+  { id: 114, path: [4,2,1] },
+  { id: 120, path: [4,2,1] },
+  { id: 115, path: [4,2,2] },
+  { id: 116, path: [4,2,2] },
+  { id: 117, path: [4,2,2] },
+  { id: 118, path: [4,2,2] },
+  { id: 119, path: [4,2,2] },
+  { id: 125, path: [4,3,0] },
+  { id: 126, path: [4,3,0] },
+  { id: 123, path: [4,3,1] },
+  { id: 124, path: [4,3,1] },
+  { id: 122, path: [4,3,2] },
+  { id: 121, path: [4,3,2] },
+  { id: 127, path: [4,3,3] },
+  { id: 131, path: [5] },
+  { id: 130, path: [6] },
+];

+ 15 - 0
src/views/home/index.syjy.scss

@@ -32,6 +32,15 @@
       border-bottom: 1px solid rgba(255, 255, 255, 0.8);
     }
   }
+  &__point {
+    position: absolute;
+    top: 30px;
+    right: 30px;
+    width: 50px;
+    height: 50px;
+    cursor: pointer;
+    z-index: 1;
+  }
 }
 
 #player {
@@ -113,6 +122,12 @@ div.cad {
       height: 35px;
       z-index: 1001;
     }
+    &__point {
+      top: 100px;
+      right: 7px;
+      width: 37px;
+      height: 37px;
+    }
   }
   div.cad {
     top: 20px;

+ 28 - 9
src/views/home/index.syjy.tsx

@@ -11,12 +11,14 @@ import Popup from './components/popup';
 import HotSpotList from './components/hot-spot-list';
 import BackIcon from '@/assets/images/syjy/icon-back-min.png';
 import useBaseStore from '@/store/module/base';
+import PointIcon from '@/assets/images/syjy/icon-zhanban-min.png';
+import { data } from './constants.syjy';
 import './index.syjy.scss';
 
 // @ts-ignore
 window.hoticon = {
-  default: '/images/syjy/icon-hot.png',
-  higt: '/images/syjy/icon-hot1-min.png',
+  default: './images/syjy/icon-hot.png',
+  higt: './images/syjy/icon-hot1-min.png',
 };
 
 export default defineComponent({
@@ -35,10 +37,25 @@ export default defineComponent({
     const manageJsLoaded = ref(false);
     const hotJsLoaded = ref(false);
 
+    const handlePoint = () => {
+      // @ts-ignore
+      const item = data.find((i) => i.id === Number(window.player.currentPano.id));
+
+      const isMobileDevice = window.browser.isMobile();
+      const currentPath = window.location.pathname;
+
+      window.location.href =
+        currentPath.replace(
+          '/scene/syjy.html',
+          `${isMobileDevice ? '/mobile/index.html' : '/pc/index.html'}`
+        ) + `#exhibition/?path=${item.path.join(',')}`;
+    };
+
     return {
       manageJsLoaded,
       hotJsLoaded,
       baseStore,
+      handlePoint,
     };
   },
   render() {
@@ -56,6 +73,8 @@ export default defineComponent({
           }}
         />
 
+        <img src={PointIcon} class="home__point" onClick={this.handlePoint} />
+
         {/* 进度条加载 */}
         <GuiLoading />
 
@@ -95,7 +114,7 @@ export default defineComponent({
 
         {/* TODO: 没有控制权,耦合严重;放在此处为了防止元素未渲染导致报错 */}
         <JsScript
-          src="/js/manage.js"
+          src="./js/manage.js"
           onLoad={() => {
             this.manageJsLoaded = true;
             this.baseStore.handleJSLoaded('manageJsLoaded');
@@ -104,7 +123,7 @@ export default defineComponent({
         {this.manageJsLoaded && (
           <div>
             <JsScript
-              src="/js/Hot.js"
+              src="./js/Hot.js"
               onLoad={() => {
                 this.hotJsLoaded = true;
                 this.baseStore.handleJSLoaded('hotJsLoaded');
@@ -112,12 +131,12 @@ export default defineComponent({
             />
             {this.hotJsLoaded && (
               <div>
-                <JsScript src="/js/main_2020_show.js" />
+                <JsScript src="./js/main_2020_show.js" />
                 {/* 延迟加载 */}
-                <JsScript src="/js/lib/player-0.0.12.min.js" />
-                <JsScript src="/js/lib/Tween.js" />
-                <JsScript src="/js/SpecialScene.js" />
-                <JsScript src="/js/loadCAD.js" />
+                <JsScript src="./js/lib/player-0.0.12.min.js" />
+                <JsScript src="./js/lib/Tween.js" />
+                <JsScript src="./js/SpecialScene.js" />
+                <JsScript src="./js/loadCAD.js" />
               </div>
             )}
           </div>