Browse Source

style: 1:1适配

chenlei 1 năm trước cách đây
mục cha
commit
ce9385e0f1
54 tập tin đã thay đổi với 573 bổ sung394 xóa
  1. 1 1
      src/App.vue
  2. 1 1
      src/components/CameraContent-1-1-1.vue
  3. 1 1
      src/components/CameraContent-1-1-2.vue
  4. 1 1
      src/components/CameraContent-1-1-3.vue
  5. 1 1
      src/components/CameraContent-1-2-1.vue
  6. 1 1
      src/components/CameraContent-1-2-2.vue
  7. 3 3
      src/components/CameraContent-1-2-3.vue
  8. 1 1
      src/components/CameraContent-1-3-1.vue
  9. 1 1
      src/components/CameraContent-1-3-2.vue
  10. 1 1
      src/components/CameraContent-1-3-3.vue
  11. 1 1
      src/components/CameraContent-2-1-1.vue
  12. 1 1
      src/components/CameraContent-2-1-2.vue
  13. 1 1
      src/components/CameraContent-2-1-3.vue
  14. 1 1
      src/components/CameraContent-2-2-1.vue
  15. 1 1
      src/components/CameraContent-2-2-2.vue
  16. 1 1
      src/components/CameraContent-2-3-1.vue
  17. 1 1
      src/components/CameraContent-2-3-2.vue
  18. 1 1
      src/components/CameraContent-2-3-3.vue
  19. 1 1
      src/components/CameraContent-3-1-1.vue
  20. 1 1
      src/components/CameraContent-3-1-2.vue
  21. 1 1
      src/components/CameraContent-3-1-3.vue
  22. 1 1
      src/components/CameraContent-3-2-1.vue
  23. 1 1
      src/components/CameraContent-3-2-2.vue
  24. 1 1
      src/components/CameraContent-3-2-3.vue
  25. 1 1
      src/components/CharacterDesc.vue
  26. 1 1
      src/components/GameEntryPage.vue
  27. 56 37
      src/components/HotspotDialog-1.vue
  28. 63 3
      src/components/MobileCameraContent/CameraContent-1-1-1.vue
  29. 1 2
      src/components/MobileCameraContent/CameraContent-1-1-2.vue
  30. 3 0
      src/components/MobileCameraContent/CameraContent-1-2-1.vue
  31. 2 2
      src/components/MobileCameraContent/CameraContent-1-2-3.vue
  32. 20 20
      src/components/MobileCameraContent/CameraContent-1-3-2.vue
  33. 1 1
      src/components/MobileCameraContent/CameraContent-1-3-3.vue
  34. 1 1
      src/components/MobileCameraContent/CameraContent-2-1-1.vue
  35. 1 1
      src/components/MobileCameraContent/CameraContent-2-1-2.vue
  36. 1 1
      src/components/MobileCameraContent/CameraContent-2-1-3.vue
  37. 47 55
      src/components/MobileCameraContent/CameraContent-2-2-1.vue
  38. 4 13
      src/components/MobileCameraContent/CameraContent-2-3-1.vue
  39. 1 1
      src/components/MobileCameraContent/CameraContent-3-1-3.vue
  40. 1 1
      src/components/MsgContent.vue
  41. 1 1
      src/components/MutiRelicHotSpot.vue
  42. 1 1
      src/components/RelicDetailForHotspot.vue
  43. 22 35
      src/components/StartUp.vue
  44. 1 1
      src/components/UserGuide.vue
  45. 146 0
      src/components/VideoAdapter.vue
  46. 11 2
      src/main.js
  47. 8 1
      src/preloadList.js
  48. 2 2
      src/views/EpilogueView.vue
  49. 78 76
      src/views/HomeView.vue
  50. 60 69
      src/views/PanoView.vue
  51. 1 1
      src/views/RelicDetail.vue
  52. 1 1
      src/views/RelicList.vue
  53. 1 1
      src/views/RelicListMobile.vue
  54. 10 37
      src/views/ShipGame/ShipGameView.vue

+ 1 - 1
src/App.vue

@@ -527,7 +527,7 @@ button.logo{
     width: 200px;
   }
 }
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .viewer-button.viewer-close {
     transform: scale(2.3);
   }

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

