Просмотр исходного кода

Merge branch 'master' of http://face3d.4dage.com:7005/renyicun/NanjingMuseumWuJinZang into master

shaogen1995 1 год назад
Родитель
Сommit
ff1d9408c8

+ 5 - 0
src/App.vue

@@ -11,6 +11,11 @@
   </router-view>
   <audio
     id="bg-music"
+    src="./configMultiMedia/music/music1.mp3"
+    style="opacity: 0;"
+  />
+  <audio
+    id="bg-music2"
     src="./configMultiMedia/music/music2.mp3"
     style="opacity: 0;"
   />

BIN
src/assets/images/loding_apng.png


BIN
src/assets/videos/fade-at-shuang-gou.mp4


+ 4 - 2
src/components/BtnSkip.vue

@@ -1,6 +1,8 @@
 <template>
   <div
-    v-show="isReady"
+    :style="{
+      opacity: isReady ? 1 : 0,
+    }"
     class="btn-skip"
   >
     <div class="text">
@@ -57,7 +59,7 @@ onMounted(()=>{
   align-items: center;
   z-index: 30;
   >.text{
-    font-family: KingHwa_OldSong, KingHwa_OldSong;
+    // font-family: KingHwa_OldSong;
     font-weight: 400;
     font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     color: #FFFFFF;

+ 164 - 45
src/views/BambooHotView2/index.vue

@@ -49,7 +49,10 @@
           hide: hotVisible && checkedHotId !== 2
         }"
       >
-        <img src="./images/bamboo2.png">
+        <img
+          src="./images/bamboo2.png"
+          @load="handleBambooOffset(2)"
+        >
       </div>
       <div
         class="bamboo-hot2__hot b2"
@@ -67,7 +70,10 @@
           hide: hotVisible && checkedHotId !== 3
         }"
       >
-        <img src="./images/bamboo3.png">
+        <img
+          src="./images/bamboo3.png"
+          @load="handleBambooOffset(3)"
+        >
 
         <div
           class="bamboo-hot2__hot"
@@ -86,7 +92,10 @@
           hide: hotVisible && checkedHotId !== 4
         }"
       >
-        <img src="./images/bamboo4.png">
+        <img
+          src="./images/bamboo4.png"
+          @load="handleBambooOffset(4)"
+        >
 
         <div
           class="bamboo-hot2__hot"
@@ -132,7 +141,10 @@
           hide: hotVisible && checkedHotId !== 8
         }"
       >
-        <img src="./images/bamboo8.png">
+        <img
+          src="./images/bamboo8.png"
+          @load="handleBambooOffset(8)"
+        >
 
         <div
           class="bamboo-hot2__hot"
@@ -199,6 +211,7 @@
         class="bamboo-hot2-bg-wrap"
       >
         <img
+          v-if="bgImgLoaded"
           class="bamboo-hot2__grass"
           :class="{
             hide: hotVisible
@@ -209,6 +222,10 @@
         <img
           class="bamboo-hot2__bg"
           src="./images/bg.png"
+          :style="{
+            filter: hotVisible ? 'saturate(1.3) brightness(0.95)' : 'none'
+          }"
+          @load="bgImgLoaded = true"
         >
       </div>
     </div>
@@ -226,16 +243,16 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, watch, onBeforeUnmount } from 'vue'
 import { useRouter } from 'vue-router'
 import useSizeAdapt from "@/useFunctions/useSizeAdapt"
 
