Prechádzať zdrojové kódy

feat: 竹子列表页和竹子详情页

任一存 1 rok pred
rodič
commit
088e3c3bed

BIN
src/assets/images/bamboo-list/bg.jpg


BIN
src/assets/images/bamboo-list/dan-zhu.png


BIN
src/assets/images/bamboo-list/leaf.png


BIN
src/assets/images/bamboo-list/mei-lu-zhu.png


BIN
src/assets/images/bamboo-list/nan-zhu.png


BIN
src/assets/images/bamboo-list/shui-zhu.png


BIN
src/assets/images/bamboo-list/weed.png


BIN
src/assets/images/bamboo-list/xiang-fei-zhu.png


BIN
src/assets/images/bamboo-list/zi-zhu.png


BIN
src/assets/images/bamboo-list/渐变-min.png


BIN
src/assets/images/icon_hotspot-small.png


+ 43 - 0
src/components/HotspotCompSmall.vue

@@ -0,0 +1,43 @@
+<template>
+  <div class="hotspot animation-show-hide">
+    <img
+      class=""
+      src="@/assets/images/icon_hotspot-small.png"
+      alt=""
+      draggable="false"
+    >
+    <div class="text">
+      <slot />
+    </div>
+  </div>
+</template>
+
+<script setup>
+</script>
+
+<style lang="less" scoped>
+.hotspot{
+  position: absolute;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  cursor: pointer;
+  >img{
+    flex: 0 0 auto;
+    width: 28px;
+    height: 28px;
+  }
+  >.text{
+    margin-top: -0.3em;
+    writing-mode: vertical-lr;
+    white-space: pre;
+    font-family: KaiTi, KaiTi;
+    font-weight: 400;
+    font-size: 26px;
+    color: #FFFFFF;
+    line-height: 30px;
+    text-shadow: 0px 0px 3px rgba(0,0,0,0.75);
+    letter-spacing: 0.15em;
+  }
+}
+</style>

+ 2 - 0
src/main.js

@@ -16,6 +16,7 @@ import BtnBack from '@/components/BtnBack.vue'
 // import BtnClickMe from '@/components/BtnClickMe.vue'
 import OperationTip from '@/components/OperationTip.vue'
 import HotspotComp from '@/components/HotspotComp.vue'
+import HotspotCompSmall from '@/components/HotspotCompSmall.vue'
 import HotspotForHomepage from '@/components/HotspotForHomepage.vue'
 import SerialFrames from '@/components/LongImageSerialFrames.vue'
 import BtnSkip from '@/components/BtnSkip.vue'
@@ -90,6 +91,7 @@ app.use(store)
 //   .component('BtnClickMe', BtnClickMe)
   .component('OperationTip', OperationTip)
   .component('HotspotComp', HotspotComp)
+  .component('HotspotCompSmall', HotspotCompSmall)
   .component('HotspotForHomepage', HotspotForHomepage)
 //   .component('Swiper', Swiper)
 //   .component('SwiperSlide', SwiperSlide)

+ 6 - 0
src/router/index.js

@@ -2,6 +2,7 @@ import { createRouter, createWebHashHistory } from 'vue-router'
 import HomeView from '../views/HomeView.vue'
 import MoreContent from '../views/MoreContent.vue'
 import ShuangGou from '../views/ShuangGou.vue'
+import BambooList from '../views/BambooList.vue'
 import PaintingDetail from '../views/PaintingDetail'
 
 // import store from '@/store/index.js'