@@ -737,7 +737,7 @@ const closeTipsCover = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 h1 {
     top: calc(-72 / 970* 100vh);
     font-size: calc(36 / 970* 100vh);

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

@@ -284,7 +284,7 @@ const tab1ContentPageNumber = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     .tab-1-content {
       .pre-btn {

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

@@ -139,7 +139,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
     width: 100%;

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

@@ -416,7 +416,7 @@ const closeTipsCover = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 {
     > h1 {
       top: 0;

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

@@ -369,7 +369,7 @@ const handleFull = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-2-2 > .content-wrap {
     top: 50%;
     height: 100%;

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

@@ -112,8 +112,8 @@ const closeTipsCover = () => {
   backdrop-filter: blur(60px);
   .tips-cover {
     top: calc(-50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    left: calc(-70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    right: calc(-70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    left: calc(-80 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    right: calc(-80 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     bottom: calc(-50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
   >button.return{
@@ -222,7 +222,7 @@ const closeTipsCover = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 .video {
     width: calc(860 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }

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

@@ -268,7 +268,7 @@ const activeTabIdx = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-2-2 .content-wrap {
     top: 50%;
     height: 100%;

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

@@ -287,7 +287,7 @@ const hotspotIdx = computed(() => displayingHotspotIdx.value !== 0 ? displayingH
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-3-2 {
     > h1 {
       top: 0;

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

@@ -134,7 +134,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 .content-wrap {
     top: 50%;
 

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

@@ -290,7 +290,7 @@ const handleFull = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 {
     > h1 {
       top: calc(56 / 970* 100vh);

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

@@ -207,7 +207,7 @@ const handleFull = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
 

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

@@ -396,7 +396,7 @@ const tab1ContentPageNumber = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
     width: calc(1685 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

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

@@ -141,7 +141,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 .content-wrap {
     top: 50%;
     &-c {

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

@@ -129,7 +129,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
 

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

@@ -180,7 +180,7 @@ const currentSwitchIdx = ref(0)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 {
     > h1 {
       font-size: calc(36 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

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

@@ -487,7 +487,7 @@ const activeTabIdx = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 >  div.content-wrap {
     top: 50%;
     width: calc(1685 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

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

@@ -123,7 +123,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 .content-wrap {
     top: 50%;
 

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

@@ -293,7 +293,7 @@ const activeTabIdx = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
     height: 100%;

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

@@ -367,7 +367,7 @@ const activeTabIdx = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
     height: 100%;

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

@@ -280,7 +280,7 @@ const next = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 {
     > h1 {
       font-size: calc(36 / 970* 100vh);

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

@@ -295,7 +295,7 @@ const activeTabIdx = ref(1)
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     top: 50%;
     height: 100%;

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

@@ -218,7 +218,7 @@ const next = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > h1 {
     font-size: calc(36 / 970* 100vh);
   }

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

@@ -133,7 +133,7 @@ const title = '表演元曲的著名演员'
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > h1 {
     font-size: calc(36 / 970* 100vh);
   }

+ 1 - 1
src/components/CharacterDesc.vue

@@ -90,7 +90,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .character-desc .wrap > .wrap-2 > .desc {
     font-size: 26px;
     line-height: 34px;

+ 1 - 1
src/components/GameEntryPage.vue

@@ -165,7 +165,7 @@ const isDBG = gameName === '多宝阁'
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .game-entry-page {
     button.return {
       width: 100px;

+ 56 - 37
src/components/HotspotDialog-1.vue

@@ -594,7 +594,7 @@
     </template>
 
     <MsgContent
-      v-if="currentMsg.length && innerHeight > 250"
+      v-if="currentMsg.length && iHeight > 250"
       v-model:curIndex="curMsgIndex"
       :list="currentMsg"
       @back="close"
@@ -612,7 +612,17 @@ const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
 } = useSizeAdapt(1920, 970)
-const innerHeight = window.innerHeight
+const windowAspectRatio = window.innerWidth / window.innerHeight
+const imageAspectRatio = 16 / 9
+let ratioX
+
+if (windowAspectRatio > imageAspectRatio) {
+  ratioX = 1
+} else {
+  ratioX = Math.round(imageAspectRatio / windowAspectRatio * 100) / 100
+}
+
+const iHeight = window.innerHeight
 const $isMobile = inject('$isMobile')
 const store = useStore()
 const startBgAudio = inject("startBgAudio")
@@ -638,6 +648,7 @@ const thhDetailVisbile = ref(false)
 const hyHover = ref(false)
 const hyDetailVisbile = ref(false)
 const hy2Hover = ref(false)
+
 const hy2DetailVisbile = ref(false)
 const hy3Hover = ref(false)
 const hy3DetailVisbile = ref(false)
@@ -851,11 +862,11 @@ const close = () => {
   position: absolute;
   top: 50%;
   left: 50%;
-  width: 70px;
-  height: 70px;
+  width: calc(70px * v-bind('ratioX'));
+  height: calc(70px * v-bind('ratioX'));
   overflow: hidden;
-  z-index: 2;
   transform: translate(-50%, -50%);
+  z-index: 2;
 
   img {
     position: absolute;
@@ -868,7 +879,7 @@ const close = () => {
     animation-iteration-count: infinite;
   }
   &.spot-qy {
-    margin: calc(-100 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) 0 0 200px;
+    margin: calc(-70px * v-bind('ratioX')) 0 0 calc(190px * v-bind('ratioX'));
   }
   &.spot-hc {
     margin-top: -160px;
@@ -883,13 +894,13 @@ const close = () => {
     margin: 70px 0 0 350px;
   }
   &.spot-hym {
-    margin: -200px 0 0 100px;
+    margin: calc(-140px * v-bind('ratioX')) 0 0 calc(80px * v-bind('ratioX'));
   }
   &.spot-dmd {
-    margin: -100px 0 0 -20px;
+    margin: calc(-100px * v-bind('ratioX')) 0 0 calc(-30px * v-bind('ratioX'));
   }
   &.spot-qss {
-    margin: -100px 0 0 140px;
+    margin: calc(-100px * v-bind('ratioX')) 0 0 calc(140px * v-bind('ratioX'));
   }
 }
 .hotspot-dialog-1 {
@@ -1006,15 +1017,18 @@ const close = () => {
   }
   .qy {
     position: absolute;
-    top: 18%;
-    left: 45%;
-    width: 29vw;
-    height: 31vh;
+    top: 50%;
+    left: 50%;
+    margin: calc(-110px * v-bind('ratioX')) 0 0 calc(190px * v-bind('ratioX'));
+    width: calc(500px * v-bind('ratioX'));
+    height: calc(300px * v-bind('ratioX'));
+    transform: translate(-50%, -50%);
     z-index: 1;
 
     .label {
-      top: -25%;
-      left: 47.5%;
+      top: calc(-50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      left: 50%;
+      transform: translateX(-50%);
     }
     &.hover {
       .label {
@@ -1139,15 +1153,17 @@ const close = () => {
   }
   .qss {
     position: absolute;
-    top: 5vh;
-    left: 48vw;
-    right: 30vw;
-    height: 45vh;
+    top: 50%;
+    left: 50%;
+    margin: calc(-170px * v-bind('ratioX')) 0 0 calc(180px * v-bind('ratioX'));
+    width: calc(400px * v-bind('ratioX'));
+    height: calc(400px * v-bind('ratioX'));
+    transform: translate(-50%, -50%);
     z-index: 1;
 
     .label {
-      top: 8%;
-      left: 35%;
+      top: calc(80px * v-bind('ratioX'));
+      left: calc(140px * v-bind('ratioX'));
     }
     &.hover {
       .label {
@@ -1178,15 +1194,18 @@ const close = () => {
   }
   .dmd {
     position: absolute;
-    top: 20vh;
-    left: 26vw;
-    right: 28vw;
-    height: 35vh;
+    top: 50%;
+    left: 50%;
+    margin: calc(-90px * v-bind('ratioX')) 0 0 calc(-30px * v-bind('ratioX'));
+    width: calc(900px * v-bind('ratioX'));
+    height: calc(350px * v-bind('ratioX'));
+    transform: translate(-50%, -50%);
     z-index: 1;
 
     .label {
       top: -28%;
-      left: 47%;
+      left: 50%;
+      transform: translateX(-50%);
     }
     &.hover {
       .label {
@@ -1220,15 +1239,17 @@ const close = () => {
   // 外城门
   .hym-ncm {
     position: absolute;
-    top: 13vh;
-    left: 10vw;
-    width: 68vw;
-    height: 64vh;
+    top: 50%;
+    left: 50%;
+    margin: 0 0 0 calc(-100px * v-bind('ratioX'));
+    width: calc(1300px * v-bind('ratioX'));
+    height: calc(700px * v-bind('ratioX'));
+    transform: translate(-50%, -50%);
     z-index: 2;
 
     .label {
       top: -10%;
-      left: 70%;
+      right: calc(370px * v-bind('ratioX'));
     }
     &.hover {
       .label {
@@ -1324,8 +1345,8 @@ const close = () => {
     align-items: center;
     justify-content: center;
     position: absolute;
-    width: 41px;
-    height: 181px;
+    width: calc(41px * v-bind('ratioX'));
+    height: calc(181px * v-bind('ratioX'));
     font-size: 18px;
     color: #724b26;
     letter-spacing: 1px;
@@ -1344,7 +1365,7 @@ const close = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .hzcc-video {
     width: calc(1200 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
@@ -1371,8 +1392,6 @@ const close = () => {
       }
     }
     &__label {
-      width: 61px;
-      height: 201px;
       font-size: 24px;
     }
   }
@@ -1390,7 +1409,7 @@ const close = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .hotspot-icon.spot-qss {
     margin-top: -50px;
   }

+ 63 - 3
src/components/MobileCameraContent/CameraContent-1-1-1.vue

@@ -360,13 +360,13 @@ const closeTipsCover = () => {
       width: 100%;
       height: 100%;
       background-image: url(@/assets/images/mobile/bg_1-2-min.jpg);
-      background-size: 100% 100%;
+      background-size: cover;
       background-repeat: no-repeat;
       background-position: center center;
       z-index: 1;
       &__container {
         position: absolute;
-        top: calc(160 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(50% - 45 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         left: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         right: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         bottom: 0;
@@ -376,6 +376,7 @@ const closeTipsCover = () => {
         padding-left: constant(safe-area-inset-left);
         padding-left: env(safe-area-inset-left);
         box-sizing: border-box;
+        transform: translateY(-50%);
       }
       h2.character-name{
         width: calc(62 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -484,6 +485,7 @@ const closeTipsCover = () => {
         justify-content: center;
         align-items: center;
         writing-mode: vertical-lr;
+        margin-left: calc(-70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-right: calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-bottom: calc(10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));;
         font-family: "Source Han Serif CN Heavy";
@@ -523,7 +525,10 @@ const closeTipsCover = () => {
 
       &__map {
         position: relative;
+        top: 50%;
         height: 100%;
+        max-height: calc(974 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translateY(-50%);
 
         > img {
           height: 100%;
@@ -690,7 +695,7 @@ const closeTipsCover = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
     &.full-content-wrap {
       width: 100%;
@@ -744,4 +749,59 @@ const closeTipsCover = () => {
     }
   }
 }
+
+@media screen and (min-height: 480px) and (max-height: 740px) {
+  .camera-content-1-1 > .content-wrap .map-wrap__map {
+    max-height: calc(674 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    button.hotspot {
+      width: calc(73 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(73 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    }
+    button.hotspot:nth-of-type(1){
+      left: calc(488 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      top: calc(86 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      >img.deco{
+        position: absolute;
+        width: calc(42 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        height: calc(615.5 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        left: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(-72 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+    button.hotspot:nth-of-type(2){
+      left: calc(329 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      top: calc(178 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      >img.deco{
+        position: absolute;
+        width: calc(1125 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        height: calc(851 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        left: calc(-368 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(-229 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+    button.hotspot:nth-of-type(3){
+      left: calc(847 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      top: calc(131 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      >img.deco{
+        position: absolute;
+        width: calc(1470 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        height: calc(621 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        left: calc(-1051 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(-125 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+    button.hotspot:nth-of-type(4){
+      left: calc(504 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      top: calc(403 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      >img.deco{
+        position: absolute;
+        width: calc(509 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        height: calc(211 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        left: calc(-305 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(-85 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        z-index: 1;
+      }
+    }
+  }
+}
 </style>

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

@@ -112,8 +112,7 @@ const tab1ContentPageNumber = ref(1)
     margin-bottom: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
   img {
-    flex: 1;
-    height: 0;
+    width: calc(1200 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
 }
 .tab-1-content {

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

@@ -269,7 +269,10 @@ const closeTipsCover = () => {
 
       &__map {
         position: relative;
+        top: 50%;
         height: 100%;
+        max-height: calc(974 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translateY(-50%);
 
         > img {
           height: 100%;

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

@@ -112,8 +112,8 @@ const closeTipsCover = () => {
   backdrop-filter: blur(60px);
   .tips-cover {
     top: calc(-50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    left: calc(-70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    right: calc(-70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    left: calc(-120 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    right: calc(-120 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     bottom: calc(-50 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
   >button.return{

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

@@ -150,14 +150,14 @@ const closeTipsCover = () => {
   >h1{
     position: absolute;
     left: 0;
-    top: calc(100 / @page-height-design-px * 100vh);
+    top: 0;
     width: 100%;
     height: calc(140 / @page-height-design-px * 100vh);
     background-image: url(@/assets/images/camera-content-1-1-1-title-bg.png);
     background-size: auto 100%;
     background-repeat: no-repeat;
     background-position: center center;
-    font-size: calc(32 / @page-height-design-px * 100vh);
+    font-size: 32px;
     font-family: "Source Han Serif CN Heavy";
     color: #FFFFFF;
     line-height: calc(38 / @page-height-design-px * 100vh);
@@ -168,11 +168,10 @@ const closeTipsCover = () => {
   }
   >.content-wrap{
     position: absolute;
-    left: 50%;
-    top: 54%;
-    width: calc(1920 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    height: calc(723 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    transform: translate(-50%, -50%);
+    left: 0;
+    top: 0;
+    right: 0;
+    bottom: 0;
     .map-wrap{
       position: absolute;
       left: 0;
@@ -187,8 +186,11 @@ const closeTipsCover = () => {
 
       &__map {
         position: relative;
+        top: 50%;
         left: calc(-200 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         height: 100%;
+        max-height: calc(974 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        transform: translateY(-50%);
 
         > img {
           height: 100%;
@@ -243,23 +245,23 @@ const closeTipsCover = () => {
       }
       button.hotspot:nth-of-type(1){
         left: calc(531 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        top: calc(520 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(470 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       button.hotspot:nth-of-type(2){
         left: calc(694 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        top: calc(396 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(346 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       button.hotspot:nth-of-type(3){
         left: calc(828 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        top: calc(499 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(449 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       button.hotspot:nth-of-type(4){
         left: calc(575 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        top: calc(176 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(126 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       button.hotspot:nth-of-type(5){
         left: calc(621 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-        top: calc(176 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        top: calc(126 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       }
       .desc{
         position: absolute;
@@ -327,15 +329,7 @@ const closeTipsCover = () => {
 
 @media screen and (max-height: 480px) {
   .camera-content-1-3-2 {
-    > h1 {
-      top: 0;
-      font-size: 36px;
-    }
     > .content-wrap {
-      top: 50%;
-      width: 100%;
-      height: 100%;
-
       .map-wrap {
         button.hotspot {
           width: calc(163 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -393,4 +387,10 @@ const closeTipsCover = () => {
     }
   }
 }
+
+@media screen and (min-height: 480px) and (max-height: 740px) {
+  .camera-content-1-3-2 > .content-wrap .map-wrap__map {
+    max-height: calc(674 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  }
+}
 </style>

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

@@ -134,7 +134,7 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 .content-wrap {
     top: 50%;
 

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

@@ -288,7 +288,7 @@ const handleFull = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 {
     > h1 {
       top: calc(10 / 970* 100vh);

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

@@ -208,7 +208,7 @@ const handleFull = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 > .content-wrap {
 
     .design-wrap {

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

@@ -116,7 +116,7 @@ const tab1ContentPageNumber = ref(1)
   overflow: auto;
 }
 .table-img {
-  height: calc(687 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  width: 100%;
 }
 .next-btn,
 .pre-btn {

+ 47 - 55
src/components/MobileCameraContent/CameraContent-2-2-1.vue

@@ -6,35 +6,34 @@
       @click="emit('close')"
     />
     <div class="content-wrap">
-      <img
-        draggable="false"
-        src="@/assets/images/mobile/bg_2-min.jpg"
+      <div
+        class="left-c"
+        :style="$isAndroidFullScreen ? {
+          paddingLeft: '50px'
+        } : {}"
       >
-      <div class="content-wrap-c">
-        <div class="left">
-          <p class="card-title left one">
-            菏泽沉船
-          </p>
-          <p class="one text-indent">
-            2010年发现的菏泽元代沉船,向世人展示了一处完整的内河沉船遗迹。该船为木质单桅货船,船型狭长,方首,方尾,平底,共 12 个舱,主体用材为杉木。据专家研究,这艘沉船发现的位置正在元朝的黄河北支上,而黄河北支此时与会通河相接,当时凡从运河北上元大都或南下去往杭州方向的船只,在徐州到济宁段都需要经过这段河道。
-          </p>
-          <p class="card-title left one">
-            菏泽沉船上的瓷器
-          </p>
-          <p class="two text-indent">
-            沉船中还出土了包括精美瓷器在内的160余件遗物,其中瓷器主要为景德镇青花与青白釉瓷器、磁州窑瓷器、龙泉窑瓷器、钧窑瓷器等,而这也是元大都内最常发现的瓷器组合。
-          </p>
-        </div>
-        <div class="right">
-          <img
-            class=""
-            src="@/assets/images/camera-content-2-1-1-img.png"
-            alt=""
-            draggable="false"
-          >
-          <div class="img-title">
-            修复后的菏泽沉船
-          </div>
+        <p class="card-title left one">
+          菏泽沉船
+        </p>
+        <p class="one text-indent">
+          2010年发现的菏泽元代沉船,向世人展示了一处完整的内河沉船遗迹。该船为木质单桅货船,船型狭长,方首,方尾,平底,共 12 个舱,主体用材为杉木。据专家研究,这艘沉船发现的位置正在元朝的黄河北支上,而黄河北支此时与会通河相接,当时凡从运河北上元大都或南下去往杭州方向的船只,在徐州到济宁段都需要经过这段河道。
+        </p>
+        <p class="card-title left one">
+          菏泽沉船上的瓷器
+        </p>
+        <p class="two text-indent">
+          沉船中还出土了包括精美瓷器在内的160余件遗物,其中瓷器主要为景德镇青花与青白釉瓷器、磁州窑瓷器、龙泉窑瓷器、钧窑瓷器等,而这也是元大都内最常发现的瓷器组合。
+        </p>
+      </div>
+      <div class="right">
+        <img
+          class=""
+          src="@/assets/images/camera-content-2-1-1-img.png"
+          alt=""
+          draggable="false"
+        >
+        <div class="img-title">
+          修复后的菏泽沉船
         </div>
       </div>
     </div>
@@ -42,13 +41,15 @@
 </template>
 
 <script setup>
+import { inject } from 'vue'
+
 const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
 } = useSizeAdapt(1920, 970)
 
 const emit = defineEmits(['close'])
-
+const $isAndroidFullScreen = inject('$isAndroidFullScreen')
 </script>
 
 <style lang="less" scoped>
@@ -73,27 +74,22 @@ const emit = defineEmits(['close'])
   }
   .content-wrap{
     position: absolute;
-    left: 50%;
-    top: 54%;
-    width: 100%;
-    transform: translate(-50%, -50%);
-    img {
-      width: 100%;
-    }
-    &-c {
-      position: absolute;
-      top: 0;
-      left: 0;
-      right: 0;
-      bottom: 0;
-      display: flex;
-      justify-content: space-evenly;
-      align-items: center;
-      padding: 0 calc(150 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-      z-index: 1;
-    }
-    .left{
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    padding: 0 calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    display: flex;
+    align-items: center;
+    background-image: url(@/assets/images/mobile/bg_2-min.jpg);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center;
+
+    .left-c{
       flex: 1;
+      padding-left: constant(safe-area-inset-left);
+      padding-left: env(safe-area-inset-left);
       .card-title {
         width: 70%
       }
@@ -128,13 +124,9 @@ const emit = defineEmits(['close'])
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 .content-wrap {
-    top: 50%;
-    &-c {
-      padding: calc(90 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) calc(150 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-    }
-    .left {
+    .left-c {
       padding-right: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       h2 {
         font-size: calc(32 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4 - 13
src/components/MobileCameraContent/CameraContent-2-3-1.vue


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

@@ -280,7 +280,7 @@ const next = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .camera-content-1-1 {
     > h1 {
       font-size: calc(36 / 970* 100vh);

+ 1 - 1
src/components/MsgContent.vue

@@ -158,7 +158,7 @@ watch(curMsg, handleAudio, {
     }
   }
 
-  @media screen and (max-height: 480px) {
+  @media screen and (max-height: 740px) {
     .msg-content__inner {
       font-size: 28px !important;
     }

+ 1 - 1
src/components/MutiRelicHotSpot.vue

@@ -367,7 +367,7 @@ const showRandomPoster = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .muti-relic {
     &__close {
       top: 60px;

+ 1 - 1
src/components/RelicDetailForHotspot.vue

@@ -340,7 +340,7 @@ const handleNext = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .relic-detail-for-hotspot {
     :deep(.left > .swiper-root > .swiper-pagination > span) {
       --swiper-pagination-bullet-horizontal-gap: 0.6vw;

+ 22 - 35
src/components/StartUp.vue

@@ -1,6 +1,5 @@
 <template>
   <div
-    v-if="loaded"
     class="start-up"
   >
     <!-- <div class="title-wrap">
@@ -40,34 +39,22 @@
       />
     </transition>
     <img
+      v-if="loaded"
       class="person-animation"
       src="@/assets/images/startup-animation.png"
       alt=""
       draggable="false"
     >
-    <div
+    <VideoAdapter
+      v-if="startUpVideo"
       v-show="isShowVideo"
-      class="video-wrap"
-    >
-      <video
-        ref="videoEl"
-        :src="startUpVideo"
-        playsinline="true"
-        webkit-playsinline="true"
-        x5-playsinline="true"
-        x-webkit-airplay="true"
-        x5-video-player-type="h5-page"
-        @play="onVideoPlay"
-        @ended="onVideoEnd"
-      />
-      <transition name="fade-in">
-        <button
-          v-show="isShowSkip"
-          class="skip"
-          @click="onClickSkip"
-        />
-      </transition>
-    </div>
+      ref="videoEl"
+      :src="startUpVideo"
+      :autoplay="false"
+      :show-skip="isShowSkip"
+      :show-play="false"
+      @ended="onVideoEnd"
+    />
   </div>
 </template>
 
@@ -79,6 +66,7 @@ import { useStore } from "vuex"
 import preloadList from '@/preloadList'
 import { usePreloader } from '@/hooks/usePreloader'
 // import startupVoiceUrl from '@/assets/audios/startup-voice.mp3'
+import VideoAdapter from '@/components/VideoAdapter.vue'
 
 const $isMobile = inject('$isMobile')
 const store = useStore()
@@ -97,19 +85,22 @@ const loaded = ref(false)
 
 onMounted(() => {
   Promise.all([
-    preloaderImage(require('@/assets/images/start-up-bg.jpg'))
-  ]).then(() => {
+    preloaderImage(require('@/assets/images/startup-animation.png'))
+  ]).finally(() => {
     loaded.value = true
     start()
   })
 })
 
 const preloaderImage = (url) => {
-  return new Promise(res => {
+  return new Promise((res, rej) => {
     const img = new Image()
     img.onload = () => {
       res()
     }
+    img.onerror = () => {
+      rej()
+    }
     img.src = url
   })
 }
@@ -125,7 +116,7 @@ const canStart = computed(() => {
 const isShowVideo = ref(false)
 function onClickStart() {
   isShowVideo.value = true
-  videoEl.value.play()
+  videoEl.value.videoRef.play()
   setTimeout(() => {
     isShowSkip.value = true
   }, 2000)
@@ -137,12 +128,13 @@ const haveShownStartUp = computed(() => {
 })
 watch(haveShownStartUp, (v) => {
   if (!v) {
-    videoEl.value.currentTime = 0
-    videoEl.value.play()
+    videoEl.value.videoRef.currentTime = 0
+    videoEl.value.videoRef.play()
   }
 })
 
 function onVideoEnd() {
+  videoEl.value.videoRef.pause()
   store.commit('setHaveShownStartUp', true)
   URL.revokeObjectURL(startUpVideo)
 }
@@ -159,11 +151,6 @@ function onVideoPlay() {
 }
 
 const isShowSkip = ref(false)
-function onClickSkip() {
-  videoEl.value.pause()
-  store.commit('setHaveShownStartUp', true)
-  // startUpAudio.pause()
-}
 </script>
 
 <style lang="less" scoped>
@@ -272,7 +259,7 @@ function onClickSkip() {
   scale: 1.4;
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .start-up > button.start {
     width: 320px;
   }

+ 1 - 1
src/components/UserGuide.vue

@@ -546,7 +546,7 @@ const handleClose = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .user-guide {
     .btn,
     .left-line,

+ 146 - 0
src/components/VideoAdapter.vue

@@ -0,0 +1,146 @@
+<template>
+  <div class="video-adapter">
+    <transition name="fade-in">
+      <button
+        v-if="showSkip"
+        class="video-adapter__skip"
+        @click="handleEnd"
+      />
+    </transition>
+
+    <img
+      v-if="showVideoPlay && showPlay"
+      class="video-adapter__play"
+      src="@/assets/images/play.png"
+      @click="() => {
+        videoRef?.play()
+        showVideoPlay = false
+      }"
+    >
+
+    <video
+      ref="videoRef"
+      :poster="poster"
+      :src="src"
+      :autoplay="autoplay"
+      :muted="muted"
+      x5-playsinline="true"
+      playsinline="true"
+      webkit-playsinline="true"
+      x-webkit-airplay="true"
+      x5-video-player-type="h5-page"
+      :style="{
+        objectFit: $mediaNeedContain ? 'contain' : 'cover',
+        objectPosition
+      }"
+      @play="showVideoPlay = false"
+      @ended="handleEnd"
+    />
+
+    <slot />
+  </div>
+</template>
+
+<script setup>
+import { inject, ref, defineExpose } from "vue"
+
+defineProps({
+  src: {
+    required: true,
+    type: String
+  },
+  poster: {
+    default: '',
+    type: String
+  },
+  autoplay: {
+    default: true,
+    type: Boolean
+  },
+  muted: {
+    default: false,
+    type: Boolean
+  },
+  showSkip: {
+    default: true,
+    type: Boolean
+  },
+  showPlay: {
+    default: true,
+    type: Boolean
+  },
+  objectPosition: {
+    default: 'center',
+    type: String
+  }
+})
+const emits = defineEmits(['ended'])
+const $mediaNeedContain = inject('$mediaNeedContain')
+const $isMobile = inject('$isMobile')
+const videoRef = ref()
+const showVideoPlay = ref($isMobile)
+
+const handleEnd = () => {
+  emits('ended')
+}
+
+const toEnd = () => {
+  videoRef.value.currentTime = videoRef.value.duration
+}
+
+defineExpose({
+  videoRef,
+  toEnd
+})
+</script>
+
+<style lang="less" scoped>
+.video-adapter {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, .8);
+  backdrop-filter: blur(10px);
+  z-index: 999;
+
+  video {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    object-position: center;
+    z-index: 1;
+  }
+  &__skip{
+    position: absolute;
+    width: 220px;
+    height: 58px;
+    right: 50px;
+    bottom: 50px;
+    background-image: url(@/assets/images/startup-video-skip.png);
+    background-size: cover;
+    background-repeat: no-repeat;
+    background-position: center center;
+    z-index: 2;
+  }
+  &__play {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    width: 120px;
+    transform: translate(-50%, -50%);
+    z-index: 2;
+  }
+}
+
+@media screen and (max-height: 740px) {
+  .video-adapter{
+    &__skip {
+      width: 320px;
+    }
+  }
+}
+</style>

+ 11 - 2
src/main.js

@@ -1,4 +1,4 @@
-import { createApp } from 'vue'
+import { createApp, ref } from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
@@ -40,13 +40,19 @@ if (uaInfo.browser && uaInfo.browser.name === 'WeChat') {
 if (uaInfo.browser && uaInfo.browser.name === 'Safari') {
   app.provide('$isSafari', true)
 }
-if (uaInfo.device.type === 'mobile') {
+if (uaInfo.device.type === 'mobile' || uaInfo.device.type === 'tablet') {
   app.provide('$isMobile', true)
 }
 
+const getNeedContain = () => {
+  const scale = Math.round(window.innerWidth / window.innerHeight * 100) / 100
+  return scale <= 1.47 || scale >= 2.45
+}
+
 // 处理resize事件
 let windowWidthLast = window.innerWidth
 let windowHeightLast = window.innerHeight
+const $mediaNeedContain = ref(getNeedContain())
 function onResize() {
   if (window.innerWidth === windowWidthLast) {
     // 发生了高度变化,认为发生了软键盘显隐
@@ -60,7 +66,10 @@ function onResize() {
   }
   windowWidthLast = window.innerWidth
   windowHeightLast = window.innerHeight
+
+  $mediaNeedContain.value = getNeedContain()
 }
+app.provide('$mediaNeedContain', $mediaNeedContain)
 window.addEventListener('resize', () => {
   onResize()
 })

+ 8 - 1
src/preloadList.js

@@ -2,7 +2,7 @@ import UAParser from "@/libs/ua-parser.min.js"
 
 const uaParser = new UAParser()
 const uaInfo = uaParser.getResult()
-const isMobile = uaInfo.device.type === 'mobile'
+const isMobile = uaInfo.device.type === 'mobile' || uaInfo.device.type === 'tablet'
 
 export default [
   require('@/assets/images/pose1-min.png'),
@@ -53,4 +53,11 @@ export default [
   // require('@/assets/videos/screen/screensaver-2-3.mp4'),
   // require('@/assets/videos/screen/screensaver-3-1.mp4'),
   // require('@/assets/videos/screen/screensaver-3-2.mp4'),
+
+  require('@/assets/images/scene-entry-1.png'),
+  require('@/assets/images/scene-entry-2.png'),
+  require('@/assets/images/scene-entry-3.png'),
+  require('@/assets/images/scene-entry-1-active.png'),
+  require('@/assets/images/scene-entry-2-active.png'),
+  require('@/assets/images/scene-entry-3-active.png'),
 ]

+ 2 - 2
src/views/EpilogueView.vue

@@ -193,7 +193,7 @@ function onClickOfflineMuseumEntry() {
     left: 158px;
     width: 298px;
   }
-  @media screen and (max-height: 480px) {
+  @media screen and (max-height: 740px) {
     >img.character{
       left: -20px;
     }
@@ -311,7 +311,7 @@ function onClickOfflineMuseumEntry() {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .epilogue-view {
     > .bottom-wrap > .button-group img {
       width: 320px !important;

+ 78 - 76
src/views/HomeView.vue

@@ -25,88 +25,90 @@
         >
       </div>
     </transition>
-    <template v-if="!$isMobile">
-      <transition
-        v-for="idx in 3"
-        :key="idx"
-        name="fade-in-out"
-      >
-        <div
-          v-if="hoveringEntryIdx === idx"
-          :class="`scene-preview scene-preview-${idx}`"
-          @click="goToDetail(idx)"
-        >
-          <img
-            class="bg"
-            :src="require(`@/assets/images/scene-${idx}-preview.jpg`)"
-            alt=""
-            draggable="false"
-          >
-          <img
-            class="title"
-            :src="require(`@/assets/images/scene-preview-title-${idx}.png`)"
-            alt=""
-            draggable="false"
-          >
-        </div>
-      </transition>
-    </template>
-    <template v-else-if="store.state.haveShownStartUp">
-      <Swiper
-        class="scene-preview swiper-scene-preview"
-        :initial-slide="hoveringEntryIdx - 1"
-        auto-height
-        @slide-change="(e) => {
-          hoveringEntryIdx = e.activeIndex + 1
-        }"
-        @swiper="e => swiper = e"
-      >
-        <SwiperSlide
+
+    <template v-if="store.state.canStart">
+      <template v-if="!$isMobile">
+        <transition
           v-for="idx in 3"
           :key="idx"
-          :class="`scene-preview-${idx}`"
-          @click="goToDetail(idx)"
+          name="fade-in-out"
         >
-          <img
-            class="bg"
-            :src="require(`@/assets/images/scene-${idx}-preview.jpg`)"
-            alt=""
-            draggable="false"
+          <div
+            v-if="hoveringEntryIdx === idx"
+            :class="`scene-preview scene-preview-${idx}`"
+            @click="goToDetail(idx)"
           >
-          <img
-            class="title"
-            :src="require(`@/assets/images/scene-preview-title-${idx}.png`)"
-            alt=""
-            draggable="false"
+            <img
+              class="bg"
+              :src="require(`@/assets/images/scene-${idx}-preview.jpg`)"
+              alt=""
+              draggable="false"
+            >
+            <img
+              class="title"
+              :src="require(`@/assets/images/scene-preview-title-${idx}.png`)"
+              alt=""
+              draggable="false"
+            >
+          </div>
+        </transition>
+      </template>
+      <template v-else-if="store.state.haveShownStartUp">
+        <Swiper
+          class="scene-preview swiper-scene-preview"
+          :initial-slide="hoveringEntryIdx - 1"
+          @slide-change="(e) => {
+            hoveringEntryIdx = e.activeIndex + 1
+          }"
+          @swiper="e => swiper = e"
+        >
+          <SwiperSlide
+            v-for="idx in 3"
+            :key="idx"
+            :class="`scene-preview-${idx}`"
+            @click="goToDetail(idx)"
           >
-        </SwiperSlide>
-      </Swiper>
-    </template>
+            <img
+              class="bg"
+              :src="require(`@/assets/images/scene-${idx}-preview.jpg`)"
+              alt=""
+              draggable="false"
+            >
+            <img
+              class="title"
+              :src="require(`@/assets/images/scene-preview-title-${idx}.png`)"
+              alt=""
+              draggable="false"
+            >
+          </SwiperSlide>
+        </Swiper>
+      </template>
 
-    <button
-      v-if="store.state.haveShownStartUp"
-      class="logo"
-      @click="onClickLogo"
-    >
-      <img
-        src="@/assets/images/logo-bright.png"
-        alt=""
-        draggable="false"
-      >
-    </button>
-    <div class="btn-group">
       <button
-        v-for="idx of 3"
-        :key="idx"
-        :class="`scene-entry entry-${idx} ${($isMobile && idx === hoveringEntryIdx) ? 'hover' : ''}`"
-        @mouseenter="!$isMobile && (hoveringEntryIdx = idx)"
-        @mouseleave="!$isMobile && (hoveringEntryIdx = 0)"
-        @click="handleGroup(idx)"
-      />
-    </div>
+        v-if="store.state.haveShownStartUp"
+        class="logo"
+        @click="onClickLogo"
+      >
+        <img
+          src="@/assets/images/logo-bright.png"
+          alt=""
+          draggable="false"
+        >
+      </button>
+      <div class="btn-group">
+        <button
+          v-for="idx of 3"
+          :key="idx"
+          :class="`scene-entry entry-${idx} ${($isMobile && idx === hoveringEntryIdx) ? 'hover' : ''}`"
+          @mouseenter="!$isMobile && (hoveringEntryIdx = idx)"
+          @mouseleave="!$isMobile && (hoveringEntryIdx = 0)"
+          @click="handleGroup(idx)"
+        />
+      </div>
+    </template>
   </div>
 
-  <template v-if="$isMobile">
+  <template v-if="$isMobile && store.state.canStart">
     <img
       v-if="showHelper"
       class="mobile-helper"
@@ -137,7 +139,7 @@ import { Swiper, SwiperSlide } from "swiper/vue"
 const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
-} = useSizeAdapt()
+} = useSizeAdapt(1920, 970)
 
 let swiper = null
 const $isMobile = inject('$isMobile')
@@ -255,7 +257,7 @@ const handleHover = (num) => {
     >img.bg-default{
       position: absolute;
       width: 100%;
-      height: calc(891 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: 83%;
       left: 0;
       top: 0;
       object-fit: cover;
@@ -271,7 +273,7 @@ const handleHover = (num) => {
   >.scene-preview{
     position: absolute;
     width: 100%;
-    height: calc(891 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: 83%;
     left: 0;
     top: 0;
     >img.bg{

+ 60 - 69
src/views/PanoView.vue

@@ -336,65 +336,46 @@
     </template>
     <template v-else>
       <transition name="fade-in-out-slow">
-        <div
+        <VideoAdapter
           v-if="isShowCameraIntro"
-          class="text-wrap"
-        >
-          <button
-            class="skip"
-            @click="skipCameraIntro"
-          />
-          <img
-            v-if="showVideoPlay"
-            class="pano-play-icon"
-            src="@/assets/images/play.png"
-            @click="() => {
-              videoRef?.play()
-              showVideoPlay = false
-            }"
-          >
-          <video
-            ref="videoRef"
-            :poster="require(`@/assets/images/mobile-intro/${toggleCameraVideoName}.jpg`)"
-            :src="require(`@/assets/videos/mobile-intro/${toggleCameraVideoName}.mp4`)"
-            autoplay
-            x5-playsinline="true"
-            playsinline="true"
-            webkit-playsinline="true"
-            x-webkit-airplay="true"
-            x5-video-player-type="h5-page"
-            style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; object-position: bottom;"
-            @play="showVideoPlay = false"
-            @ended="skipCameraIntro"
-          />
-        </div>
+          :poster="require(`@/assets/images/mobile-intro/${toggleCameraVideoName}.jpg`)"
+          :src="require(`@/assets/videos/mobile-intro/${toggleCameraVideoName}.mp4`)"
+          :object-position="$mediaNeedContain ? 'center' : 'center bottom'"
+          @ended="skipCameraIntro"
+        />
       </transition>
     </template>
     <!-- end of 镜头切换过渡 -->
     <!-- 场景切换过渡 -->
-    <video
+    <VideoAdapter
       v-show="isShowSceneIntroVideoStart"
       ref="sceneIntrovideoStartEl"
-      class="scene-intro-video scene-intro-video-start"
+      :show-play="false"
+      :show-skip="false"
       :src="videoIntroUrl"
-      x5-playsinline="true"
-      playsinline="true"
-      webkit-playsinline="true"
-      x-webkit-airplay="true"
-      x5-video-player-type="h5-page"
       @ended="onPlayedFirstSceneIntroVideoEnded"
-    />
-    <button
-      v-show="isShowSceneIntroVideoStart"
-      class="skip-scene-intro"
-      :style="{
-        left: skipBtnLeftTop.x + 'px',
-        top: skipBtnLeftTop.y + 'px',
-        width: skipBtnRightBottom.x - skipBtnLeftTop.x + 'px',
-        height: skipBtnRightBottom.y - skipBtnLeftTop.y + 'px',
-      }"
-      @click="skipFirstSceneIntro"
-    />
+    >
+      <button
+        v-if="!$mediaNeedContain"
+        class="skip-scene-intro"
+        :style="{
+          left: skipBtnLeftTop.x + 'px',
+          top: skipBtnLeftTop.y + 'px',
+          width: skipBtnRightBottom.x - skipBtnLeftTop.x + 'px',
+          height: skipBtnRightBottom.y - skipBtnLeftTop.y + 'px',
+        }"
+        @click="skipFirstSceneIntro"
+      />
+      <button
+        v-else
+        class="skip-scene-intro-contain"
+        :style="{
+          width: skipBtnRightBottom.x - skipBtnLeftTop.x + 'px',
+          height: skipBtnRightBottom.y - skipBtnLeftTop.y + 'px',
+        }"
+        @click="skipFirstSceneIntro"
+      />
+    </VideoAdapter>
     <!-- end of 场景切换过渡 -->
 
     <MsgContent
@@ -473,7 +454,9 @@ import MutiRelicHotSpot from "@/components/MutiRelicHotSpot.vue"
 import ShipGameView from '@/views/ShipGame/ShipGameView.vue'
 import GameEntryPage from '@/components/GameEntryPage.vue'
 import ScreenSaver from '@/components/ScreenSaver.vue'
+import VideoAdapter from '@/components/VideoAdapter.vue'
 
+const $mediaNeedContain = inject('$mediaNeedContain')
 const $isMobile = inject('$isMobile')
 const GUIDE_KEY = 'is-open-guide'
 const msgVisible = ref(false)
@@ -481,8 +464,7 @@ const curMsgIndex = ref(0)
 const showGuide = ref(false)
 const showShipGame = ref(false)
 const showScreensaver = ref(false)
-const showVideoPlay = ref(true)
-const videoRef = ref()
+
 let screensaverTime = 0
 let screensaverTimer = null
 
@@ -807,7 +789,6 @@ watch(cameraIdx, (vNew, pVal) => {
 
 // 跳过按钮 功能
 function skipCameraIntro(showAction, routeChange) {
-  showVideoPlay.value = true
   clearTimeout(cameraIntroAudioTimeoutId)
   !$isMobile && sceneIntroaudioStartEl.value?.pause()
   clearCameraIntroMedia(showAction, routeChange)
@@ -842,7 +823,7 @@ watch(sceneIdx, (vNew) => {
     isShowSceneIntroVideoStart.value = true
     nextTick(() => {
       setTimeout(() => {
-        sceneIntrovideoStartEl.value.play()
+        sceneIntrovideoStartEl.value.videoRef.play()
       }, 500)
     })
   } else if (!$isMobile) {
@@ -924,14 +905,14 @@ function skipSceneIntro() {
   })
   isShowSceneIntroVideoStart.value = false
   isShowSceneIntroVideoEnd.value = false
-  sceneIntrovideoStartEl.value?.pause()
+  sceneIntrovideoStartEl.value?.videoRef.pause()
   sceneIntrovideoEndEl.value?.pause()
 }
 function skipFirstSceneIntro() {
   if (jumpIntroduceDisable) return
 
   jumpIntroduceDisable = true
-  const video = sceneIntrovideoStartEl.value
+  // const video = sceneIntrovideoStartEl.value.videoRef
   // 不需要过渡
   // switch (sceneIdx.value) {
   // case 0:
@@ -943,7 +924,8 @@ function skipFirstSceneIntro() {
   // default:
   //   video.currentTime = $isMobile ? 31 : 31
   // }
-  video.currentTime = video.duration
+  // video.currentTime = video.duration
+  sceneIntrovideoStartEl.value.toEnd()
 }
 onUnmounted(() => {
   skipSceneIntro()
@@ -1753,27 +1735,26 @@ const {
   /**
    * 场景切换过渡
    */
-  >video.scene-intro-video{
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-    height: 100%;
-    object-fit: cover;
-    z-index: 20;
-  }
-  >button.skip-scene-intro{
+  button.skip-scene-intro{
     position: absolute;
     z-index: 21;
     // background-color: red;
     // opacity: 0.5;
   }
+  .skip-scene-intro-contain {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    margin-top: calc(300 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    transform: translate(-50%, -50%);
+    z-index: 21;
+  }
   /**
    * end of 场景切换过渡
    */
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .skip-scene-intro {
     top: unset !important;
     padding: 20px;
@@ -1807,6 +1788,16 @@ const {
   }
 }
 
+@media screen and (min-height: 480px) and (max-height: 740px) {
+  .skip-scene-intro {
+    top: unset !important;
+    padding: 20px;
+    margin-left: calc(-20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    bottom: calc(150 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    box-sizing: content-box;
+  }
+}
+
 .pano-play-icon {
   position: absolute;
   top: 50%;
@@ -1818,7 +1809,7 @@ const {
 </style>
 
 <style lang="less">
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .pano-view > .text-wrap {
     .text,
     .text p {

+ 1 - 1
src/views/RelicDetail.vue

@@ -336,7 +336,7 @@ const handleFull = () => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .relic-detail {
     :deep(.left > .swiper-root > .swiper-pagination > span) {
       --swiper-pagination-bullet-horizontal-gap: 0.6vw;

+ 1 - 1
src/views/RelicList.vue

@@ -537,7 +537,7 @@ const handleScroll = debounce(() => {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .relic-list > button.return {
     left: calc(42 / 970* 100vh);
     top: calc(48 / 970* 100vh);

+ 1 - 1
src/views/RelicListMobile.vue

@@ -535,7 +535,7 @@ const {
   }
 }
 
-@media screen and (max-height: 480px) {
+@media screen and (max-height: 740px) {
   .relic-list > .the-list {
     .content-wrap {
       margin-top: 0;

+ 10 - 37
src/views/ShipGame/ShipGameView.vue

@@ -105,55 +105,22 @@
       </div>
 
       <template v-if="showVideo">
-        <video
-          ref="videoRef"
-          class="video"
-          autoplay
+        <VideoAdapter
           muted
-          x5-playsinline="true"
-          playsinline="true"
-          webkit-playsinline="true"
-          x-webkit-airplay="true"
-          x5-video-player-type="h5-page"
-          src="@/assets/videos/ship-game/end.mp4"
-          @play="() => {
-            showVideoPlay = false
-          }"
+          :src="require('@/assets/videos/ship-game/end.mp4')"
           @ended="back"
         />
-
-        <img
-          class="video-skip"
-          src="@/assets/images/startup-video-skip.png"
-          @click="back"
-        >
-
-        <div
-          v-if="showVideoPlay"
-          class="play-icon"
-        >
-          <img
-            v-if="$isMobile"
-            src="@/assets/images/play.png"
-            @click="() => {
-              videoRef?.play()
-            }"
-          >
-        </div>
       </template>
     </template>
   </div>
 </template>
 
 <script setup>
-import { ref, watch, inject } from 'vue'
+import { ref, watch } from 'vue'
 // import { useRouter } from 'vue-router'
 import { Container, Draggable } from "vue3-smooth-dnd"
+import VideoAdapter from '@/components/VideoAdapter.vue'
 
-// const router = useRouter()
-const $isMobile = inject('$isMobile')
-const showVideoPlay = ref(true)
-const videoRef = ref(null)
 const showBanner = ref(false)
 const showVideo = ref(false)
 const {
@@ -458,4 +425,10 @@ const back = () => {
     }
   }
 }
+
+@media screen and (min-height: 480px) and (max-height: 900px) {
+  .ship-game-container {
+    top: calc(200 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  }
+}
 </style>