Pārlūkot izejas kodu

增加大地图功能

任一存 2 gadi atpakaļ
vecāks
revīzija
27fbd392bf

+ 24 - 2
.eslintrc.js

@@ -4,7 +4,7 @@ module.exports = {
     node: true
   },
   'extends': [
-    'plugin:vue/essential',
+    'plugin:vue/recommended',
     'eslint:recommended'
   ],
   parserOptions: {
@@ -12,6 +12,28 @@ module.exports = {
   },
   rules: {
     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
-    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'semi': ['error', 'never'],
+    "no-unused-vars": ["warn", {
+      "vars": "all",
+      "args": "after-used",
+      "ignoreRestSiblings": false
+    }],
+    "keyword-spacing": ["error", { "before": true, "after": true }],
+    "object-curly-spacing": ["error", "always"],
+    "space-infix-ops": ["error"],
+    'key-spacing': ["error", {
+      "mode": "strict"
+    }],
+    "comma-spacing": ["error", { "before": false, "after": true }],
+    "func-call-spacing": ["error", "never"],
+    "semi-spacing": ["error", { "before": false, "after": true }],
+    "space-before-blocks": ["error", "always"],
+    'no-trailing-spaces': 'error',
+    'no-multi-spaces': 'error',
+    "indent": ["error", 2],
+    'no-empty': 'off',
+    // 默认不启用:为了避免细微的 bug,最好直接从 Object.prototype 调用挂载于prototype上的方法方法。例如,foo.hasOwnProperty("bar") 应该替换为 Object.prototype.hasOwnProperty.call(foo, "bar")。
+    'no-prototype-builtins': "off",
   }
 }

BIN
src/assets/images/big-map.jpg


BIN
src/assets/images/big-map.png


BIN
src/assets/images/close.png


+ 81 - 37
src/pages/Home.vue

@@ -1,26 +1,50 @@
 <template>
-  <div class="parent-body"
-    @click="musicPlay" @touchstart="musicPlay"
+  <div
+    class="parent-body"
+    @click="musicPlay"
+    @touchstart="musicPlay"
   >
     <!-- 热点弹出框 -->
     <popup />
     <!-- 加载初始页面——看来也没什么卵用 -->
-    <div id="gui-thumb"></div>
+    <div id="gui-thumb" />
 
     <!-- 场景canvs主容器 -->
-    <div id="player"></div>
-
-    <MiniMapDecorator class="mini-map-decorator"></MiniMapDecorator>
+    <div id="player" />
+
+    <MiniMapDecorator class="mini-map-decorator" />
+    <button
+      class="big-map"
+      @click="isShowBigMap = true"
+    >
+      <img
+        class=""
+        src="@/assets/images/floor.png"
+        alt=""
+        draggable="false"
+      >
+    </button>
+    <BigMap
+      v-show="isShowBigMap"
+      @close="isShowBigMap = false"
+    />
 
     <!-- 底部菜单 -->
     <div id="gui-parent">
       <!-- 进度条加载 -->
       <gui-loading />
-      <div id="hot"></div>
-      <div id="gui" style="display: none">
+      <div id="hot" />
+      <div
+        id="gui"
+        style="display: none"
+      >
         <!-- 退出VR模式按钮 -->
         <div id="vrOff">
-          <img id="vrOffImg" src="@/assets/images/vrOffImg.png" alt="" />
+          <img
+            id="vrOffImg"
+            src="@/assets/images/vrOffImg.png"
+            alt=""
+          >
         </div>
 
         <!-- 热点列表 -->
@@ -79,25 +103,25 @@
       <vr-con />
 
       <v-other />
-
     </div>
   </div>
 </template>
 
 <script>