@@ -28,6 +29,11 @@ const routes = [
     component: ShuangGou,
   },
   {
+    path: '/bamboo-list',
+    name: 'BambooList',
+    component: BambooList,
+  },
+  {
     path: '/painting-detail',
     name: 'PaintingDetail',
     component: PaintingDetail,

+ 0 - 1
src/useFunctions/useSmoothSwipe.js

@@ -96,7 +96,6 @@ export default function useSmoothSwipe({
   }
 
   function onWheel(e) {
-    console.log(e)
     translateLength.value += e.deltaY / 2.5
   }
 

+ 429 - 0
src/views/BambooList.vue

@@ -0,0 +1,429 @@
+<template>
+  <div class="bamboo-list">
+    <img
+      class="bg"
+      :style="{
+        opacity: isShowDetail ? 1 : 0.5,
+      }"
+      src="@/assets/images/bamboo-list/bg.jpg"
+      alt=""
+      draggable="false"
+    >
+    <BtnBack
+      class="btn-back"
+      @click="onClickBack"
+    />
+
+    <!-- 竹林各元素 -->
+    <div
+      ref="scrollTarget"
+      class="scroll-target"
+    >
+      <div
+        class="layer-1"
+        :style="{
+          left: layer1Left + 'px',
+        }"
+      >
+        <img
+          class="weed"
+          :style="{
+            opacity: isShowDetail ? 0 : 1,
+          }"
+          src="@/assets/images/bamboo-list/weed.png"
+          alt=""
+          draggable="false"
+        >
+        <img
+          class="leaf"
+          :style="{
+            opacity: isShowDetail ? 0 : 1,
+          }"
+          src="@/assets/images/bamboo-list/leaf.png"
+          alt=""
+          draggable="false"
+        >
+        <img
+          class="bamboo shui-zhu"
+          :class="{
+            focused: showDetailIdx === 0,
+            hide: isShowDetail && showDetailIdx !== 0
+          }"
+          src="@/assets/images/bamboo-list/shui-zhu.png"
+          alt=""
+          draggable="false"
+        >
+        <HotspotCompSmall
+          v-show="!isShowDetail"
+          class="hotspot-shui-zhu"
+          @click="onClickHotspot(0)"
+        >
+          水竹
+        </HotspotCompSmall>
+        <img
+          class="bamboo zi-zhu"
+          :class="{
+            focused: showDetailIdx === 1,
+            hide: isShowDetail && showDetailIdx !== 1
+          }"
+          src="@/assets/images/bamboo-list/zi-zhu.png"
+          alt=""
+          draggable="false"
+        >
+        <HotspotCompSmall
+          v-show="!isShowDetail"
+          class="hotspot-zi-zhu"
+          @click="onClickHotspot(1)"
+        >
+          紫竹
+        </HotspotCompSmall>
+        <img
+          class="bamboo mei-lu-zhu"
+          :class="{
+            focused: showDetailIdx === 2,
+            hide: isShowDetail && showDetailIdx !== 2
+          }"
+          src="@/assets/images/bamboo-list/mei-lu-zhu.png"
+          alt=""
+          draggable="false"
+        >
+        <HotspotCompSmall
+          v-show="!isShowDetail"
+          class="hotspot-mei-lu-zhu"
+          @click="onClickHotspot(2)"
+        >
+          梅鹿竹
+        </HotspotCompSmall>
+        <img
+          class="bamboo nan-zhu"
+          :class="{
+            focused: showDetailIdx === 3,
+            hide: isShowDetail && showDetailIdx !== 3
+          }"
+          src="@/assets/images/bamboo-list/nan-zhu.png"
+          alt=""
+          draggable="false"
+        >
+        <HotspotCompSmall
+          v-show="!isShowDetail"
+          class="hotspot-nan-zhu"
+          @click="onClickHotspot(3)"
+        >
+          楠竹
+        </HotspotCompSmall>
+        <img
+          class="bamboo xiang-fei-zhu"
+          :class="{
+            focused: showDetailIdx === 4,
+            hide: isShowDetail && showDetailIdx !== 4
+          }"
+          src="@/assets/images/bamboo-list/xiang-fei-zhu.png"
+          alt=""
+          draggable="false"
+        >
+        <HotspotCompSmall
+          v-show="!isShowDetail"
+          class="hotspot-xiang-fei-zhu"
+          @click="onClickHotspot(4)"
+        >
+          湘妃竹
+        </HotspotCompSmall>
+        <img
+          class="bamboo dan-zhu"
+          :class="{
+            focused: showDetailIdx === 5,
+            hide: isShowDetail && showDetailIdx !== 5
+          }"
+          src="@/assets/images/bamboo-list/dan-zhu.png"
+          alt=""
+          draggable="false"
+        >
+        <HotspotCompSmall
+          v-show="!isShowDetail"
+          class="hotspot-dan-zhu"
+          @click="onClickHotspot(5)"
+        >
+          单竹
+        </HotspotCompSmall>
+      </div>
+    </div>
+
+    <!-- 详情 -->
+    <Transition name="fade-in-out">
+      <div
+        v-if="isShowDetail"
+        class="detail-wrap-outter"
+      >
+        <div
+          class="detail-wrap"
+        >
+          <h1>{{ bambooList[showDetailIdx].label }}</h1>
+          <p v-html="bambooList[showDetailIdx].info" />
+        </div>
+      </div>
+    </Transition>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted, onBeforeUnmount, inject, nextTick } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+import useSmoothSwipe from "@/useFunctions/useSmoothSwipe.js"
+import { useWindowSize } from "@vueuse/core"
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const $env = inject('$env')
+
+const windowWidthDesign = 1920
+const windowHeightDesign = 1080 - 71 - 37 // 设计稿里视口高度。注意要减去上下边栏
+
+const scrollTarget = ref(null)
+const { width: windowWidth, height: windowHeight } = useWindowSize()
+
+const maxTranslateLength = computed(() => {
+  return (windowHeight.value * windowWidthDesign) / windowHeightDesign
+})
+
+const {
+  translateLength,
+} = useSmoothSwipe({
+  scrollTargetRef: scrollTarget,
+  maxTranslateLength,
+  viewportWidth: windowWidth,
+})
+
+// layer1Left位移
+const layer1InitialLeft = 0
+const layer1Left = ref(layer1InitialLeft)
+
+watch(
+  translateLength,
+  (v) => {
+    console.log(v)
+    layer1Left.value = layer1InitialLeft - v
+  },
+  {
+    immediate: true,
+  }
+)
+
+const bambooList = ref([
+  {
+    label: '水竹',
+    info: '篷耳小,形状为卵形或长椭圆形。锋舌边缘生有短白纤毛。筝片直立,呈三角形至狭长三角形。'
+  },
+  {
+    label: '紫竹',
+    info: '紫竹幼竿绿色,覆盖细柔毛和白粉,幕环有毛,籍鞘背面红褐色或绿色加深。叶片小而薄,窄披针形。'
+  },
+  {
+    label: '梅鹿竹',
+    info: '梅鹿竹斑纹相连,圆形,外轮廓深色,斑心发白。竹地上有兽斑状斑痕,酷似梅花鹿的花纹。'
+  },
+  {
+    label: '楠竹',
+    info: '单轴散生型常绿乔木状竹类植物,呈直立状,竹叶深绿,呈披针形'
+  },
+  {
+    label: '湘妃竹',
+    info: '中小型竹,竿环及箨<span style="writing-mode:horizontal-tb;">(tuò)</span>环隆起,竿箨黄褐色,有黑褐色斑点,箨叶三角形或带形'
+  },
+  {
+    label: '单竹',
+    info: '竹质细腻,纤维韧性极强,可制成薄如蝉翼的竹篾丝,编织成绸似、绢似的精美竹编工艺品。'
+  },
+])
+
+const isShowDetail = ref(false)
+const showDetailIdx = ref(-1)
+
+function onClickHotspot(idx) {
+  showDetailIdx.value = idx
+  isShowDetail.value = true
+}
+
+function onClickBack() {
+  if (isShowDetail.value) {
+    isShowDetail.value = false
+    showDetailIdx.value = -1
+  } else {
+    router.go(-1)
+  }
+}
+
+</script>
+
+<style lang="less" scoped>
+.bamboo-list{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #d3e2cd;
+  >img.bg{
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+    transition: all 1s;
+  }
+  >.btn-back{
+    z-index: 1;
+  }
+
+  > .scroll-target {
+    height: 100%;
+    width: 100%;
+    display: flex;
+    gap: 100px;
+    overflow: hidden;
+    position: relative;
+    z-index: 0;
+    >.layer-1{
+      position: absolute;
+      height: 100%;
+      >img.weed{
+        position: absolute;
+        left: 0;
+        bottom: calc(-50px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        height: calc(410px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        transition: all 1s;
+      }
+      >img.leaf{
+        position: absolute;
+        left: 0;
+        top: calc(-80px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        height: calc(442px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 1;
+        transition: all 1s;
+      }
+      >img.bamboo{
+        transition: all 1s;
+      }
+      >img.bamboo.hide{
+        opacity: 0;
+      }
+      >img.bamboo.focused{
+        left: calc(v-bind('translateLength') * 2px + 20vw); // 为什么要乘以2?我自己也不知道。。。
+      }
+      >img.shui-zhu{
+        position: absolute;
+        left: calc(100px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: 0;
+        height: 100%;
+        z-index: 1;
+      }
+      >.hotspot-shui-zhu{
+        position: absolute;
+        left: calc(185px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: calc(350px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 2;
+      }
+      >img.zi-zhu{
+        position: absolute;
+        left: calc(390px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: 0;
+        height: 100%;
+        z-index: 0;
+      }
+      >.hotspot-zi-zhu{
+        position: absolute;
+        left: calc(510px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: calc(152px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 2;
+      }
+      >img.mei-lu-zhu{
+        position: absolute;
+        left: calc(390px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: 0;
+        height: 100%;
+        z-index: 1;
+      }
+      >.hotspot-mei-lu-zhu{
+        position: absolute;
+        left: calc(710px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: calc(274px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 2;
+      }
+      >img.nan-zhu{
+        position: absolute;
+        left: calc(1140px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: 0;
+        height: 100%;
+        z-index: 1;
+      }
+      >.hotspot-nan-zhu{
+        position: absolute;
+        left: calc(1160px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: calc(217px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 2;
+      }
+      >img.xiang-fei-zhu{
+        position: absolute;
+        left: calc(1350px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: 0;
+        height: 100%;
+        z-index: 1;
+      }
+      >.hotspot-xiang-fei-zhu{
+        position: absolute;
+        left: calc(1695px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: calc(71px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 2;
+      }
+      >img.dan-zhu{
+        position: absolute;
+        left: calc(1500px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: 0;
+        height: 100%;
+        z-index: 1;
+      }
+      >.hotspot-dan-zhu{
+        position: absolute;
+        left: calc(1620px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        top: calc(358px / v-bind('windowHeightDesign') * v-bind('windowHeight'));
+        z-index: 2;
+      }
+    }
+  }
+
+  >.detail-wrap-outter{
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    >.detail-wrap{
+      position: absolute;
+      top: 17.6vh;
+      left: 50%;
+      >h1{
+        font-family: KingHwa_OldSong, KingHwa_OldSong;
+        font-weight: 400;
+        font-size: 60px;
+        color: #FFFFFF;
+        line-height: 75px;
+        text-shadow: 0px 0px 2px rgba(0,0,0,0.25);
+        margin-bottom: 1em;
+      }
+      >p{
+        width: 24.2vw;
+        margin-left: 60px;
+        font-family: KaiTi, KaiTi;
+        font-weight: 400;
+        font-size: 30px;
+        color: #FFFFFF;
+        line-height: 45px;
+        text-align: justified;
+      }
+    }
+  }
+}
+</style>

+ 2 - 2
src/views/MoreContent.vue

@@ -74,8 +74,8 @@
         <HotspotComp
           class="hotspot"
           @click="
-            router.replace({
-              name: 'BambooHot',
+            router.push({
+              name: 'BambooList',
             })
           "
         />