-const ITEM_SCROLL_MAP = {
-  1: 10,
+let itemScrollMap = {
+  1: 0,
   2: 166,
-  3: 231,
-  4: 420,
-  8: 958
+  3: 201,
+  4: 450,
+  8: 1048
 }
 const ITEM_INFO_MAP = {
   1: {
@@ -281,13 +298,13 @@ const ITEM_INFO_MAP = {
   },
 }
 
+const bgImgLoaded = ref(false)
 const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
 } = useSizeAdapt()
 const router = useRouter()
-let startX = 0
-let lastStartX = 0
+
 const bambooWrap = ref()
 const bambooWrapBg = ref()
 
@@ -298,42 +315,126 @@ const handleHot = (id) => {
   checkedHotId.value = id
   hotVisible.value = true
 
+  cancelAnimationFrame(animationFrameId.value)
   bambooWrap.value.scrollTo({
-    left: ITEM_SCROLL_MAP[id],
+    left: itemScrollMap[id],
     behavior: 'smooth'
   })
-
-  lastStartX = ITEM_SCROLL_MAP[id]
+  translateX.value = itemScrollMap[id]
 }
 
-const handleTouchstart = (v) => {
-  if (hotVisible.value) return
-
-  startX = v.changedTouches[0].pageX
+const handleBambooOffset = (target) => {
+  const offset = window.innerWidth / 6
+  const left = document.getElementsByClassName(`bamboo-hot2-b${target}`)?.[0].getBoundingClientRect().left
+  let temp = 0
+  switch (target) {
+  case 3:
+    temp = window.innerWidth / 3
+    break
+  case 4:
+    temp = -(window.innerWidth * 0.25)
+    break
+  case 8:
+    temp = -(window.innerWidth * 0.7)
+    break
+  }
+  itemScrollMap[target] = left - offset + temp
 }
-const handleTouchmove = (v) => {
-  v.preventDefault()
-  if (hotVisible.value) return
 
-  const wrapWidth = bambooWrapBg.value.scrollWidth - window.innerWidth
-  const moveX = startX - v.changedTouches[0].pageX
+// 动画帧相关
+const lastAnimationTimeStamp = ref(0)
+const animationFrameId = ref(0)
+const moveSpeed = ref(0)
+const translateX = ref(0)
+const maxTranslateXLength = ref(0)
+const lastMoveEventTimeStamp = ref(0)
+const isMouseDown = ref(false)
+const isMove = ref(false)
+const lastTouchPos = ref(0)
+
+watch([bambooWrapBg, bgImgLoaded], () => {
+  if (!bgImgLoaded.value) return
+
+  maxTranslateXLength.value = bambooWrapBg.value ? bambooWrapBg.value.scrollWidth - window.innerWidth : 0
+  animationFrameId.value = requestAnimationFrame(animationFrameTask)
+})
+
+const animationFrameTask = () => {
+  const timeStamp = Date.now()
+  const timeElapsed = timeStamp - lastAnimationTimeStamp.value
+
+  // 速度减慢
+  if (moveSpeed.value > 0) {
+    moveSpeed.value -= 0.003 * timeElapsed
+    if (moveSpeed.value < 0) {
+      moveSpeed.value = 0
+    }
+  } else if (moveSpeed.value < 0) {
+    moveSpeed.value += 0.003 * timeElapsed
+    if (moveSpeed.value > 0) {
+      moveSpeed.value = 0
+    }
+  }
+
+  // 根据速度更新距离
+  translateX.value += moveSpeed.value * timeElapsed
+  if (translateX.value < 0) {
+    translateX.value = 0
+  } else if (translateX.value > maxTranslateXLength.value) {
+    translateX.value = maxTranslateXLength.value
+    moveSpeed.value = 0
+  }
 
-  bambooWrap.value.scrollTo({
-    left: Math.min(moveX + lastStartX, wrapWidth),
+  bambooWrap.value?.scrollTo({
+    left: translateX.value,
     behavior: 'instant'
   })
+  lastAnimationTimeStamp.value = timeStamp
+  animationFrameId.value = requestAnimationFrame(animationFrameTask)
+}
+
+const handleTouchstart = (e) => {
+  if (hotVisible.value) return
+
+  isMouseDown.value = true
+  moveSpeed.value = 0
+  lastMoveEventTimeStamp.value = 0
+  lastAnimationTimeStamp.value = Date.now()
+  lastTouchPos.value = e.changedTouches[0].clientX
+}
+const handleTouchmove = (e) => {
+  e.preventDefault()
+  if (hotVisible.value || !isMouseDown.value || !e.changedTouches.length) return
+
+  if (
+    lastMoveEventTimeStamp.value &&
+    e.timeStamp - lastMoveEventTimeStamp.value > 1
+  ) {
+    // 更新speed
+    isMove.value = true
+    const currentMoveSpeed =
+      (-(e.changedTouches[0].clientX - lastTouchPos.value) /
+        (e.timeStamp - lastMoveEventTimeStamp.value)) *
+      1.5
+    moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
+    lastTouchPos.value = e.changedTouches[0].clientX
+  }
+  lastMoveEventTimeStamp.value = e.timeStamp
 }
-const handleTouchend = (v) => {
+const handleTouchend = () => {
   if (hotVisible.value) return
 
-  const wrapWidth = bambooWrapBg.value.scrollWidth - window.innerWidth
-  lastStartX = Math.min(Math.max(startX - v.changedTouches[0].pageX + lastStartX, 0), wrapWidth)
+  isMouseDown.value = false
+  setTimeout(() => {
+    isMove.value = false
+  })
 }
 
 const goBack = () => {
   if (hotVisible.value) {
     hotVisible.value = false
     checkedHotId.value = 0
+    animationFrameId.value = requestAnimationFrame(animationFrameTask)
     return
   }
 
@@ -344,6 +445,10 @@ const goBack = () => {
     }
   })
 }
+
+onBeforeUnmount(() => {
+  cancelAnimationFrame(animationFrameId.value)
+})
 </script>
 
 <style lang="less" scoped>
@@ -357,6 +462,7 @@ img {
 
 .hide {
   opacity: 0 !important;
+  animation: none !important;
 }
 
 [class^="bamboo-hot2-b"] {
@@ -429,6 +535,7 @@ img {
     font-size: 12px;
     font-family: KaiTi;
     writing-mode: vertical-rl;
+    animation: breathing linear 2s infinite;
 
     &::before {
       content: '';
@@ -441,7 +548,7 @@ img {
   }
   &-b1 {
     left: calc(50 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(20 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.8);
 
     .bamboo-hot2__hot {
       top: calc(340 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
@@ -450,18 +557,18 @@ img {
   }
   &-b2 {
     left: calc(250 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(10 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
     z-index: 2;
   }
   .bamboo-hot2__hot.b2 {
     top: calc(200 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
     left: calc(305 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(10 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
     z-index: 4;
   }
   &-b3 {
-    left: calc(155 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(5px);
+    left: calc(140 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
+    transform: translateZ(calc(20 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.8);
 
     .bamboo-hot2__hot {
       top: calc(300 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
@@ -470,7 +577,7 @@ img {
   }
   &-b4 {
     left: calc(600 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(5px);
+    transform: translateZ(calc(15 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.85);
 
     .bamboo-hot2__hot {
       top: calc(220 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
@@ -479,20 +586,20 @@ img {
   }
   &-b5 {
     left: calc(1050 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(20 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.8);
   }
   &-b6 {
     left: calc(1170 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(15px);
+    transform: translateZ(calc(15 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
   }
   &-b7 {
     left: calc(1050 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(10 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
     z-index: 2;
   }
   &-b8 {
     left: calc(1180 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(5px);
+    transform: translateZ(calc(25 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.8);
 
     .bamboo-hot2__hot {
       top: calc(320 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
@@ -501,30 +608,30 @@ img {
   }
   &-b9 {
     left: calc(1480 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(20 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.82);
   }
   &-b10 {
     left: calc(1810 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(10 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
   }
   &-b11 {
     left: calc(1790 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(5px);
+    transform: translateZ(calc(5 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
     z-index: 2;
   }
   &-b12 {
     left: calc(1600 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(15px);
+    transform: translateZ(calc(15 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
     z-index: 2;
   }
   &-b13 {
     left: calc(2050 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(15px);
+    transform: translateZ(calc(15 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef')));
     z-index: 2;
   }
   &-b14 {
     left: calc(2220 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'));
-    transform: translateZ(10px);
+    transform: translateZ(calc(30 /v-bind('windowSizeWhenDesignForRef')* v-bind('windowSizeInCssForRef'))) scale(0.7);
   }
   &.wrap-hide {
     &::before,
@@ -589,4 +696,16 @@ img {
     transition: opacity 0.5s ease-in-out;
   }
 }
+
+@keyframes breathing {
+  0% {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.3;
+  }
+  100% {
+    opacity: 1;
+  }
+}
 </style>

+ 17 - 4
src/views/HotspotDetail3.vue

@@ -27,15 +27,19 @@
     >
 
     <img
-      v-show="state == 1"
       class="content1"
       :src="hots3StateContent1"
+      :style="{
+        opacity: state === 1 ? 1 : 0
+      }"
       alt=""
     >
     <div
-      v-show="state == 2"
       id="content2"
       ref="content2Dom"
+      :style="{
+        opacity: state === 2 ? 1 : 0
+      }"
       class="content2"
     >
       <img
@@ -45,8 +49,10 @@
       >
     </div>
     <img
-      v-show="state == 3"
       class="content3"
+      :style="{
+        opacity: state === 3 ? 1 : 0
+      }"
       :src="hots3StateContent3"
       alt=""
     >
@@ -188,6 +194,7 @@ const goState2 = () => {
     position: absolute;
     left: 50%;
     transform: translateX(-50%);
+    transition: opacity 1s ease;
     bottom: calc(130 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
 
@@ -195,6 +202,8 @@ const goState2 = () => {
     width: 100%;
     background-position: left top;
     overflow: auto;
+    position: absolute;
+    transition: opacity 1s ease;
 
     img {
       // height: 50vh;
@@ -202,7 +211,11 @@ const goState2 = () => {
     }
   }
 
-  .content3 {}
+  .content3 {
+    position: absolute;
+    width: 100%;
+    transition: opacity 1s ease;
+  }
 
   .operation-tip {
     position: fixed;

+ 4 - 0
src/views/MoreContent.vue

@@ -1142,6 +1142,10 @@ onMounted(() => {
 
         > .button-group {
           position: absolute;
+          width: calc(
+              20 / v-bind("windowSizeWhenDesignForRef") *
+                v-bind("windowSizeInCssForRef")
+            );
           top: calc(
             75px * v-bind("windowHeight") / v-bind("windowHeightDesign")
           );

+ 1 - 1
src/views/PaintingList.vue

@@ -313,7 +313,7 @@ const unwatch = watch(menuElScrollLeft, (v) => {
     position: absolute;
     left: 0;
     top: 0;
-    width: 100%;
+    width: 100vw;
     height: 100%;
     display: flex;
     overflow: auto;

+ 17 - 1
src/views/StartupView.vue

@@ -13,6 +13,13 @@
     /> -->
 
     <img
+      class="bg-serial-frames"
+      src="@/assets/images/loding_apng.png"
+      alt=""
+      draggable="false"
+    >
+
+    <img
       class="title"
       src="@/assets/images/startup-title.png"
       alt=""
@@ -96,9 +103,16 @@ const videoEl = ref(null)
 function onClickStart() {
   isShowVideo.value = true
   const audioEl = document.getElementById('bg-music')
+  const audioEl2 = document.getElementById('bg-music2')
   nextTick(() => {
     videoEl.value.play()
-    audioEl.play()
+    if (window.location.href.includes('?m=2')) {
+      audioEl2.play()
+      console.log('播放2')
+    } else {
+      audioEl.play()
+      console.log('播放1')
+    }
   })
   setTimeout(() => {
     isShowSkip.value = true
@@ -133,6 +147,8 @@ function onVideoEnd() {
     top: 0;
     transform: translateX(-50%);
     mix-blend-mode: multiply;
+    width: 100%;
+    height: 100%;
   }
 
   >img.title{