-import popup from "@/views/popup";
-import guiLoading from "@/views/gui/loading";
-import hotspotList from "@/views/gui/hotspotlist";
-import vTitle from "@/views/gui/title";
-import vMenu from "@/views/gui/menu";
-import vGuide from "@/views/gui/guide";
-import webVr from "@/views/gui/webvr";
-import guimsg from "@/views/gui/guimsg";
-import vError from "@/views/gui/error";
-import vrCon from "@/views/gui/vrcon";
-import vOther from "@/views/gui/other";
-import MiniMapDecorator from "@/views/gui/MiniMapDecorator.vue";
-import ModeSelectorMobile from "@/views/gui/ModeSelectorMobile.vue";
+import popup from "@/views/popup"
+import guiLoading from "@/views/gui/loading"
+import hotspotList from "@/views/gui/hotspotlist"
+import vTitle from "@/views/gui/title"
+import vMenu from "@/views/gui/menu"
+import vGuide from "@/views/gui/guide"
+import webVr from "@/views/gui/webvr"
+import guimsg from "@/views/gui/guimsg"
+import vError from "@/views/gui/error"
+import vrCon from "@/views/gui/vrcon"
+import vOther from "@/views/gui/other"
+import MiniMapDecorator from "@/views/gui/MiniMapDecorator.vue"
+import ModeSelectorMobile from "@/views/gui/ModeSelectorMobile.vue"
+import BigMap from "@/views/gui/BigMap.vue"
 
 export default {
   name: "Home",
@@ -115,6 +139,7 @@ export default {
     vOther,
     MiniMapDecorator,
     ModeSelectorMobile,
+    BigMap,
   },
 
   data() {
@@ -122,15 +147,8 @@ export default {
       hotspots: "",
       // 控制背景音乐
       isMusicInitiallyPlayed: false,
-    };
-  },
-
-  methods: {
-    // 控制背景音乐播放
-    musicPlay() {
-      if (!this.isMusicInitiallyPlayed) window.manage.switchBgmState(true);
-      this.isMusicInitiallyPlayed = true;
-    },
+      isShowBigMap: false,
+    }
   },
 
   mounted() {
@@ -144,19 +162,39 @@ export default {
     ) {
       // 移动端
       if (window.location.href.includes("web")) {
-        window.location.href = window.location.href.replace("web", "webM");
+        window.location.href = window.location.href.replace("web", "webM")
         setTimeout(() => {
-          location.reload(true);
-        }, 1000);
+          location.reload(true)
+        }, 1000)
       }
-    } 
+    }
+  },
+
+  methods: {
+    // 控制背景音乐播放
+    musicPlay() {
+      if (!this.isMusicInitiallyPlayed) window.manage.switchBgmState(true)
+      this.isMusicInitiallyPlayed = true
+    },
   },
-};
+}
 </script>
 
 <style lang="less" scoped>
 .mini-map-decorator {
 }
