chenlei 1 rok pred
rodič
commit
a25c760dd2
57 zmenil súbory, kde vykonal 541 pridanie a 280 odobranie
  1. 118 118
      public/relic-data/data.json
  2. 1 0
      src/App.vue
  3. BIN
      src/assets/audios/follow-me.mp3
  4. BIN
      src/assets/audios/follow-me2.mp3
  5. BIN
      src/assets/audios/follow-me3.mp3
  6. BIN
      src/assets/audios/gogogo.mp3
  7. BIN
      src/assets/audios/scene-1-msg-1.mp3
  8. BIN
      src/assets/audios/scene-1-msg-2.mp3
  9. BIN
      src/assets/audios/scene-1-msg-3.mp3
  10. BIN
      src/assets/audios/scene-2-msg-1.mp3
  11. BIN
      src/assets/audios/scene-2-msg-2.mp3
  12. BIN
      src/assets/audios/scene-2-msg-3.mp3
  13. BIN
      src/assets/audios/scene-3-msg-1.mp3
  14. BIN
      src/assets/audios/scene-3-msg-2.mp3
  15. BIN
      src/assets/audios/scene-bg-2-3.mp3
  16. BIN
      src/assets/images/1331-min.jpg
  17. BIN
      src/assets/images/1332-min.jpg
  18. BIN
      src/assets/images/box_2-min.png
  19. BIN
      src/assets/images/camera-content-1-3-3-content.png
  20. BIN
      src/assets/images/camera-content-2-1-3-tab-1-table.png
  21. BIN
      src/assets/images/camera-content-2-3-1-img-2.png
  22. BIN
      src/assets/images/scene-entry-1.png
  23. BIN
      src/assets/videos/camera-content-1-2-3.mp4
  24. BIN
      src/assets/videos/start-up-video.mp4
  25. 38 24
      src/components/CameraContent-1-1-1.vue
  26. 6 2
      src/components/CameraContent-1-1-2.vue
  27. 2 1
      src/components/CameraContent-1-1-3.vue
  28. 3 3
      src/components/CameraContent-1-2-1.vue
  29. 13 6
      src/components/CameraContent-1-2-2.vue
  30. 4 0
      src/components/CameraContent-1-3-1.vue
  31. 2 2
      src/components/CameraContent-1-3-2.vue
  32. 90 7
      src/components/CameraContent-1-3-3.vue
  33. 3 2
      src/components/CameraContent-2-1-1.vue
  34. 6 4
      src/components/CameraContent-2-1-2.vue
  35. 12 5
      src/components/CameraContent-2-1-3.vue
  36. 3 3
      src/components/CameraContent-2-2-1.vue
  37. 4 4
      src/components/CameraContent-2-2-2.vue
  38. 2 2
      src/components/CameraContent-2-2-3.vue
  39. 9 7
      src/components/CameraContent-2-3-1.vue
  40. 24 12
      src/components/CameraContent-2-3-2.vue
  41. 2 2
      src/components/CameraContent-2-3-3.vue
  42. 8 4
      src/components/CameraContent-3-1-1.vue
  43. 8 1
      src/components/CameraContent-3-1-2.vue
  44. 17 8
      src/components/CameraContent-3-1-3.vue
  45. 7 3
      src/components/CameraContent-3-2-1.vue
  46. 2 2
      src/components/CameraContent-3-2-2.vue
  47. 3 2
      src/components/CameraContent-3-2-3.vue
  48. 1 1
      src/components/CharacterDesc.vue
  49. 6 7
      src/components/HotspotDialog-1.vue
  50. 25 9
      src/components/RelicDetailForHotspot.vue
  51. 1 1
      src/components/UserGuide.vue
  52. 6 2
      src/useFunctions/useSmoothSwipe.js
  53. 8 3
      src/views/EpilogueView.vue
  54. 5 6
      src/views/HomeView.vue
  55. 55 19
      src/views/PanoView.vue
  56. 12 6
      src/views/RelicDetail.vue
  57. 35 2
      src/views/RelicList.vue

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 118 - 118
public/relic-data/data.json


+ 1 - 0
src/App.vue

