Jelajahi Sumber

首页热点详情2

任一存 1 tahun lalu
induk
melakukan
53e31f69c0
8 mengubah file dengan 772 tambahan dan 13 penghapusan
  1. 1 0
      package.json
  2. 454 0
      public/configExcel.js
  3. 2 2
      src/App.vue
  4. TEMPAT SAMPAH
      src/assets/images/home-painting-big.jpg
  5. TEMPAT SAMPAH
      src/assets/images/painting-border-bottom.png
  6. 25 11
      src/views/HomeView.vue
  7. 286 0
      src/views/HotspotDetail2.vue
  8. 4 0
      yarn.lock

+ 1 - 0
package.json

@@ -9,6 +9,7 @@
     "lint": "vue-cli-service lint"
     "lint": "vue-cli-service lint"
   },
   },
   "dependencies": {
   "dependencies": {
+    "@tweenjs/tween.js": "tweenjs/tween.js",
     "@vueuse/core": "^10.11.0",
     "@vueuse/core": "^10.11.0",
     "axios": "^1.1.3",
     "axios": "^1.1.3",
     "core-js": "^3.8.3",
     "core-js": "^3.8.3",

File diff ditekan karena terlalu besar
+ 454 - 0
public/configExcel.js


+ 2 - 2
src/App.vue

@@ -86,10 +86,10 @@ input, textarea {
 }
 }
 
 
 .fade-in-out-enter-active {
 .fade-in-out-enter-active {
-  transition: opacity 2s;
+  transition: opacity 1s;
 }
 }
 .fade-in-out-leave-active {
 .fade-in-out-leave-active {
-  transition: opacity 2s;
+  transition: opacity 1s;
   pointer-events: none;
   pointer-events: none;
 }
 }
 .fade-in-out-enter-from {
 .fade-in-out-enter-from {

TEMPAT SAMPAH
src/assets/images/home-painting-big.jpg


TEMPAT SAMPAH
src/assets/images/painting-border-bottom.png


+ 25 - 11
src/views/HomeView.vue

@@ -108,6 +108,7 @@
       <HotspotComp
       <HotspotComp
         v-show="isShowHotspot"
         v-show="isShowHotspot"
         class="hotspot-2"
         class="hotspot-2"
+        @click="isShowHotspotDetail2 = true"
       />
       />
       <HotspotComp
       <HotspotComp
         v-show="isShowHotspot"
         v-show="isShowHotspot"
@@ -173,17 +174,27 @@
       </p>
       </p>
       <div class="bottom-mask" />
       <div class="bottom-mask" />
     </div>
     </div>
-
-    <HotspotDetail1
-      v-if="isShowHotspotDetail1"
-      class="hotspot-detail"
-      @close="isShowHotspotDetail1 = false"
-    />
-    <HotspotDetail3
-      v-if="isShowHotspotDetail3"
-      class="hotspot-detail"
-      @close="isShowHotspotDetail3 = false"
-    />
+    <Transition name="fade-in-out">
+      <HotspotDetail1
+        v-if="isShowHotspotDetail1"
+        class="hotspot-detail"
+        @close="isShowHotspotDetail1 = false"
+      />
+    </Transition>
+    <Transition name="fade-in-out">
+      <HotspotDetail2
+        v-if="isShowHotspotDetail2"
+        class="hotspot-detail"
+        @close="isShowHotspotDetail2 = false"
+      />
+    </Transition>
+    <Transition name="fade-in-out">
+      <HotspotDetail3
+        v-if="isShowHotspotDetail3"
+        class="hotspot-detail"
+        @close="isShowHotspotDetail3 = false"
+      />
+    </Transition>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -194,6 +205,7 @@ import { useStore } from "vuex"
 import Startup from '@/views/StartupView.vue'
 import Startup from '@/views/StartupView.vue'
 import useSizeAdapt from "@/useFunctions/useSizeAdapt"
 import useSizeAdapt from "@/useFunctions/useSizeAdapt"
 import HotspotDetail1 from '@/views/HotspotDetail1.vue'
 import HotspotDetail1 from '@/views/HotspotDetail1.vue'
+import HotspotDetail2 from '@/views/HotspotDetail2.vue'
 import HotspotDetail3 from '@/views/HotspotDetail3.vue'
 import HotspotDetail3 from '@/views/HotspotDetail3.vue'
 
 
 const route = useRoute()
 const route = useRoute()
@@ -336,6 +348,7 @@ const isShowHotspot = computed(() => {
 })
 })
 
 
 const isShowHotspotDetail1 = ref(false)
 const isShowHotspotDetail1 = ref(false)
+const isShowHotspotDetail2 = ref(false)
 const isShowHotspotDetail3 = ref(false)
 const isShowHotspotDetail3 = ref(false)
 </script>
 </script>
 
 
@@ -525,6 +538,7 @@ const isShowHotspotDetail3 = ref(false)
     font-family: KaiTi, KaiTi;
     font-family: KaiTi, KaiTi;
     color: #FFFFFF;
     color: #FFFFFF;
     >h3{
     >h3{
+      font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
       margin-top: 1em;
       margin-top: 1em;
       margin-bottom: 0.5em;
       margin-bottom: 0.5em;
       font-weight: 600;
       font-weight: 600;

+ 286 - 0
src/views/HotspotDetail2.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="hotspot-detail-2">
+    <div
+      class="painting-wrap"
+      :style="{
+        clipPath: `rect(0 100% ${AnimationProgress.value}% 0)`,
+      }"
+    >
+      <img
+        class="painting-border"
+        src="@/assets/images/painting-border.png"
+        alt=""
+        draggable="false"
+      >
+      <img
+        class="painting"
+        src="@/assets/images/home-painting.jpg"
+        alt=""
+        draggable="false"
+      >
+      <Transition name="fade-out">
+        <img
+          v-show="isAnimating"
+          class="bottom-border-for-animation"
+          :style="{
+            bottom: `${100 - AnimationProgress.value}%`,
+          }"
+          src="@/assets/images/painting-border-bottom.png"
+          alt=""
+          draggable="false"
+        >
+      </Transition>
+    </div>
+    <div
+      class="fixed-desc"
+      :style="{
+        opacity: isAnimating ? AnimationProgress.value / 100 : fixedDescOpacity,
+      }"
+    >
+      <div class="inner-wrap">
+        <h3>修篁树石图</h3>
+        <p>李衎(元)</p>
+        <p>轴 绢本 墨笔</p>
+        <p>南京博物院藏</p>
+      </div>
+    </div>
+
+    <OperationTip
+      v-if="store.state.isStartupInvisible"
+      class="operation-tip"
+      :is-show="isShowOperationTip"
+    />
+    <div
+      ref="descEl"
+      class="desc"
+      :style="{
+        backdropFilter: `blur(${descBlurScale}px)`,
+        backgroundColor: `rgba(0, 0, 0, ${descBgAlpha})`,
+        pointerEvents: isAnimating ? 'none' : null,
+      }"
+    >
+      <h3>作品简介:</h3>
+      <p
+        v-for="(item, index) in homepagePaintingDesc"
+        :key="index"
+      >
+        {{ item }}
+      </p>
+      <h3>作者简介:</h3>
+      <p
+        v-for="(item, index) in homepageAuthorDesc"
+        :key="index"
+      >
+        {{ item }}
+      </p>
+      <div class="bottom-mask" />
+    </div>
+    <BtnBack
+      @click="emit('close')"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted, inject, onUnmounted } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+import useSizeAdapt from "@/useFunctions/useSizeAdapt"
+import TWEEN from '@tweenjs/tween.js'
+import { progressProps } from "element-plus"
+
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const $env = inject('$env')
+
+const emit = defineEmits(['close'])
+
+const {
+  windowSizeInCssForRef,
+  windowSizeWhenDesignForRef,
+} = useSizeAdapt()
+
+const homepagePaintingDesc = configText.homepagePaintingDesc
+const homepageAuthorDesc = configText.homepageAuthorDesc
+
+const isAnimating = ref(true)
+
+/** 卷轴展开动画的tweening */
+const AnimationProgress = ref({
+  value: 7
+})
+const tween = new TWEEN.Tween(AnimationProgress.value)
+tween.to({
+  value: 100,
+}, 3000)
+tween.easing(TWEEN.Easing.Cubic.InOut)
+let animationRequestId = null
+const animate = () => {
+  animationRequestId = requestAnimationFrame(animate)
+  TWEEN.update()
+}
+tween.onUpdate(function (object) {
+  console.log(object.value)
+})
+onMounted(() => {
+  tween.start()
+  animate()
+})
+tween.onComplete(() => {
+  isAnimating.value = false
+  cancelAnimationFrame(animationRequestId)
+})
+onUnmounted(() => {
+  tween.stop()
+  cancelAnimationFrame(animationRequestId)
+})
+
+const descEl = ref(null)
+const descElScrollTop = ref(0)
+onMounted(() => {
+  descEl.value.addEventListener('scroll', (e) => {
+    descElScrollTop.value = descEl.value.scrollTop
+  })
+})
+
+const isShowOperationTip = ref(true)
+watch(descElScrollTop, (v) => {
+  if (v > 0) {
+    isShowOperationTip.value = false
+  }
+})
+
+const descBlurScale = computed(() => {
+  let ret = 0
+  if (descElScrollTop.value < window.innerHeight * 0.3) {
+    ret = descElScrollTop.value / (window.innerHeight * 0.3) * 20
+  } else {
+    ret = 20
+  }
+  return ret
+})
+const descBgAlpha = computed(() => {
+  let ret = 0
+  if (descElScrollTop.value < window.innerHeight * 0.3) {
+    ret = descElScrollTop.value / (window.innerHeight * 0.3) * 0.3
+  } else {
+    ret = 0.3
+  }
+  return ret
+})
+const fixedDescOpacity = computed(() => {
+  let ret = 1
+  if (descElScrollTop.value < window.innerHeight * 0.3) {
+    ret = 1 - descElScrollTop.value / (window.innerHeight * 0.3)
+  } else {
+    ret = 0
+  }
+  return ret
+})
+</script>
+
+<style lang="less" scoped>
+.hotspot-detail-2{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
+  >.painting-wrap{
+    position: absolute;
+    left: 50%;
+    top: 44%;
+    transform: translate(-50%, -50%);
+    width: calc(356 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(602 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    overflow: hidden;
+    >img.painting-border{
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
+    }
+    >img.painting{
+      position: absolute;
+      left: 50%;
+      top: 50%;
+      transform: translate(-50%, -50%);
+      width: 90%;
+    }
+    >img.bottom-border-for-animation{
+      position: absolute;
+      left: 0;
+      width: 100%;
+    }
+  }
+  >.fixed-desc{
+    position: absolute;
+    left: 50%;
+    bottom: 2%;
+    transform: translateX(-50%);
+    width: 100%;
+    height: 20%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    >.inner-wrap{
+      text-align: center;
+      >h3{
+        font-family: KaiTi, KaiTi;
+        font-weight: 400;
+        font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        color: #FFFFFF;
+        margin-bottom: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+      >p{
+        font-family: KaiTi, KaiTi;
+        font-weight: 400;
+        font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        color: rgba(255, 255, 255, 0.8);
+        line-height: calc(19 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+        margin-bottom: calc(6 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      }
+    }
+  }
+  >.operation-tip{
+    position: absolute;
+    right: calc(49 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    bottom: calc(39 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  }
+  >.desc{
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    padding-top: 100vh;
+    color: white;
+    overflow: auto;
+    padding-left: calc(37 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    padding-right: calc(37 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    font-family: KaiTi, KaiTi;
+    color: #FFFFFF;
+    >h3{
+      margin-top: 1em;
+      margin-bottom: 0.5em;
+      font-weight: 600;
+    }
+    >p{
+      font-weight: 400;
+      font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      line-height: calc(25 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      text-align: justified;
+      margin-bottom: 0.5em;
+    }
+    >.bottom-mask{
+      width: 100%;
+      height: 10vh;
+    }
+  }
+}
+</style>

+ 4 - 0
yarn.lock

@@ -1236,6 +1236,10 @@
   resolved "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
   resolved "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
   integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
   integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
 
 
+"@tweenjs/tween.js@tweenjs/tween.js":
+  version "23.1.2"
+  resolved "https://codeload.github.com/tweenjs/tween.js/tar.gz/ea96cb35ef31f769bc72c2e4e0a6ebe5bfcdd1a1"
+
 "@types/body-parser@*":
 "@types/body-parser@*":
   version "1.19.5"
   version "1.19.5"
   resolved "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4"
   resolved "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4"