+button.big-map {
+  position: absolute;
+  top: 190px;
+  right: 30px;
+  z-index: 9998;
+  width: 50px;
+  height: 50px;
+}
+.mobile {
+  button.big-map {
+  }
+}
 
 .parent-body {
   position: relative;
@@ -195,10 +233,16 @@ export default {
   .mini-map-decorator {
     display: none;
   }
+  .button.big-map {
+    display: none;
+  }
 }
 .mobile[view-mode='panorama'], .mobile[view-mode='outside'] {
   .mode-selector-mobile {
     display: none;
   }
+  .button.big-map {
+    display: none;
+  }
 }
 </style>

+ 201 - 0
src/views/gui/BigMap.vue

@@ -0,0 +1,201 @@
+<template>
+  <div class="big-map">
+    <button
+      class="close"
+      @click="$emit('close')"
+    >
+      <img
+        class=""
+        src="@/assets/images/close.png"
+        alt=""
+        draggable="false"
+      >
+    </button>
+    <div class="map-wrapper">
+      <img
+        class="map"
+        src="@/assets/images/big-map.jpg"
+        alt=""
+        draggable="false"
+      >
+      <div
+        class="area-zhong-da-gong-cheng"
+        @click="onClickArea('1308')"
+      />
+      <div
+        class="area-yue-lan-shi"
+        @click="onClickArea('1302')"
+      />
+      <div
+        class="area-dian-xing-ren-wu-ting"
+        @click="onClickArea('1310')"
+      />
+      <div
+        class="area-ying-xiang-ting"
+        @click="onClickArea('1307')"
+      />
+      <div
+        class="area-fa-zhan-li-cheng-ting"
+        @click="onClickArea('1300')"
+      />
+      <div
+        class="area-xu-ting"
+        @click="onClickArea('1294')"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      targetSceneCode: '',
+    }
+  },
+  beforeDestroy() {
+    window.addEventListener('message', this.onMsg, false)
+  },
+  methods: {
+    onMsg(msg) {
+      console.log('message received!', msg)
+      window.removeEventListener('message', this.onMsg, false)
+      if (msg.data === 'quiz over') {
+        // 跳转到新场景
+        const newLocation = location.href.split('?')[0] + `?m=${this.targetSceneCode}`
+        location.assign(newLocation)
+        location.reload(true)
+      }
+    },
+    onClickArea(targetSceneCode) {
+      // 注意,因为网站用了vue router, url里看上去像是查询片段的那一段其实是放在hash片段中的。
+      const currentLocationQuerySection = new URLSearchParams(location.href.split('?')[1])
+      const currentSceneCode = currentLocationQuerySection.get('m')
+
+      if (currentSceneCode === '1300' && targetSceneCode === '1302') {
+        const iframeElem = document.createElement('iframe')
+        iframeElem.style.position = 'absolute'
+        iframeElem.style.top = '50%'
+        iframeElem.style.left = '50%'
+        iframeElem.style.width = '600px'
+        iframeElem.style.height = '800px'
+        iframeElem.style.transform = 'translate(-50%, -50%)'
+        iframeElem.style.zIndex = '9999'
+        iframeElem.style.boxShadow = '0 0 0 1000px rgba(0, 0, 0, 0.85)'
+        // iframeElem.src = 'http://192.168.20.16:8081/#/topic'
+        iframeElem.src = '../quiz/index.html#/topic'
+        document.documentElement.appendChild(iframeElem)
+
+        this.targetSceneCode = targetSceneCode
+        window.addEventListener('message', this.onMsg, false)
+      } else {
+        // 跳转到新场景
+        const newLocation = location.href.split('?')[0] + `?m=${targetSceneCode}`
+        location.assign(newLocation)
+        location.reload(true)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.big-map {
+  position: absolute;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 10000;
+  background: rgba(0, 0, 0, 0.5);
+  backdrop-filter: blur(10px);
+  > button.close {
+    position: absolute;
+    top: 20px;
+    right: 20px;
+    width: 60px;
+    height: 60px;
+    > img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  > .map-wrapper {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    > img.map {
+      width: 700px;
+      height: auto;
+    }
+    > .area-zhong-da-gong-cheng {
+      position: absolute;
+      left: 28%;
+      top: 5%;
+      width: 44%;
+      height: 20%;
+      cursor: pointer;
+    }
+    > .area-yue-lan-shi {
+      position: absolute;
+      left: 16%;
+      top: 26%;
+      width: 22%;
+      height: 25%;
+      cursor: pointer;
+    }
+    > .area-dian-xing-ren-wu-ting {
+      position: absolute;
+      left: 39%;
+      top: 26%;
+      width: 22%;
+      height: 25%;
+      cursor: pointer;
+    }
+    > .area-ying-xiang-ting {
+      position: absolute;
+      left: 61.5%;
+      top: 26%;
+      width: 22%;
+      height: 25%;
+      cursor: pointer;
+    }
+    > .area-fa-zhan-li-cheng-ting {
+      position: absolute;
+      left: 21%;
+      top: 54%;
+      width: 58%;
+      height: 20%;
+      cursor: pointer;
+    }
+    > .area-xu-ting {
+      position: absolute;
+      left: 33%;
+      top: 75%;
+      width: 34%;
+      height: 17%;
+      cursor: pointer;
+    }
+  }
+}
+
+.mobile {
+  .big-map {
+    > button.close {
+      top: 10px;
+      right: 10px;
+      width: 50px;
+      height: 50px;
+      > img {
+      }
+    }
+    > .map-wrapper {
+      > img.map {
+        width: 95vw;
+        height: auto;
+      }
+    }
+  }
+}
+</style>