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

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

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

BIN
src/assets/images/game-tip-cancel.png


BIN
src/assets/images/game-tip-yes.png


BIN
src/assets/images/game-tip.png


+ 201 - 47
src/views/HomeView.vue

@@ -1,5 +1,6 @@
 <template>
   <div
+
     class="home"
   >
     <div class="bg-mask" />
@@ -75,7 +76,6 @@
       >
       <img
         class="painting"
-
         src="@/assets/images/home-painting.jpg"
         alt=""
         draggable="false"
@@ -136,6 +136,8 @@
     <!-- 文字介绍 -->
     <div
       ref="longDesc"
+      v-touch:swipe.left="onSwipeLeft"
+      v-touch:swipe.right="onSwipeRight"
       class="long-desc"
       :style="{
         top: `${(paintingTop + paintingHeight + 53) / windowSizeWhenDesignForRef * windowSizeInCssForRef.substring(0, windowSizeInCssForRef.length - 2)}px`,
@@ -194,9 +196,7 @@
       {{ summaryDesc }}
     </div>
 
-    <div
-      class="progress-bar"
-    >
+    <div class="progress-bar">
       <div class="bar-artwork-desc" />
       <img
         class="progress-bar-node-1"
@@ -236,6 +236,8 @@
 
     <div
       ref="scrollerEl"
+      v-touch:swipe.left="onSwipeLeft"
+      v-touch:swipe.right="onSwipeRight"
       class="scroller"
     >
       <div