@@ -27,6 +27,7 @@ let bgAudio = null
 let curBgAudio = ''
 
 const handleBgAudio = ({ sceneIdx, cameraIdx, canPlay }) => {
+  console.log(sceneIdx, cameraIdx)
   if (`${sceneIdx}-${cameraIdx}` === curBgAudio) return
 
   bgAudio?.pause()

BIN
src/assets/audios/follow-me.mp3


BIN
src/assets/audios/follow-me2.mp3


BIN
src/assets/audios/follow-me3.mp3


BIN
src/assets/audios/gogogo.mp3


BIN
src/assets/audios/scene-1-msg-1.mp3


BIN
src/assets/audios/scene-1-msg-2.mp3


BIN
src/assets/audios/scene-1-msg-3.mp3


BIN
src/assets/audios/scene-2-msg-1.mp3


BIN
src/assets/audios/scene-2-msg-2.mp3


BIN
src/assets/audios/scene-2-msg-3.mp3


BIN
src/assets/audios/scene-3-msg-1.mp3


BIN
src/assets/audios/scene-3-msg-2.mp3


BIN
src/assets/audios/scene-bg-2-3.mp3


BIN
src/assets/images/1331-min.jpg


BIN
src/assets/images/1332-min.jpg


BIN
src/assets/images/box_2-min.png


BIN
src/assets/images/camera-content-1-3-3-content.png


BIN
src/assets/images/camera-content-2-1-3-tab-1-table.png


BIN
src/assets/images/camera-content-2-3-1-img-2.png


BIN
src/assets/images/scene-entry-1.png


BIN
src/assets/videos/camera-content-1-2-3.mp4


BIN
src/assets/videos/start-up-video.mp4


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 38 - 24
src/components/CameraContent-1-1-1.vue


+ 6 - 2
src/components/CameraContent-1-1-2.vue

@@ -154,10 +154,14 @@ const tab1ContentPageNumber = ref(1)
         display: flex;
         justify-content: center;
         align-items: center;
+        color: #FFF3C3;
         background: #AC997F;
+        font-size: 18px;
+        letter-spacing: 8px;
         box-shadow: 3px 4px 9px 0px rgba(0,0,0,0.25);
       }
       >button.active{
+        color: #43310E;
         background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
       }
       >.splitter{
@@ -190,7 +194,7 @@ const tab1ContentPageNumber = ref(1)
         font-weight: 300;
         color: #000000;
         line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-right: 0.5em;
       }
       >div.table{
@@ -259,7 +263,7 @@ const tab1ContentPageNumber = ref(1)
         font-weight: 300;
         color: #000000;
         line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >img{
         width: calc(818 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 2 - 1
src/components/CameraContent-1-1-3.vue

@@ -114,7 +114,8 @@ const emit = defineEmits(['close'])
         font-weight: 300;
         color: #000000;
         line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        text-align: justify;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >p.one{
         margin-bottom: calc(50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 3 - 3
src/components/CameraContent-1-2-1.vue


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 13 - 6
src/components/CameraContent-1-2-2.vue


+ 4 - 0
src/components/CameraContent-1-3-1.vue

@@ -129,10 +129,14 @@ const activeTabIdx = ref(1)
         display: flex;
         justify-content: center;
         align-items: center;
+        color: #FFF3C3;
         background: #AC997F;
+        font-size: 19px;
+        letter-spacing: 8px;
         box-shadow: 3px 4px 9px 0px rgba(0,0,0,0.25);
       }
       >button.active{
+        color: #6A3906;
         background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
       }
       >.splitter{

+ 2 - 2
src/components/CameraContent-1-3-2.vue

@@ -280,8 +280,8 @@ const displayingHotspotIdx = ref(0)
             font-family: Source Han Sans SC, Source Han Sans SC;
             font-weight: 300;
             color: #000000;
-            line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-            letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           }
         }
       }

+ 90 - 7
src/components/CameraContent-1-3-3.vue

@@ -13,25 +13,65 @@
         draggable="false"
       >
     </div>
+    <div class="design-wrap-right">
+      <!-- 左右按钮 -->
+      <img
+        class="btn-left"
+        src="@/assets/images/CameraContent-3-1-3-left.png"
+        alt=""
+        :style="{opacity: currentSwitchIdx == 0 ? '0.4':'1'}"
+        @click="previous()"
+      >
+      <img
+        class="btn-right"
+        src="@/assets/images/CameraContent-3-1-3-right.png"
+        alt=""
+        :style="{opacity: currentSwitchIdx == imgLists.length - 1 ? '0.4':'1'}"
+        @click="next()"
+      >
+      <img
+        class="detail-img"
+        draggable="false"
+        :src="require(`@/assets/images/133${currentSwitchIdx + 1}-min.jpg`)"
+        alt=""
+      >
+    </div>
   </div>
 </template>
 
 <script setup>
-import { ref, computed, watch, onMounted } from "vue"
-import { useRoute, useRouter } from "vue-router"
-import { useStore } from "vuex"
+import { ref } from "vue"
 
 const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
 } = useSizeAdapt(1920, 970)
 
-const route = useRoute()
-const router = useRouter()
-const store = useStore()
-
 const emit = defineEmits(['close'])
+const currentSwitchIdx = ref(0)
+const imgLists = [
+  '@/assets/images/1331-min.png',
+  '@/assets/images/1332-min.jpeg',
+]
 
+const previous = () => {
+  console.log('上一页', currentSwitchIdx.value)
+  if (currentSwitchIdx.value > 0 ) {
+    console.log('上一页2')
+    currentSwitchIdx.value -= 1
+  } else {
+    return
+  }
+}
+
+const next = () => {
+  console.log('下一页')
+  if (currentSwitchIdx.value < imgLists.length - 1) {
+    currentSwitchIdx.value += 1
+  } else {
+    return
+  }
+}
 </script>
 
 <style lang="less" scoped>
@@ -72,5 +112,48 @@ const emit = defineEmits(['close'])
       width: 90%;
     }
   }
+  .design-wrap-right {
+    width: calc(880 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(550 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    background: rgba(145,129,117,0.25);
+    border: 1px solid #FFE88B;
+    padding: 15px 10px;
+    position: absolute;
+    top: calc(250 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    right: calc(100 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    >.btn-left {
+      width: 60px;
+      height: 60px;
+      position: absolute;
+      left: -30px;
+      top: 50%;
+      transform: translateY(-50%);
+      z-index: 2;
+      cursor: pointer;
+    }
+    >.btn-right {
+      width: 60px;
+      height: 60px;
+      position: absolute;
+      right: -30px;
+      top: 50%;
+      transform: translateY(-50%);
+      z-index: 2;
+      cursor: pointer;
+    }
+    .btn-left,
+    .btn-right {
+      transition: all linear .2s;
+
+      &:hover {
+        transform: translateY(-50%) scale(1.2);
+      }
+    }
+    >.detail-img {
+      width: 100%;
+      height: 100%;
+      object-fit: cover;
+    }
+  }
 }
 </style>

+ 3 - 2
src/components/CameraContent-2-1-1.vue

@@ -33,7 +33,7 @@
             class="content-box"
           >
             <div class="title">
-              第一次全线贯通:隋唐大运河
+              第一次全线贯通:隋唐大运河
             </div>
             <div
               class="content text-indent"
@@ -240,7 +240,8 @@ const title = '大运河的历史演变'
             font-size: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           }
           >.content {
-            letter-spacing: 0.2em;
+            // letter-spacing: 0.2em;
+            font-size: 18px;
             line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           }
         }

+ 6 - 4
src/components/CameraContent-2-1-2.vue

@@ -186,13 +186,15 @@ const next = () => {
           padding-top: calc(7 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         }
         >.left-text {
-          font-family: 'SourceHanSansSC-Normal';
+          // font-family: 'SourceHanSansSC-Normal';
           margin-top: 25px;
           height: calc(300 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           overflow: auto;
-          font-family: 'SourceHanSansSC-Normal';
-          letter-spacing: 3px;
-          line-height: 25px;
+          // font-family: 'SourceHanSansSC-Normal';
+          // letter-spacing: 3px;
+          font-size: 18px;
+          line-height: 30px;
+          font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           >strong {
             color: #000000;
             font-family: 'SourceHanSansSC-Bold';

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 12 - 5
src/components/CameraContent-2-1-3.vue


+ 3 - 3
src/components/CameraContent-2-2-1.vue

@@ -111,11 +111,11 @@ const emit = defineEmits(['close'])
       }
       >p{
         font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        font-family: Source Han Sans CN, Source Han Sans CN;
+        // font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >p.one{
         margin-bottom: calc(50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 4 - 4
src/components/CameraContent-2-2-2.vue

@@ -11,7 +11,7 @@
           磁县漕船
         </h2>
         <p class="one text-indent">
-          1975年河北磁县漳河故道附近出土了六只元船,有的船的尾部还烫有“漳河分省粮船”等字。六条船都已残破,但仍可看出方头平底,分为数舱。其中最大的五号船,残长16.6米,十一舱,也是平衡舵。
+          元末运粮官船,1975年河北磁县漳河故道附近出土,共六艘,有的船的尾部还烫有“漳河分省粮船”等字。六条船都已残破,但仍可看出方头平底,分为数舱。其中最大的五号船,残长16.6米,十一舱,也是平衡舵。
         </p>
       </div>
       <div class="right">
@@ -105,11 +105,11 @@ const emit = defineEmits(['close'])
       }
       >p{
         font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        font-family: Source Han Sans CN, Source Han Sans CN;
+        // font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >p.one{
         margin-bottom: calc(50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 2 - 2
src/components/CameraContent-2-2-3.vue

@@ -114,8 +114,8 @@ const emit = defineEmits(['close'])
         font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >p.one{
         margin-bottom: calc(50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 9 - 7
src/components/CameraContent-2-3-1.vue


+ 24 - 12
src/components/CameraContent-2-3-2.vue

@@ -16,7 +16,7 @@
         >
           总述
         </button>
-        <div class="splitter" />
+        <!-- <div class="splitter" /> -->
         <button
           :class="{
             active: activeTabIdx === 2
@@ -25,7 +25,7 @@
         >
           景德镇窑瓷器
         </button>
-        <div class="splitter" />
+        <!-- <div class="splitter" /> -->
         <button
           :class="{
             active: activeTabIdx === 3
@@ -34,7 +34,7 @@
         >
           龙泉窑瓷器
         </button>
-        <div class="splitter" />
+        <!-- <div class="splitter" /> -->
         <button
           :class="{
             active: activeTabIdx === 4
@@ -43,7 +43,7 @@
         >
           磁州窑瓷器
         </button>
-        <div class="splitter" />
+        <!-- <div class="splitter" /> -->
         <button
           :class="{
             active: activeTabIdx === 5
@@ -61,15 +61,23 @@
           class="table1"
         >
           <h3>元王朝在景德镇设置的全国唯一的一所为皇室服务的磁局</h3>
-          <div class="content text-indent">
+          <div
+            class="content text-indent"
+          >
             <p>
               元代在景德镇专设浮梁磁局,负责为宫廷、官府督造瓷器事宜,极大促进了景德镇制瓷业的发展。浮梁磁局是元王朝在景德镇设置的全国唯一的一所为皇室服务的磁局,秩正九品,至元十五年(1278年)立。掌烧造瓷器,并漆造马尾、棕藤笠帽等事。大使、副使各一员。 在磁局的掌管下创烧了枢府釉瓷、青花、釉里红、蓝釉、蓝地白花、孔雀蓝釉瓷器等。
             </p>
-            <div class="img-box">
+            <div
+              class="img-box"
+              style="position: relative;"
+            >
               <img
                 src="@/assets/images/camera-content-2-3-2-tab-1-img.png"
                 alt=""
               >
+              <p style="position:absolute;left:0;right: 0;text-align:center;bottom:-25px;color: #666; text-indent: 0;">
+                浮梁古城
+              </p>
             </div>
           </div>
         </div>
@@ -211,10 +219,14 @@ const activeTabIdx = ref(1)
         justify-content: center;
         align-items: center;
         background: #AC997F;
+        color: #FFF3C3;
+        font-size: 19px;
+        letter-spacing: 1px;
         box-shadow: 3px 4px 9px 0px rgba(0, 0, 0, 0.25);
       }
 
       >button.active {
+        color: #6A3906;
         background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
       }
 
@@ -264,11 +276,11 @@ const activeTabIdx = ref(1)
             max-height: 70%;
             overflow: auto;
             font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-            font-family: Source Han Sans SC, Source Han Sans SC;
+            // font-family: Source Han Sans SC, Source Han Sans SC;
             font-weight: 300;
             color: #000000;
             line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-            letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
             padding-right: 0.5em;
             margin-left: 10px;
           }
@@ -389,13 +401,13 @@ const activeTabIdx = ref(1)
       >p {
         width: calc(400 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         max-height: calc(650 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        overflow: auto;
+        // overflow: auto;
         font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        font-family: Source Han Sans CN, Source Han Sans CN;
+        // font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.2;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
 
       >img {

+ 2 - 2
src/components/CameraContent-2-3-3.vue

@@ -108,8 +108,8 @@ const emit = defineEmits(['close'])
         font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >p.one{
         margin-bottom: calc(50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 8 - 4
src/components/CameraContent-3-1-1.vue

@@ -148,9 +148,13 @@ const activeTabIdx = ref(1)
         justify-content: center;
         align-items: center;
         background: #AC997F;
+        font-size: 19px;
+        color: #FFF3C3;
+        letter-spacing: 1px;
         box-shadow: 3px 4px 9px 0px rgba(0,0,0,0.25);
       }
       >button.active{
+        color: #6A3906;
         background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
       }
       >.splitter{
@@ -199,11 +203,11 @@ const activeTabIdx = ref(1)
         max-height: 80%;
         overflow: auto;
         font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        font-family: Source Han Sans SC, Source Han Sans SC;
+        // font-family: Source Han Sans SC, Source Han Sans SC;
         font-weight: 300;
         color: #000000;
         line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-right: 0.5em;
       }
       >div.table{
@@ -271,8 +275,8 @@ const activeTabIdx = ref(1)
         font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >img{
         width: calc(818 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 8 - 1
src/components/CameraContent-3-1-2.vue

@@ -190,9 +190,16 @@ const activeTabIdx = ref(1)
         justify-content: center;
         align-items: center;
         background: #AC997F;
+        font-size: 19px;
+        color: #FFF3C3;
+        letter-spacing: 1px;
         box-shadow: 3px 4px 9px 0px rgba(0,0,0,0.25);
       }
       >button.active{
+        color: #6A3906;
+        background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
+      }
+      >button.active{
         background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
       }
       >.splitter{
@@ -248,7 +255,7 @@ const activeTabIdx = ref(1)
         font-weight: 300;
         color: #000000;
         line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-right: 0.5em;
       }
       >div.table{

+ 17 - 8
src/components/CameraContent-3-1-3.vue

@@ -230,8 +230,9 @@ const next = () => {
           height: calc(300 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           overflow: auto;
           font-family: 'SourceHanSansSC-Normal';
-          letter-spacing: 3px;
-          line-height: 25px;
+          // letter-spacing: 3px;
+          line-height: 30px;
+          font-size: 20px;
           >strong {
             color: #000000;
             font-family: 'SourceHanSansSC-Bold';
@@ -247,25 +248,33 @@ const next = () => {
         padding: 15px 10px;
         position: relative;
         >.btn-left {
-          width: 50px;
-          height: 50px;
+          width: 60px;
+          height: 60px;
           position: absolute;
-          left: -25px;
+          left: -30px;
           top: 50%;
           transform: translateY(-50%);
           z-index: 2;
           cursor: pointer;
         }
         >.btn-right {
-          width: 50px;
-          height: 50px;
+          width: 60px;
+          height: 60px;
           position: absolute;
-          right: -25px;
+          right: -30px;
           top: 50%;
           transform: translateY(-50%);
           z-index: 2;
           cursor: pointer;
         }
+        .btn-left,
+        .btn-right {
+          transition: all linear .2s;
+
+          &:hover {
+            transform: translateY(-50%) scale(1.2);
+          }
+        }
         >.detail-img {
           width: 100%;
         }

+ 7 - 3
src/components/CameraContent-3-2-1.vue

@@ -150,9 +150,13 @@ const activeTabIdx = ref(1)
         justify-content: center;
         align-items: center;
         background: #AC997F;
+        font-size: 19px;
+        color: #FFF3C3;
+        letter-spacing: 1px;
         box-shadow: 3px 4px 9px 0px rgba(0,0,0,0.25);
       }
       >button.active{
+        color: #6A3906;
         background: linear-gradient(322deg, #C69D49 0%, #F8E6A9 68%);
       }
       >.splitter{
@@ -206,7 +210,7 @@ const activeTabIdx = ref(1)
         font-weight: 300;
         color: #000000;
         line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // letter-spacing: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-right: 0.5em;
       }
       >div.table{
@@ -274,8 +278,8 @@ const activeTabIdx = ref(1)
         font-family: Source Han Sans CN, Source Han Sans CN;
         font-weight: 300;
         color: #000000;
-        line-height: 1.5;
-        letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        line-height: 30px;
+        // letter-spacing: calc(8 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       >img{
         width: calc(818 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 2 - 2
src/components/CameraContent-3-2-2.vue

@@ -196,8 +196,8 @@ const next = () => {
           height: calc(300 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           overflow: auto;
           font-family: 'SourceHanSansSC-Normal';
-          letter-spacing: 3px;
-          line-height: 25px;
+          // letter-spacing: 3px;
+          line-height: 30px;
           >strong {
             color: #000000;
             font-family: 'SourceHanSansSC-Bold';

+ 3 - 2
src/components/CameraContent-3-2-3.vue

@@ -218,8 +218,9 @@ const title = '表演元曲的著名演员'
           max-width: 80%;
           max-height: 90%;
           overflow: auto;
-          letter-spacing: 0.3em;
-          line-height: calc(26 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          font-size: 20px;
+          // letter-spacing: 0.3em;
+          line-height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         }
       }
     }

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 1
src/components/CharacterDesc.vue


+ 6 - 7
src/components/HotspotDialog-1.vue

@@ -493,6 +493,7 @@
     </template>
 
     <MsgContent
+      v-if="currentMsg.length"
       v-model:curIndex="curMsgIndex"
       :list="currentMsg"
     />
@@ -539,7 +540,7 @@ const sszDetailVisbile = ref(false)
 const openedBoxList = reactive([])
 
 // 曲苑
-const isQY = computed(() => ['_aiFVUNh3', '_t86XauFR'].includes(props.relicInfo.name))
+const isQY = computed(() => ['_niQSUEYt'].includes(props.relicInfo.name))
 // 河畅
 const isHC = computed(() => ['_Kd6Z3CsH'].includes(props.relicInfo.name))
 // 航运
@@ -602,7 +603,7 @@ const currentMsg = computed(() => {
     // }
 
     return [
-      '通惠河是元代挖建的漕运河道,由郭守敬主持修建。于至元二十九年(1292)春天动工,至元三十年(1293)工程完成,总长 164 里,沿河设坝闸10 处。从此以后,南来的船舶可直驶到大都城中,作为船舶终点码头的积水潭上登时桅樯如林,热闹非凡。通惠河不但解决了运粮问题,而且促进了南货北销,繁荣了大都城的经济。',
+      '通惠河是元代挖建的漕运河道,由郭守敬主持修建。于至元二十九年(1292)春天动工,次年工程完成,总长 164 里,沿河设坝闸10 处。从此以后,南来的船舶可直驶到大都城中,作为船舶终点码头的积水潭上登时桅樯如林,热闹非凡。通惠河不但解决了运粮问题,而且促进了南货北销,繁荣了大都城的经济。',
     ]
   }
 
@@ -617,9 +618,7 @@ const currentMsg = computed(() => {
     if (hy3DetailVisbile.value) {
       return ['<p>船长108cm* 船宽28cm* 船高26cm</p><p>隔舱板、肋骨:江西小叶樟; 甲板、船壳外板:柚木、梢木;</p><p>船附件:菠萝格、龙眼木;</p>']
     }
-    return [
-      '2010 年发现的菏泽元代沉船,向世人展示了一处完整的内河沉船遗迹。该船为木质单桅货船,船型狭长,方首,方尾,平底,共 12 个舱,主体用材为杉木。据专家研究,这艘沉船发现的位置正在元朝的黄河北支上,而黄河北支此时与会通河相接,当时凡从运河北上元大都或南下去往杭州方向的船只,在徐州到济宁段都需要经过这段河道。'
-    ]
+    return []
   }
 
   if (hymHover.value || hymHover2.value) {
@@ -632,9 +631,9 @@ const currentMsg = computed(() => {
     }
     if (hymHover.value) {
       // 内城门
-      return ['和义门今尚存遗址,位于北京西直门处。城门残存高22米,门洞长9.92米、宽4.62米,内券高6.68米,外券高4.56米。是研究元代城市建设的珍贵资料。 1969年,拆除北京西直门箭楼时发现了压在明代箭楼之下的元大都和义门瓮城城门,门洞内有元至正十八年(1358年)的题记。城楼建筑已被拆去,只余城门墩台和门洞。']
+      return ['和义门今尚存遗址,位于北京西直门处。城门残存高22米,门洞长9.92米、宽4.62米,内券高6.68米,外券高4.56米。是研究元代城市建设的珍贵资料。']
     }
-    return ['和义门今尚存遗址,位于北京西直门处。城门残存高22米,门洞长9.92米、宽4.62米,内券高6.68米,外券高4.56米。是研究元代城市建设的珍贵资料。']
+    return ['1969年,拆除北京西直门箭楼时发现了压在明代箭楼之下的元大都和义门瓮城城门,门洞内有元至正十八年(1358年)的题记。城楼建筑已被拆去,只余城门墩台和门洞。']
   }
 
   if (isDDLS.value) {

+ 25 - 9
src/components/RelicDetailForHotspot.vue

@@ -61,7 +61,7 @@
 </template>
 
 <script setup>
-import { ref, computed, watch, onMounted, nextTick } from "vue"
+import { ref, computed, getCurrentInstance, onMounted, nextTick } from "vue"
 import Swiper from 'swiper/bundle'
 import 'swiper/css/bundle'
 import { useStore } from "vuex"
@@ -73,7 +73,7 @@ const store = useStore()
 console.log('relicInfo: ', props.relicInfo)
 
 const relicInfo = computed(() => {
-  return store.getters.hotRelicData[typeof props.relicIndex === 'number' ? props.relicIndex : props.relicInfo.hotspotTitle]
+  return store.getters.hotRelicData[Number(typeof props.relicIndex === 'number' ? props.relicIndex : props.relicInfo.hotspotTitle) - 1]
 })
 
 const imageList = computed(() => {
@@ -92,7 +92,7 @@ const isShowDesc = ref(true)
  * swiper 相关
  */
 let swiper = null
-// const activeSwiperItemIndex = ref(0)
+const activeSwiperItemIndex = ref(0)
 function initSwiper() {
   swiper = new Swiper('.swiper-root', {
     pagination: {
@@ -109,9 +109,9 @@ function initSwiper() {
       // afterInit: function (e) {
       //   activeSwiperItemIndex.value = e.activeIndex
       // },
-      // slideChange: function(e) {
-      //   activeSwiperItemIndex.value = e.activeIndex
-      // }
+      slideChange: function(e) {
+        activeSwiperItemIndex.value = e.activeIndex
+      }
     }
   })
 }
@@ -120,6 +120,16 @@ onMounted(() => {
     initSwiper()
   })
 })
+
+const instance = getCurrentInstance()
+const handleFull = () => {
+  instance.appContext.config.globalProperties.$viewerApi({
+    options: {},
+    images: [
+      imageList.value[activeSwiperItemIndex.value]
+    ]
+  })
+}
 </script>
 
 <style lang="less" scoped>
@@ -240,6 +250,8 @@ onMounted(() => {
       overflow: hidden;
     }
     >.detail{
+      display: flex;
+      flex-direction: column;
       flex: 0 1 auto;
       margin-top: 30px;
       margin-bottom: 30px;
@@ -249,11 +261,15 @@ onMounted(() => {
       font-family: Source Han Sans SC, Source Han Sans SC;
       font-weight: 300;
       color: #000000;
-      line-height: 23px;
-      letter-spacing: 4px;
+      // letter-spacing: 4px;
       overflow: auto;
       padding-right: calc(35 / 577 * 100%);
-      text-indent: 2em;
+      word-wrap: break-word;
+      white-space: pre-wrap;
+
+      :deep(p) {
+        line-height: 30px;
+      }
     }
     >button.show-hide{
       position: absolute;

+ 1 - 1
src/components/UserGuide.vue

@@ -4,7 +4,7 @@
       class="btn"
       @click="handleClose"
     >
-      下一步
+      {{ curStep === 6 ? '我知道了' : '下一步' }}
     </div>
     <template v-if="curStep === 0">
       <div class="user-guide-1" />

+ 6 - 2
src/useFunctions/useSmoothSwipe.js

@@ -41,7 +41,8 @@ export default function useSmoothSwipe({
   viewportWidth = document.documentElement.clientWidth,
   speedFactor = 1,
   damping = 0.003, // 阻尼
-  enableAutoMoving = false
+  enableAutoMoving = false,
+  initTranslateLength = 0
 } = {}) {
   const isOperating = ref(false)
   const hasOperatedThisTime = ref(false)
@@ -49,7 +50,7 @@ export default function useSmoothSwipe({
   let lastMoveEventTimeStamp = 0
   let lastCursorPos = 0
   let moveSpeed = ref(0)
-  let translateLength = ref(0)
+  let translateLength = ref(initTranslateLength)
   let maxTranslateLengthInner = Infinity
   let isAutoMoving = ref(false)
   let beginAutoMoveIntervalId = null
@@ -289,5 +290,8 @@ export default function useSmoothSwipe({
     translateLength,
     hasOperatedThisTime,
     updateWidth,
+    updateTranslateLength: (v) => {
+      translateLength.value = v
+    }
   }
 }

+ 8 - 3
src/views/EpilogueView.vue

@@ -2,7 +2,7 @@
   <div class="epilogue-view">
     <transition name="fade-out">
       <video
-        v-show="isShowVideo"
+        v-if="isShowVideo"
         class="epilogue-video"
         src="@/assets/videos/epilogue.mp4"
         autoplay
@@ -44,15 +44,20 @@
 </template>
 
 <script setup>
-import { ref } from "vue"
+import { inject, onMounted, ref } from "vue"
 import QRCode from 'qrcode'
 import { useRouter } from "vue-router"
 
 const router = useRouter()
 const isShowVideo = ref(true)
+const stopBgAudio = inject('stopBgAudio')
+
+onMounted(() => {
+  stopBgAudio()
+})
 
 const imageUrl = ref('')
-QRCode.toDataURL(`${location.origin}${process.env.BASE_URL || '/'}index.html#/`).then((url) => {
+QRCode.toDataURL(`${location.origin}/project/yzdyh-dadu/index.html`).then((url) => {
   imageUrl.value = url
 })
 </script>

+ 5 - 6
src/views/HomeView.vue

@@ -252,18 +252,17 @@ function onClickLogo() {
       position: absolute;
       left: 20%;
       transform: translate(-50%);
-      bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      bottom: 0;
       background-image: url(@/assets/images/scene-entry-1.png);
       background-size: cover;
       background-repeat: no-repeat;
       background-position: center center;
-      width: calc(506 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-      height: calc(337 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      width: calc(521 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(369 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       &:hover{
         background-image: url(@/assets/images/scene-entry-1-active.png);
-        width: calc(506 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        height: calc(337 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        transform: translate(calc(-50% - (10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'))), calc(12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
+        width: calc(521 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        height: calc(369 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         // &::after{
         //   position: absolute;
         //   content: '';

+ 55 - 19
src/views/PanoView.vue

@@ -221,10 +221,10 @@
     <transition name="fade-in-out-slow">
       <div
         v-if="isShowCameraIntro"
-        class="text-wrap text-indent"
+        class="text-wrap"
       >
         <div
-          class="text"
+          class="text text-indent"
           v-html="cameraIntroText"
         />
         <button
@@ -447,11 +447,11 @@ const ZMFMsgList = computed(() => {
           audio: 'scene-1-msg-1.mp3'
         },
         {
-          inner: '请大家跟随我的脚步,一起游览这座13世纪世界上最伟大的都城建筑——元大都。',
+          inner: '请大家跟随我的脚步,一起游览这座13世纪世界上最伟大的都城建筑——元大都。',
           audio: 'follow-me.mp3'
         },
         {
-          inner: '请进入场景开始游览',
+          inner: '请进入场景开始游览',
           audio: 'gogogo.mp3'
         }
       ]
@@ -479,11 +479,11 @@ const ZMFMsgList = computed(() => {
           audio: 'scene-2-msg-1.mp3'
         },
         {
-          inner: '请大家跟随我的脚步,一起游览流动的文化,滋养元大都的通惠河。',
+          inner: '请大家跟随我的脚步,一起游览流动的文化,滋养元大都的通惠河。',
           audio: 'follow-me2.mp3'
         },
         {
-          inner: '请进入场景开始游览',
+          inner: '请进入场景开始游览',
           audio: 'gogogo.mp3'
         }
       ]
@@ -511,11 +511,11 @@ const ZMFMsgList = computed(() => {
           audio: 'scene-3-msg-1.mp3'
         },
         {
-          inner: '请大家跟随我的脚步,一起游览笔墨之间,舞台之上的文化魅力。',
+          inner: '请大家跟随我的脚步,一起游览笔墨之间,舞台之上的文化魅力。',
           audio: 'follow-me3.mp3'
         },
         {
-          inner: '请进入场景开始游览',
+          inner: '请进入场景开始游览',
           audio: 'gogogo.mp3'
         }
       ]
@@ -573,7 +573,7 @@ function onClickCharacter(anType) {
       }, duration)
     }, 200)
   }
-  if (!anType) {
+  if (!anType && !isShowHotspotDetail2.value) {
     msgVisible.value = true
   }
 }
@@ -752,7 +752,7 @@ function skipFirstSceneIntro() {
   const video = sceneIntrovideoStartEl.value
   switch (sceneIdx.value) {
   case 0:
-    video.currentTime = 38
+    video.currentTime = 34
     break
   case 1:
     video.currentTime = 42
@@ -773,12 +773,11 @@ onBeforeRouteUpdate(() => {
 
 const handleBgAudio = inject('handleBgAudio')
 watch(sceneIdx, () => {
-  if (sceneIdx.value === 1) {
-    handleBgAudio({
-      sceneIdx: sceneIdx.value,
-      canPlay: !isShowSceneIntroVideoStart.value && !isShowCameraIntro.value
-    })
-  }
+  handleBgAudio({
+    sceneIdx: sceneIdx.value,
+    cameraIdx: cameraIdx.value,
+    canPlay: !isShowSceneIntroVideoStart.value && !isShowCameraIntro.value
+  })
 }, {
   immediate: true,
 })
@@ -828,11 +827,41 @@ function onClickNextScene() {
  * end of 点击“下一个场景”按钮的逻辑
  */
 
+const currentVr = computed(() => {
+  switch (Number(route.query.sceneIdx)) {
+  case 0:
+    switch (Number(route.query.cameraIdx)) {
+    case 0:
+      return 'fd720_kdDO8sPe6'
+    case 1:
+      return 'fd720_CKI5Ly4eo'
+    default:
+      return 'fd720_Ti8chaWqT'
+    }
+  case 1:
+    switch (Number(route.query.cameraIdx)) {
+    case 0:
+      return 'fd720_f4R2wpbQC'
+    case 1:
+      return 'fd720_I2StypBk9'
+    default:
+      return 'fd720_s9WjwfMcG'
+    }
+  default:
+    switch (Number(route.query.cameraIdx)) {
+    case 0:
+      return 'fd720_Xzq2fjoBa'
+    default:
+      return 'fd720_0vzJY3UBA'
+    }
+  }
+})
+
 
 /**
  * iframe的逻辑
  */
-const iframeSrc = `${process.env.VUE_APP_CLI_MODE === 'dev' ? 'http://192.168.0.44:8081/' : 'https://houseoss.4dkankan.com/project/yzdyh-dadu/pano/'}show.html?id=WK1730428603763576832&lang=zh&vr=${route.query.sceneIdx === '0' ? 'fd720_kdDO8sPe6' : route.query.sceneIdx === '1' ? 'fd720_f4R2wpbQC' : 'fd720_Xzq2fjoBa'}`
+const iframeSrc = `${process.env.VUE_APP_CLI_MODE === 'dev' ? 'http://192.168.0.44:8081/' : 'https://houseoss.4dkankan.com/project/yzdyh-dadu/pano/'}show.html?id=WK1730428603763576832&lang=zh&vr=${currentVr.value}`
 const panoIframe = ref(null)
 
 watch(cameraIdx, (vNew) => {
@@ -1157,8 +1186,8 @@ onMounted(() => {
           letter-spacing: 5px;
         }
         &:hover{
-          width: 397px;
-          height: 91px;
+          width: 390px;
+          height: 104px;
           transform: translate(-13px, -5px);
           >span{
             display: initial;
@@ -1170,6 +1199,8 @@ onMounted(() => {
         top: -42px;
         background-image: v-bind(btnOnTrack1ImgUrl);
         &:hover{
+          top: -49px;
+          left: 217px;
           background-image: v-bind(btnOnTrack1ActiveImgUrl);
         }
       }
@@ -1178,6 +1209,7 @@ onMounted(() => {
         top: 62px;
         background-image: v-bind(btnOnTrack2ImgUrl);
         &:hover{
+          top: 54px;
           background-image: v-bind(btnOnTrack2ActiveImgUrl);
         }
       }
@@ -1186,6 +1218,8 @@ onMounted(() => {
         top: 205px;
         background-image: v-bind(btnOnTrack3ImgUrl);
         &:hover{
+          top: 196px;
+          left: 391px;
           background-image: v-bind(btnOnTrack3ActiveImgUrl);
         }
       }
@@ -1194,6 +1228,8 @@ onMounted(() => {
         top: 353px;
         background-image: v-bind(btnOnTrack4ImgUrl);
         &:hover{
+          top: 344px;
+          left: 359px;
           background-image: v-bind(btnOnTrack4ActiveImgUrl);
         }
       }

+ 12 - 6
src/views/RelicDetail.vue

@@ -41,12 +41,13 @@
       <h1 :title="relicInfo['名称']">
         {{ relicInfo['名称'] }}
       </h1>
-      <div class="age">
+      <div class="age text-indent">
         {{ relicInfo['年份'] }}
       </div>
-      <pre
-        class="detail"
-      >{{ relicInfo['详细描述'] }}</pre>
+      <div
+        v-html="relicInfo['详细描述']"
+        class="detail text-indent"
+      />
       <button
         class="show-hide"
         :class="{
@@ -247,6 +248,8 @@ const handleFull = () => {
       overflow: hidden;
     }
     >.detail{
+      display: flex;
+      flex-direction: column;
       flex: 0 1 auto;
       margin-top: 30px;
       margin-bottom: 30px;
@@ -256,12 +259,15 @@ const handleFull = () => {
       font-family: Source Han Sans SC, Source Han Sans SC;
       font-weight: 300;
       color: #000000;
-      line-height: 23px;
-      letter-spacing: 4px;
+      // letter-spacing: 4px;
       overflow: auto;
       padding-right: calc(35 / 577 * 100%);
       word-wrap: break-word;
       white-space: pre-wrap;
+
+      :deep(p) {
+        line-height: 30px;
+      }
     }
     >button.show-hide{
       position: absolute;

+ 35 - 2
src/views/RelicList.vue

@@ -34,6 +34,7 @@
       <div
         ref="listEl"
         class="content-wrap"
+        @scroll="handleScroll"
       >
         <div
           class="first-item"
@@ -81,12 +82,14 @@
 /**
  * todo: 自动恢复上次滚动位置
  */
-import { ref, computed, watch, watchEffect, onMounted, nextTick } from "vue"
+import { ref, computed, watch, watchEffect, onMounted, nextTick, defineComponent } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import useSmoothSwipe from '@/useFunctions/useSmoothSwipe.js'
 import { useElementSize, useWindowSize } from '@vueuse/core'
+import { debounce } from "lodash"
 
+const SCROLL_KEY = 'relicListScrollLeft'
 const route = useRoute()
 const router = useRouter()
 const store = useStore()
@@ -192,10 +195,12 @@ function getRelicThumbUrl(idx) {
 }
 
 const listEl = ref(null)
+let scrollLeft = Number(localStorage.getItem(SCROLL_KEY) || 0)
 const { width: listWidth, height: listHeight } = useElementSize(listEl)
-const { hasOperatedThisTime, updateWidth } = useSmoothSwipe({
+const { hasOperatedThisTime, updateWidth, updateTranslateLength } = useSmoothSwipe({
   scrollTargetRef: listEl,
   viewportWidth: listWidth,
+  initTranslateLength: scrollLeft,
 })
 watch(relicData, (vNew) => {
   nextTick(() => {
@@ -217,6 +222,33 @@ function onClickItem(idx) {
     })
   }
 }
+
+watch(cascaderValue, val => {
+  router.replace({
+    name: 'RelicList',
+    query: {
+      sceneIdx: val[0],
+      cameraIdx: val[1]
+    }
+  })
+  updateTranslateLength(0)
+})
+
+router.beforeEach((to) => {
+  if (!['RelicDetail', 'RelicList'].includes(to.name)) {
+    localStorage.removeItem(SCROLL_KEY)
+  }
+})
+
+onMounted(() => {
+  if (scrollLeft) {
+    listEl.value.scrollLeft = scrollLeft
+  }
+})
+
+const handleScroll = debounce(() => {
+  listEl.value && localStorage.setItem(SCROLL_KEY, listEl.value.scrollLeft)
+}, 100)
 </script>
 
 <style lang="less" scoped>
@@ -418,6 +450,7 @@ function onClickItem(idx) {
           line-height: 1.5em;
           background-image: url(@/assets/images/relic-item-title-bg-wide.png);
           padding-right: 0.7em;
+          z-index: 1;
         }
         >img {
           position: absolute;