@@ -346,6 +348,8 @@ const scrollerEl = ref(null)
 const scrollerElScrollTop = ref(0)
 function onScroll() {
   scrollerElScrollTop.value = scrollerEl.value.scrollTop
+
+  // console.log('当前高度', scrollerElScrollTop.value / scrollerEl.value.scrollHeight )
 }
 onMounted(() => {
   scrollerEl.value.addEventListener('scroll', onScroll)
@@ -465,9 +469,9 @@ const longDescOpacity = computed(() => {
 })
 watch(scrollerElScrollTop, (vNew, vOld) => {
   if (vNew > paintingMoveUpFinishAt) {
-    longDesc.value.scrollTop = vNew - paintingMoveUpFinishAt
+    // longDesc.value.scrollTop = vNew - paintingMoveUpFinishAt
   } else if (vNew < vOld && vNew <= paintingMoveUpFinishAt) {
-    longDesc.value.scrollTop = 0
+    // longDesc.value.scrollTop = 0
   }
 })
 
@@ -628,6 +632,109 @@ watch(scrollerElScrollTop, (v) => {
     isShowBtnGoNextPage.value = false
   }
 })
+
+// const lastX = ref(0)
+// function isDesktopUsingViewportWidth() {
+//   return window.matchMedia('(min-width: 769px)').matches
+// }
+
+// 开始滑动
+// const handletouchstart = (event) => {
+//   // pc端通过mouse移动
+//   if (isDesktopUsingViewportWidth) {
+//     lastX.value = event.pageX
+//   } else {
+//     lastX.value = event.changedTouches[0].pageX
+//   }
+// }
+
+const direction = ref(null)
+
+
+
+// 监听活动
+// const touchMove = (event) => {
+//   let currentX = event.changedTouches[0].pageX
+//   let tx = currentX - lastX.value
+
+//   if (tx < -30) {
+//     // 右滑
+//     direction.value = 'right'
+//     // 页面2--600,页面3--1000
+
+//   } else if (tx > 30) {
+//     // 左滑
+//     direction.value = 'left'
+//   } else {
+//     direction.value = null
+//   }
+// }
+
+
+function smoothScrollTo(element, finalPosition, duration = 500, startTime = performance.now()) {
+
+  const currentTime = performance.now()
+  const timeElapsed = currentTime - startTime
+  const progress = Math.min(timeElapsed / duration, 1) // 确保进度不超过1
+  const currentPos = element.scrollTop
+  const newPos = currentPos + (finalPosition - currentPos) * progress
+  element.scrollTop = newPos
+
+  if (progress < 1 && finalPosition == scrollerPositionList[curStep.value] * scrollerEl.value.scrollHeight) {
+    console.log('最后位置', finalPosition)
+    requestAnimationFrame(() => smoothScrollTo(element, finalPosition, duration, startTime))
+  }
+}
+
+const curStep = ref(0)
+
+const scrollerPositionList = [0, 0.17, 0.33, 0.46, 0.62, 1]
+const scrollerPositionTimeRight = [6000, 6000, 15000, 15000, 15000, 4000]
+const scrollerPositionTimeLeft = [6000, 6000, 15000, 15000, 15000, 15000]
+
+
+
+
+// const handletouchend = () => {
+//   if (direction.value == 'right' && curStep.value < scrollerPositionList.length - 1) {
+//     curStep.value ++
+//     console.log('right', curStep.value)
+//     const pp = scrollerPositionList[curStep.value]
+//     const startTime = performance.now()
+//     requestAnimationFrame(() => {smoothScrollTo(scrollerEl.value, pp * scrollerEl.value.scrollHeight, scrollerPositionTimeRight[curStep.value], startTime)})
+//   } else if (direction.value == 'left' && curStep.value > 0) {
+//     curStep.value --
+//     const pp = scrollerPositionList[curStep.value] * scrollerEl.value.scrollHeight
+//     const startTime = performance.now()
+//     requestAnimationFrame(() => {smoothScrollTo(scrollerEl.value, pp, scrollerPositionTimeLeft[curStep.value], startTime)})
+//   }
+//   direction.value = null
+
+// }
+
+const onSwipeLeft = () => {
+  if (curStep.value < scrollerPositionList.length - 1) {
+    console.log('右滑下一步', curStep.value)
+    curStep.value ++
+    console.log('right', curStep.value)
+    const pp = scrollerPositionList[curStep.value]
+    const startTime = performance.now()
+    requestAnimationFrame(() => {smoothScrollTo(scrollerEl.value, pp * scrollerEl.value.scrollHeight, scrollerPositionTimeRight[curStep.value], startTime)})
+  }
+
+}
+
+const onSwipeRight = () => {
+  if (curStep.value > 0) {
+    console.log('左滑返回', curStep.value)
+    curStep.value --
+    const pp = scrollerPositionList[curStep.value] * scrollerEl.value.scrollHeight
+    const startTime = performance.now()
+    requestAnimationFrame(() => {smoothScrollTo(scrollerEl.value, pp, scrollerPositionTimeLeft[curStep.value], startTime)})
+  }
+}
+
+
 function onClickGoNextPage() {
   isShowBtnGoNextPage.value = false
   isShowVideoFadeToNextPage.value = true
@@ -648,9 +755,14 @@ function onClickGoNextPage() {
   background-size: cover;
   background-repeat: no-repeat;
   background-position: center center;
+
   // 滚动条,只设置某一项可能导致不生效。
-  ::-webkit-scrollbar { width: 0; height: 0; }
-  >.bg-mask{
+  ::-webkit-scrollbar {
+    width: 0;
+    height: 0;
+  }
+
+  >.bg-mask {
     position: absolute;
     left: 0;
     top: 0;
@@ -659,10 +771,12 @@ function onClickGoNextPage() {
     background: rgba(60, 89, 71, 0.65);
     backdrop-filter: blur(calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
   }
-  >.startup{
+
+  >.startup {
     z-index: 10;
   }
-  >.title-wrap{
+
+  >.title-wrap {
     position: absolute;
     left: 50%;
     top: calc(36 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -670,14 +784,16 @@ function onClickGoNextPage() {
     width: calc(43 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     height: calc(180 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     z-index: 5;
-    >img.title{
+
+    >img.title {
       position: absolute;
       left: 0;
       top: 0;
       width: 100%;
       height: 100%;
     }
-    >.sub-text{
+
+    >.sub-text {
       position: absolute;
       left: 110%;
       top: 46%;
@@ -693,20 +809,24 @@ function onClickGoNextPage() {
       text-align: center;
     }
   }
-  >.painting-wrap{
+
+  >.painting-wrap {
     position: absolute;
     left: 50%;
     transform: translate(-50%, 0);
-    >.size-sign-h{
+
+    >.size-sign-h {
       position: absolute;
       left: 50%;
       top: 0;
       transform: translate(-50%, -105%);
       width: calc(245 / 308 * 100%);
-      >img{
+
+      >img {
         width: 100%;
       }
-      >span{
+
+      >span {
         position: absolute;
         left: 50%;
         top: 50%;
@@ -719,16 +839,19 @@ function onClickGoNextPage() {
         text-shadow: 0px 0px calc(4 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')) #F8DD86;
       }
     }
-    >.size-sign-v{
+
+    >.size-sign-v {
       position: absolute;
       right: 0;
       top: 54%;
       transform: translate(80%, -50%);
       height: calc(371 / 523 * 100%);
-      >img{
+
+      >img {
         height: 100%;
       }
-      >span{
+
+      >span {
         position: absolute;
         left: 50%;
         top: 50%;
@@ -742,14 +865,19 @@ function onClickGoNextPage() {
         writing-mode: vertical-lr;
       }
     }
-    >img.painting-border{
+
+    >img.painting-border {
       position: absolute;
       left: 0;
       top: 0;
       width: 100%;
       height: 100%;
     }
-    >img.painting, img.painting-stem, img.painting-leaf, img.painting-stone{
+
+    >img.painting,
+    img.painting-stem,
+    img.painting-leaf,
+    img.painting-stone {
       position: absolute;
       left: 50%;
       top: 54%;
@@ -757,7 +885,8 @@ function onClickGoNextPage() {
       width: calc(245 / 308 * 100%);
     }
   }
-  >.hotspot-wrap{
+
+  >.hotspot-wrap {
     position: absolute;
     left: 50%;
     transform: translate(-50%, 0);
@@ -765,29 +894,34 @@ function onClickGoNextPage() {
     height: calc(522 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     z-index: 7;
     pointer-events: none;
-    &>div{
+
+    &>div {
       z-index: 100;
     }
-    >.hotspot-1{
+
+    >.hotspot-1 {
       position: absolute;
       top: calc(54 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       right: calc(0 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       pointer-events: initial;
     }
-    >.hotspot-2{
+
+    >.hotspot-2 {
       position: absolute;
       left: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       top: calc(222 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       pointer-events: initial;
     }
-    >.hotspot-3{
+
+    >.hotspot-3 {
       position: absolute;
       bottom: calc(-10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       right: calc(-10 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       pointer-events: initial;
     }
   }
-  >.long-desc{
+
+  >.long-desc {
     position: absolute;
     left: 50%;
     bottom: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -797,12 +931,16 @@ function onClickGoNextPage() {
     overflow: auto;
     font-family: KaiTi, KaiTi;
     color: #FFFFFF;
-    >h3{
+    animation: none;
+    z-index: 10;
+
+    >h3 {
       font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       margin-bottom: 0.5em;
       font-weight: 600;
     }
-    >p{
+
+    >p {
       font-weight: 400;
       font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -810,7 +948,8 @@ function onClickGoNextPage() {
       margin-bottom: 0.5em;
     }
   }
-  >.fixed-desc{
+
+  >.fixed-desc {
     position: absolute;
     left: 50%;
     transform: translateX(-50%);
@@ -826,13 +965,15 @@ function onClickGoNextPage() {
     line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     text-align: justify;
   }
-  >.progress-bar{
+
+  >.progress-bar {
     position: absolute;
     left: 0;
     bottom: 0;
     width: 100%;
     height: 15px;
-    >.bar-artwork-desc{
+
+    >.bar-artwork-desc {
       position: absolute;
       left: 0;
       bottom: 0;
@@ -840,14 +981,16 @@ function onClickGoNextPage() {
       height: 3px;
       background-color: #A9D185;
     }
-    >img.progress-bar-node-1{
+
+    >img.progress-bar-node-1 {
       position: absolute;
       left: calc(0.6 * v-bind('longDescHideFinishAt') / v-bind('summaryHideAt') * 100%);
       bottom: 1px;
       width: 2.41px;
       height: 10.23px
     }
-    >.bar-author-desc{
+
+    >.bar-author-desc {
       position: absolute;
       left: 12px;
       bottom: 0;
@@ -855,14 +998,16 @@ function onClickGoNextPage() {
       height: 3px;
       background: #A9D185;
     }
-    >img.progress-bar-node-2{
+
+    >img.progress-bar-node-2 {
       position: absolute;
       left: calc(v-bind('longDescHideFinishAt') / v-bind('summaryHideAt') * 100%);
       bottom: 1px;
       width: 7.5px;
       height: 10.8px
     }
-    >.bar-artwork-enjoy{
+
+    >.bar-artwork-enjoy {
       position: absolute;
       left: calc(v-bind('stoneShowAt') / v-bind('summaryHideAt') * 100%);
       bottom: 0;
@@ -870,7 +1015,8 @@ function onClickGoNextPage() {
       height: 3px;
       background: #A9D185;
     }
-    >img.progress-bar-node-3{
+
+    >img.progress-bar-node-3 {
       position: absolute;
       right: 0;
       bottom: 1px;
@@ -878,7 +1024,7 @@ function onClickGoNextPage() {
       height: 10.8px
     }
 
-    > .mask{
+    >.mask {
       position: absolute;
       right: 0;
       bottom: 0;
@@ -886,30 +1032,38 @@ function onClickGoNextPage() {
       background-color: #6e8175;
     }
   }
-  >.operation-tip{
+
+  >.operation-tip {
     position: absolute;
     left: 50%;
-    bottom: calc(77 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     transform: translateX(-50%);
+    // bottom: calc(77 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    bottom: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
   }
-  >.scroller{
+
+  >.scroller {
     position: absolute;
     left: 0;
     top: 0;
     width: 100%;
     height: 100%;
-    overflow: auto;
-    >.inner{
+    overflow: hidden;
+    transition: transform 2s ease;
+
+    >.inner {
       width: 100%;
     }
   }
-  >.hotspot-detail{
+
+  >.hotspot-detail {
     z-index: 10;
   }
-  >.hotspot-detail.painting-detail{
+
+  >.hotspot-detail.painting-detail {
     backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
   }
-  >video.fade-to-next-page{
+
+  >video.fade-to-next-page {
     position: absolute;
     left: 0;
     top: 0;
@@ -919,7 +1073,7 @@ function onClickGoNextPage() {
     z-index: 20;
   }
 
-  >button.go-next-page{
+  >button.go-next-page {
     position: absolute;
     left: 50%;
     bottom: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));

+ 170 - 6
src/views/MoreContent.vue

@@ -346,15 +346,52 @@
     </Transition>
     <!-- 游戏页面 -->
     <div
-      v-if="isShowGamePage"
+      v-if="true"
       class="game-box"
     >
-      <iframe
-        class="game-box"
-        :src="`./game/index.html`"
-      />
+      <iframe :src="`./game/index.html`" />
       <!-- edit弹框 -->
-      <div class="edit-box" />
+      <div
+        v-if="isShowToastFromGame"
+        class="edit-box"
+      >
+        <!-- <input :v-model="inputValue"> -->
+        <!-- <div class="text" >{{ inputValue }}</div>
+        <div class="text">{{  }}</div> -->
+        <!-- <textarea
+          v-model="inputText"
+          rows="2"
+          maxlength="15"
+          @input="onInput"
+        /> -->
+        <div class="input-box">
+          <input
+            ref="input1Ref"
+            v-model="input1"
+            @input="handleInput1"
+            @keyup="checkInput1"
+          >
+          <input
+            ref="input2Ref"
+            v-model="input2"
+            :readonly="input1.length < 7"
+            @input="handleInput2"
+            @keyup="checkInput2"
+          >
+          <div class="tips">
+            请输入内容
+          </div>
+        </div>
+        <div
+          class="cencel-btn"
+          @click="isShowToastFromGame =false"
+        >
+          取消
+        </div>
+        <div class="yes-btn">
+          保存
+        </div>
+      </div>
     </div>
 
 
@@ -398,6 +435,44 @@ const isShowGamePage = ref(false)
 
 const isShowScenePage = ref(false)
 
+const isShowToastFromGame = ref(false)
+
+const input1 = ref('')
+const input2 = ref('')
+const input1Ref = ref(null)
+const input2Ref = ref(null)
+
+const handleInput1 = () => {
+  console.log('第一个框得内容', input1.value)
+  if (input1.value.length >= 7) {
+    input1.value = input1.value.slice(0, 7) // 限制输入长度
+    input2Ref.value.focus() // 聚焦到第二个输入框
+  }
+}
+
+const checkInput1 = (event) => {
+  if (event.key === 'Backspace' && input1.value.length === 0) {
+    input2.value = '' // 清空第二个输入框
+    input1Ref.value.focus() // 聚焦回到第一个输入框
+  }
+
+}
+
+const handleInput2 = () => {
+  // 这里可以添加类似的逻辑,但通常不需要,因为我们假设第二个输入框不会自动跳转回去
+  if (input2.value.length >= 7) {
+    input2.value = input2.value.slice(0, 7)
+  }
+}
+
+const checkInput2 = (event) => {
+  if (event.key === 'Backspace' && input2.value.length === 0) {
+    input1Ref.value.focus() // 如果需要从第二个输入框清空后聚焦回第一个输入框
+  }
+}
+
+
+
 onMounted(() => {
   window.closeGame = () => {
     isShowGamePage.value = false
@@ -948,6 +1023,7 @@ watch(goingToAnchorIdx, (v) => {
     top: 0;
     left: 0;
     z-index: 100;
+
     >iframe {
       width: 100%;
       height: 100%;
@@ -955,6 +1031,94 @@ watch(goingToAnchorIdx, (v) => {
       top: 0;
       left: 0;
     }
+
+    .edit-box {
+      width: 125%;
+      height: 35vh;
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      background: url(@/assets/images/game-tip.png);
+      background-size: 100% 100%;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      z-index: 2;
+      font-family: 'KaiTi';
+
+      >.input-box {
+        width: 50%;
+        display: flex;
+        flex-direction: column;
+        margin-bottom: 10%;
+        margin-right: 5%;
+
+        >input {
+          width: 100%;
+          height: 45px;
+          background: none;
+          border: none;
+          font-size: 20px;
+          white-space: pre-wrap;
+          color: white;
+          border-bottom: 1px solid rgba(255, 255, 255, 0.548);
+          font-family: 'KaiTi';
+          letter-spacing: 2px;
+
+        }
+
+        .tips {
+          font-family: 'KaiTi';
+          font-size: 14px;
+          margin-top: calc(5 /v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          color: rgba(255, 255, 255, 0.418);
+        }
+      }
+
+      >textarea {
+        width: 34%;
+        height: 40%;
+        background: none;
+        border: none;
+        font-size: 20px;
+        white-space: pre-wrap;
+      }
+
+
+      >.cencel-btn {
+        // width: calc(70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        background: url(@/assets/images/game-tip-cancel.png);
+        background-size: 100% 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        color: #FFFFFF;
+        position: absolute;
+        left: 30%;
+        bottom: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        padding: 5px 10px;
+        font-family: 'KaiTi';
+      }
+
+      >.yes-btn {
+        // width: calc(70 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        // height: calc(30 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        background: url(@/assets/images/game-tip-yes.png);
+        background-size: 100% 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        color: #F4E09D;
+        position: absolute;
+        right: 38%;
+        bottom: calc(60 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        padding: 5px 10px;
+        font-family: 'KaiTi';
+      }
+    }
   }
 
   >.scene-box {