Bladeren bron

Merge branch 'master' of http://192.168.0.115:3000/renyicun/NanjingMuseumWuJinZang

aamin 1 jaar geleden
bovenliggende
commit
2d2cdde2cc
52 gewijzigde bestanden met toevoegingen van 633 en 251 verwijderingen
  1. 2 2
      README.md
  2. 131 86
      public/configExcel.js
  3. BIN
      public/configMultiMedia/paintings-small/万竹秋深图(局部).jpg
  4. BIN
      public/configMultiMedia/paintings-small/修篁树石图.jpg
  5. BIN
      public/configMultiMedia/paintings-small/十二墨花图(墨竹部分).jpg
  6. BIN
      public/configMultiMedia/paintings-small/古木竹石.jpg
  7. BIN
      public/configMultiMedia/paintings-small/墨竹.jpg
  8. BIN
      public/configMultiMedia/paintings-small/墨竹图屏.jpg
  9. BIN
      public/configMultiMedia/paintings-small/墨竹图(一).jpg
  10. BIN
      public/configMultiMedia/paintings-small/墨竹图(二).jpg
  11. BIN
      public/configMultiMedia/paintings-small/托根乱岩图.jpg
  12. BIN
      public/configMultiMedia/paintings-small/晚香高节图.jpg
  13. BIN
      public/configMultiMedia/paintings-small/朱竹图.jpg
  14. BIN
      public/configMultiMedia/paintings-small/枯木竹石图.jpg
  15. BIN
      public/configMultiMedia/paintings-small/桃竹双凫图.jpg
  16. BIN
      public/configMultiMedia/paintings-small/湘潭秋意图.jpg
  17. BIN
      public/configMultiMedia/paintings-small/潇湘竹石图(竹石部分).jpg
  18. BIN
      public/configMultiMedia/paintings-small/灵谷探梅图.jpg
  19. BIN
      public/configMultiMedia/paintings-small/竹枝图.jpg
  20. BIN
      public/configMultiMedia/paintings-small/竹石菊花图.jpg
  21. BIN
      public/configMultiMedia/paintings-small/竹禽图.jpg
  22. BIN
      public/configMultiMedia/paintings-small/筼筜清影图.jpg
  23. BIN
      public/configMultiMedia/paintings-small/花果图(墨竹部分).jpg
  24. BIN
      public/configMultiMedia/paintings-small/赵氏一门三竹图.jpg
  25. 1 1
      src/App.vue
  26. BIN
      src/assets/images/decoration-sun.png
  27. BIN
      src/assets/images/icon_operation_h_green.png
  28. BIN
      src/assets/images/icon_operation_h_white.png
  29. BIN
      src/assets/images/icon_operation_v_green.png
  30. BIN
      src/assets/images/icon_operation_v_white.png
  31. BIN
      src/assets/images/painting-menu-item-cover-bg-ming.png
  32. BIN
      src/assets/images/painting-menu-item-cover-bg-qing.png
  33. BIN
      src/assets/images/painting-menu-item-cover-bg-song.png
  34. BIN
      src/assets/images/painting-menu-item-cover-bg-yuan.png
  35. BIN
      src/assets/images/painting-menu-item-title-ming.png
  36. BIN
      src/assets/images/painting-menu-item-title-qing.png
  37. BIN
      src/assets/images/painting-menu-item-title-song.png
  38. BIN
      src/assets/images/painting-menu-item-title-yuan.png
  39. BIN
      src/assets/images/painting-menu-special-content-title.png
  40. BIN
      src/assets/images/painting-style-title.png
  41. BIN
      src/assets/images/see-more-btn.png
  42. 25 23
      src/components/OperationTip.vue
  43. 18 0
      src/router/index.js
  44. 19 7
      src/views/HomeView.vue
  45. 3 3
      src/views/HotspotDetail1.vue
  46. 3 3
      src/views/HotspotDetail3.vue
  47. 11 18
      src/views/MoreContent.vue
  48. 86 54
      src/views/HotspotDetail2.vue
  49. 105 0
      src/views/PaintingDetailList.vue
  50. 145 50
      src/views/PaintingListMenu.vue
  51. 82 0
      src/views/PaintingStyleDesc.vue
  52. 2 4
      src/views/PoemList.vue

+ 2 - 2
README.md

@@ -4,9 +4,9 @@
 访问url:https://culture.4dage.com/NanjingMuseumWuJinZang/index.html#/
 
 ## 任一存的todos
-绘画目录页 各种切图 排版
+绘画详情页开发 
 
-绘画详情页开发
+绘画详情页 长福画作居中显示
 
 内容扩展页开发
 

File diff suppressed because it is too large
+ 131 - 86
public/configExcel.js


BIN
public/configMultiMedia/paintings-small/万竹秋深图(局部).jpg


BIN
public/configMultiMedia/paintings-small/修篁树石图.jpg


BIN
public/configMultiMedia/paintings-small/十二墨花图(墨竹部分).jpg


BIN
public/configMultiMedia/paintings-small/古木竹石.jpg


BIN
public/configMultiMedia/paintings-small/墨竹.jpg


BIN
public/configMultiMedia/paintings-small/墨竹图屏.jpg


BIN
public/configMultiMedia/paintings-small/墨竹图(一).jpg


BIN
public/configMultiMedia/paintings-small/墨竹图(二).jpg


BIN
public/configMultiMedia/paintings-small/托根乱岩图.jpg


BIN
public/configMultiMedia/paintings-small/晚香高节图.jpg


BIN
public/configMultiMedia/paintings-small/朱竹图.jpg


BIN
public/configMultiMedia/paintings-small/枯木竹石图.jpg


BIN
public/configMultiMedia/paintings-small/桃竹双凫图.jpg


BIN
public/configMultiMedia/paintings-small/湘潭秋意图.jpg


BIN
public/configMultiMedia/paintings-small/潇湘竹石图(竹石部分).jpg


BIN
public/configMultiMedia/paintings-small/灵谷探梅图.jpg


BIN
public/configMultiMedia/paintings-small/竹枝图.jpg


BIN
public/configMultiMedia/paintings-small/竹石菊花图.jpg


BIN
public/configMultiMedia/paintings-small/竹禽图.jpg


BIN
public/configMultiMedia/paintings-small/筼筜清影图.jpg


BIN
public/configMultiMedia/paintings-small/花果图(墨竹部分).jpg


BIN
public/configMultiMedia/paintings-small/赵氏一门三竹图.jpg


+ 1 - 1
src/App.vue

@@ -41,7 +41,7 @@ const store = useStore()
 
 <style lang="less">
 html, body {
-  overscroll-behavior: none;
+  // overscroll-behavior: none;
   overflow: hidden;
   height: 100%;
 }

BIN
src/assets/images/decoration-sun.png


BIN
src/assets/images/icon_operation_h_green.png


BIN
src/assets/images/icon_operation_h_white.png


BIN
src/assets/images/icon_operation_v_green.png


BIN
src/assets/images/icon_operation_v_white.png


BIN
src/assets/images/painting-menu-item-cover-bg-ming.png


BIN
src/assets/images/painting-menu-item-cover-bg-qing.png


BIN
src/assets/images/painting-menu-item-cover-bg-song.png


BIN
src/assets/images/painting-menu-item-cover-bg-yuan.png


BIN
src/assets/images/painting-menu-item-title-ming.png


BIN
src/assets/images/painting-menu-item-title-qing.png


BIN
src/assets/images/painting-menu-item-title-song.png


BIN
src/assets/images/painting-menu-item-title-yuan.png


BIN
src/assets/images/painting-menu-special-content-title.png


BIN
src/assets/images/painting-style-title.png


BIN
src/assets/images/see-more-btn.png


+ 25 - 23
src/components/OperationTip.vue

@@ -1,24 +1,23 @@
 <template>
-  <div
-    v-show="isShow"
-    class="operation-tip"
-    :class="{
-      'animation-show-hide': isShow,
-    }"
-  >
+  <Transition name="fade-out">
     <div
-      v-if="props.text"
-      class="text"
+      v-show="isShow"
+      class="operation-tip"
     >
-      {{ props.text }}
+      <div
+        v-if="props.text"
+        class="text"
+      >
+        {{ props.text }}
+      </div>
+      <img
+        class=""
+        :src="require(`@/assets/images/icon_operation_${props.direction}_${props.color}.png`)"
+        alt=""
+        draggable="false"
+      >
     </div>
-    <img
-      class=""
-      :src="require(`@/assets/images/icon_operation_${props.direction}_${props.color}.png`)"
-      alt=""
-      draggable="false"
-    >
-  </div>
+  </Transition>
 </template>
 
 <script setup>
@@ -58,14 +57,17 @@ const props = defineProps({
 })
 
 const isShow = ref(true)
-let blinkCount = 0
-const intervalId = setInterval(() => {
-  blinkCount++
-  if (blinkCount >= 3 || !props.isShow) {
+const propIsShow = computed(() => {
+  return props.isShow
+})
+watch(propIsShow, (v) => {
+  if (!v) {
     isShow.value = false
-    clearInterval(intervalId)
   }
-}, 1500)
+})
+setTimeout(() => {
+  isShow.value = false
+}, 2000)
 </script>
 
 <style lang="less" scoped>

+ 18 - 0
src/router/index.js

@@ -1,6 +1,9 @@
 import { createRouter, createWebHashHistory } from 'vue-router'
 import HomeView from '../views/HomeView.vue'
 import MoreContent from '../views/MoreContent.vue'
+import PoemList from '../views/PoemList.vue'
+import PaintingList from '../views/PaintingList.vue'
+import PaintingDetailList from '../views/PaintingDetailList.vue'
 import GameView from '../views/GameView.vue'
 import BambooBookView from '../views/BambooBookView.vue'
 
@@ -22,6 +25,21 @@ const routes = [
     component: MoreContent,
   },
   {
+    path: '/poem-list',
+    name: 'PoemList',
+    component: PoemList,
+  },
+  {
+    path: '/painting-list',
+    name: 'PaintingList',
+    component: PaintingList,
+  },
+  {
+    path: '/painting-detail-list',
+    name: 'PaintingDetailList',
+    component: PaintingDetailList,
+  },
+  {
     path: '/game',
     name: 'Game',
     component: GameView,

+ 19 - 7
src/views/HomeView.vue

@@ -124,7 +124,7 @@
       <HotspotComp
         v-show="isShowHotspot"
         class="hotspot-2"
-        @click="isShowHotspotDetail2 = true"
+        @click="isShowPaintingDetail = true"
       />
       <HotspotComp
         v-show="isShowHotspot"
@@ -213,10 +213,19 @@
       />
     </Transition>
     <Transition name="fade-in-out">
-      <HotspotDetail2
-        v-if="isShowHotspotDetail2"
-        class="hotspot-detail"
-        @close="isShowHotspotDetail2 = false"
+      <PaintingDetail
+        v-if="isShowPaintingDetail"
+        :thumb="require(`@/assets/images/home-painting.jpg`)"
+        :title="'修篁树石图'"
+        :author="'李衎'"
+        :age="'元'"
+        :subtitle="'轴 绢本 墨笔'"
+        :location="'南京博物院藏'"
+        :painting-desc="homepagePaintingDesc.join('\n\n')"
+        :author-desc="homepageAuthorDesc.join('\n\n')"
+        :big-painting="require(`@/assets/images/home-painting-big.jpg`)"
+        class="hotspot-detail painting-detail"
+        @close="isShowPaintingDetail = false"
       />
     </Transition>
     <Transition name="fade-in-out">
@@ -236,7 +245,7 @@ import { useStore } from "vuex"
 import Startup from '@/views/StartupView.vue'
 import useSizeAdapt from "@/useFunctions/useSizeAdapt"
 import HotspotDetail1 from '@/views/HotspotDetail1.vue'
-import HotspotDetail2 from '@/views/HotspotDetail2.vue'
+import PaintingDetail from '@/views/PaintingDetail.vue'
 import HotspotDetail3 from '@/views/HotspotDetail3.vue'
 
 const route = useRoute()
@@ -416,7 +425,7 @@ const isShowHotspot = computed(() => {
 })
 
 const isShowHotspotDetail1 = ref(false)
-const isShowHotspotDetail2 = ref(false)
+const isShowPaintingDetail = ref(false)
 const isShowHotspotDetail3 = ref(false)
 </script>
 
@@ -629,5 +638,8 @@ const isShowHotspotDetail3 = ref(false)
   >.hotspot-detail{
     z-index: 10;
   }
+  >.hotspot-detail.painting-detail{
+    backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
+  }
 }
 </style>

+ 3 - 3
src/views/HotspotDetail1.vue

@@ -13,7 +13,7 @@
       <div class="image">
         <img
           class=""
-          :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/${craftInfo[3].title}.png`"
+          :src="`${$env.BASE_URL}configMultiMedia/${craftInfo[3].title}.png`"
           alt=""
           draggable="false"
         >
@@ -31,7 +31,7 @@
       <div class="image">
         <img
           class=""
-          :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/${craftInfo[4].title}.png`"
+          :src="`${$env.BASE_URL}configMultiMedia/${craftInfo[4].title}.png`"
           alt=""
           draggable="false"
         >
@@ -49,7 +49,7 @@
       <div class="image">
         <img
           class=""
-          :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/${craftInfo[5].title}.png`"
+          :src="`${$env.BASE_URL}configMultiMedia/${craftInfo[5].title}.png`"
           alt=""
           draggable="false"
         >

+ 3 - 3
src/views/HotspotDetail3.vue

@@ -13,7 +13,7 @@
       <div class="image">
         <img
           class=""
-          :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/${craftInfo[0].title}.png`"
+          :src="`${$env.BASE_URL}configMultiMedia/${craftInfo[0].title}.png`"
           alt=""
           draggable="false"
         >
@@ -31,7 +31,7 @@
       <div class="image">
         <img
           class=""
-          :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/${craftInfo[1].title}.png`"
+          :src="`${$env.BASE_URL}configMultiMedia/${craftInfo[1].title}.png`"
           alt=""
           draggable="false"
         >
@@ -49,7 +49,7 @@
       <div class="image">
         <img
           class=""
-          :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/${craftInfo[2].title}.png`"
+          :src="`${$env.BASE_URL}configMultiMedia/${craftInfo[2].title}.png`"
           alt=""
           draggable="false"
         >

+ 11 - 18
src/views/MoreContent.vue

@@ -1,24 +1,19 @@
 <template>
   <div class="more-content">
-    <button @click="isShowPoemList = true">
+    <button
+      @click="router.push({
+        name: 'PoemList'
+      })"
+    >
       诗词
     </button>
-    <button @click="isShowPaintingListMenu = true">
+    <button
+      @click="router.push({
+        name: 'PaintingList'
+      })"
+    >
       画作
     </button>
-
-    <Transition name="fade-in-out">
-      <PoemList
-        v-if="isShowPoemList"
-        @close="isShowPoemList = false"
-      />
-    </Transition>
-    <Transition name="fade-in-out">
-      <PaintingListMenu
-        v-if="isShowPaintingListMenu"
-        @close="isShowPaintingListMenu = false"
-      />
-    </Transition>
   </div>
 </template>
 
@@ -27,7 +22,7 @@ import { ref, computed, watch, onMounted, inject } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import PoemList from '@/views/PoemList.vue'
-import PaintingListMenu from '@/views/PaintingListMenu.vue'
+import paintingList from '@/views/PaintingList.vue'
 
 const route = useRoute()
 const router = useRouter()
@@ -35,8 +30,6 @@ const store = useStore()
 
 const $env = inject('$env')
 
-const isShowPoemList = ref(false)
-const isShowPaintingListMenu = ref(false)
 </script>
 
 <style lang="less" scoped>

+ 86 - 54
src/views/HotspotDetail2.vue

@@ -12,12 +12,15 @@
         alt=""
         draggable="false"
       >
-      <img
-        class="painting"
-        src="@/assets/images/home-painting.jpg"
-        alt=""
-        draggable="false"
-      >
+      <div class="painting-wrap-2">
+        <img
+          class="painting"
+          :src="props.thumb"
+          alt=""
+          draggable="false"
+          @click="showBigPainting"
+        >
+      </div>
       <Transition name="fade-out">
         <img
           v-show="isAnimating"
@@ -32,47 +35,38 @@
       </Transition>
     </div>
     <div
-      class="fixed-desc"
+      class="desc-text"
       :style="{
-        opacity: isAnimating ? AnimationProgress.value / 100 : fixedDescOpacity,
+        opacity: isAnimating ? AnimationProgress.value / 100 : 1,
       }"
     >
-      <h1>修篁树石图</h1>
+      <h1>{{ props.title }}</h1>
       <p class="subtitle">
-        李衎(元)
+        {{ `${props.author} (${props.age})` }}
       </p>
       <p class="subtitle">
-        轴 绢本 墨笔
+        {{ props.subtitle }}
       </p>
       <p class="subtitle">
-        南京博物院藏
+        {{ props.location }}
       </p>
 
-      <h2>作品简介:</h2>
-      <p
-        v-for="(item, index) in homepagePaintingDesc"
-        :key="index"
-        class="normal-text"
-      >
-        {{ item }}
-      </p>
-      <h2>作者简介:</h2>
-      <p
-        v-for="(item, index) in homepageAuthorDesc"
-        :key="index"
-        class="normal-text"
-      >
-        {{ item }}
-      </p>
+      <h2 v-if="paintingDesc">
+        作品简介:
+      </h2>
+      <div class="normal-text">
+        {{ paintingDesc }}
+      </div>
+      <h2 v-if="authorDesc">
+        作者简介:
+      </h2>
+      <div class="normal-text">
+        {{ authorDesc }}
+      </div>
     </div>
 
-    <!-- <OperationTip
-      v-if="store.state.isStartupInvisible"
-      class="operation-tip"
-      :is-show="isShowOperationTip"
-    /> -->
-
     <BtnBack
+      v-if="canClose"
       @click="emit('close')"
     />
   </div>
@@ -85,7 +79,6 @@ import { useStore } from "vuex"
 import useSizeAdapt from "@/useFunctions/useSizeAdapt"
 import TWEEN from '@tweenjs/tween.js'
 import { api as viewerApi } from 'v-viewer'
-import bigPainting from '@/assets/images/home-painting-big.jpg'
 
 const route = useRoute()
 const router = useRouter()
@@ -100,8 +93,44 @@ const {
   windowSizeWhenDesignForRef,
 } = useSizeAdapt()
 
-const homepagePaintingDesc = configText.homepagePaintingDesc
-const homepageAuthorDesc = configText.homepageAuthorDesc
+const props = defineProps({
+  thumb: {
+    type: String,
+    required: true,
+  },
+  bigPainting: {
+    type: String,
+    required: true,
+  },
+  title: {
+    type: String,
+    required: true,
+  },
+  author: {
+    type: String,
+    required: true,
+  },
+  age: {
+    type: String,
+    required: true,
+  },
+  location: {
+    type: String,
+    required: true,
+  },
+  paintingDesc: {
+    type: String,
+    default: '',
+  },
+  authorDesc: {
+    type: String,
+    default: '',
+  },
+  canClose: {
+    type: Boolean,
+    default: true,
+  }
+})
 
 const isAnimating = ref(true)
 
@@ -119,9 +148,9 @@ const animate = () => {
   animationRequestId = requestAnimationFrame(animate)
   TWEEN.update()
 }
-tween.onUpdate(function (object) {
-  console.log(object.value)
-})
+// tween.onUpdate(function (object) {
+//   console.log(object.value)
+// })
 onMounted(() => {
   tween.start()
   animate()
@@ -137,16 +166,10 @@ onUnmounted(() => {
 
 function showBigPainting() {
   viewerApi({
-    images: [bigPainting],
+    images: [props.bigPainting],
   })
 }
 
-// const isShowOperationTip = ref(true)
-// watch(descElScrollTop, (v) => {
-//   if (v > 0) {
-//     isShowOperationTip.value = false
-//   }
-// })
 </script>
 
 <style lang="less" scoped>
@@ -156,7 +179,7 @@ function showBigPainting() {
   top: 0;
   width: 100%;
   height: 100%;
-  backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
+  ::-webkit-scrollbar { width: 0; height: 0; }
   >.painting-wrap{
     position: absolute;
     left: 50%;
@@ -172,12 +195,21 @@ function showBigPainting() {
       width: 100%;
       height: 100%;
     }
-    >img.painting{
+    >.painting-wrap-2{
       position: absolute;
       left: 50%;
       top: 50%;
       transform: translate(-50%, -50%);
-      width: 90%;
+      width: calc(329 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      height: calc(561 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+      overflow: auto;
+      >img.painting{
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translate(-50%, -50%);
+        width: 100%;
+      }
     }
     >img.bottom-border-for-animation{
       position: absolute;
@@ -185,7 +217,7 @@ function showBigPainting() {
       width: 100%;
     }
   }
-  >.fixed-desc{
+  >.desc-text{
     position: absolute;
     left: 50%;
     bottom: 2%;
@@ -217,17 +249,17 @@ function showBigPainting() {
       color: #FFFFFF;
       margin-top: 1em;
       margin-bottom: 0.5em;
-      font-weight: 600;
+      font-weight: 400;
       font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
     }
-    >p.normal-text{
+    >.normal-text{
       font-family: KaiTi, KaiTi;
       color: #FFFFFF;
       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;
+      white-space: pre-line;
     }
   }
   >.operation-tip{

+ 105 - 0
src/views/PaintingDetailList.vue

@@ -0,0 +1,105 @@
+<template>
+  <div class="painting-detail-list">
+    <div class="bg-left" />
+    <Swiper
+      class="painting-list"
+      :initial-slide="Number(route.query.idx)"
+      :slides-per-view="1"
+      @swiper="onSwiper"
+      @slideChange="onSlideChange"
+    >
+      <SwiperSlide
+        v-for="item in paintingList"
+        :key="item['标题']"
+        class="swiper-slider"
+      >
+        <PaintingDetail
+          class="painting-item"
+          :thumb="`${$env.BASE_URL}configMultiMedia/paintings-small/${item['标题']}.jpg`"
+          :title="item['标题(展示)']"
+          :author="item['作者']"
+          :age="item['朝代']"
+          :subtitle="item['装裱\/材质\/笔类型']"
+          :location="item['馆藏']"
+          :painting-desc="item['简介']"
+          :author-desc="item['作者简介']"
+          :big-painting="`${$env.BASE_URL}configMultiMedia/paintings/${item['标题']}.jpg`"
+          :can-close="false"
+        >
+          {{ item }}
+        </PaintingDetail>
+      </SwiperSlide>
+    </Swiper>
+    <BtnBack
+      class="btn-back"
+      @click="router.go(-1)"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted, inject } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+import PaintingDetail from '@/views/PaintingDetail.vue'
+import useSizeAdapt from "@/useFunctions/useSizeAdapt"
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const $env = inject('$env')
+
+const {
+  windowSizeInCssForRef,
+  windowSizeWhenDesignForRef,
+} = useSizeAdapt()
+
+const paintingList = configExcel['画作']
+
+/**
+ * swiper
+ */
+let swiper = null
+const onSwiper = (swiperP) => {
+  swiper = swiperP
+}
+const onSlideChange = (e) => {
+}
+</script>
+
+<style lang="less" scoped>
+.painting-detail-list{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  >.bg-left{
+    background: linear-gradient(90deg, #7b916b 0%, #94a586 100%);
+    position: absolute;
+    left: 0;
+    top: 0;
+    height: 100%;
+    width: calc(57 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    background: -1;
+  }
+  >.painting-list{
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    backdrop-filter: blur(calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef')));
+    background: linear-gradient(rgba(123,145,107,0.62) 0%, rgba(0,0,0,0.3) 100%);
+    .swiper-slide{
+      >.painting-item{
+        position: relative !important;
+      }
+    }
+  }
+  >.btn-back{
+    z-index: 10;
+  }
+}
+</style>

+ 145 - 50
src/views/PaintingListMenu.vue

@@ -1,6 +1,6 @@
 <template>
   <div
-    class="painting-list-menu"
+    class="painting-list"
   >
     <ul
       ref="menuEl"
@@ -12,13 +12,19 @@
       >
         <div
           class="cover"
+          :style="{
+            backgroundImage: `url(${ageRenderInfo[ageName].coverBg})`,
+          }"
           @click="onClickAge(ageName)"
         >
-          <div class="age">
-            {{ ageName }}
-          </div>
+          <img
+            class="age"
+            :src="ageRenderInfo[ageName].artFontImg"
+            alt=""
+            draggable="false"
+          >
           <div class="age-en">
-            {{ `${ageCnToEn[ageName]} dynasty` }}
+            {{ `${ageRenderInfo[ageName].En} dynasty` }}
           </div>
           <div class="author-list">
             {{ getAuthorList(paintingGroup).join('\\') }}
@@ -38,21 +44,48 @@
             v-if="ageName === '宋'"
             class="special-desc"
           >
-            <!-- <img class="logo" src="@/assets/images/" alt="" draggable="false"> -->
-            <p>{{ specialDesc }}</p>
-            <button class="see-more" />
+            <img
+              class="title"
+              src="@/assets/images/painting-menu-special-content-title.png"
+              alt=""
+              draggable="false"
+            >
+            <p class="desc">
+              {{ specialDesc }}
+            </p>
+            <button
+              class="see-more"
+              @click="isShowPaintingStyleDesc = true"
+            />
           </div>
           <div
             v-for="item in paintingGroup"
             :key="item['标题']"
             class="painting-item"
+            @click="router.push({
+              name: 'PaintingDetailList',
+              query: {
+                idx: Number(item['序号']) - 1,
+              }
+            })"
           >
             <div class="top-wrap">
-              <div class="author">
+              <div
+                class="author"
+                :class="{
+                  long: item['作者'].length >= 6,
+                }"
+              >
+                <img
+                  class="bg"
+                  src="@/assets/images/decoration-sun.png"
+                  alt=""
+                  draggable="false"
+                >
                 {{ item['作者'] }}
               </div>
               <div class="title">
-                {{ item['标题'].split('\n').join('') }}
+                {{ item['标题(展示)'].split('\n').join('') }}
               </div>
               <div class="type">
                 {{ item['装裱\/材质\/笔类型'] }}
@@ -61,7 +94,7 @@
             <div class="img-wrap">
               <img
                 class=""
-                :src="`${$env.VUE_APP_DEPLOY_ORIGIN}/configMultiMedia/paintings-thumb/${item['标题']}.jpg`"
+                :src="`${$env.BASE_URL}configMultiMedia/paintings-thumb/${item['标题']}.jpg`"
                 alt=""
                 draggable="false"
               >
@@ -78,13 +111,20 @@
     </ul>
     <BtnBack
       class="button-back"
-      @click="emit('close')"
+      @click="router.go(-1)"
     />
     <OperationTip
       class="operation-tip"
       direction="h"
       :is-show="isShowOperationTip"
     />
+
+    <Transition name="fade-in-out">
+      <PaintingStyleDesc
+        v-if="isShowPaintingStyleDesc"
+        @close="isShowPaintingStyleDesc = false"
+      />
+    </Transition>
   </div>
 </template>
 
@@ -93,6 +133,7 @@ import { ref, computed, watch, onMounted, inject } from "vue"
 import { useRoute, useRouter } from "vue-router"
 import { useStore } from "vuex"
 import useSizeAdapt from "@/useFunctions/useSizeAdapt"
+import PaintingStyleDesc from "@/views/PaintingStyleDesc.vue"
 
 const route = useRoute()
 const router = useRouter()
@@ -100,8 +141,6 @@ const store = useStore()
 
 const $env = inject('$env')
 
-const emit = defineEmits(['close'])
-
 const {
   windowSizeInCssForRef,
   windowSizeWhenDesignForRef,
@@ -111,13 +150,10 @@ const menuEl = ref(null)
 const menuElScrollLeft = ref(0)
 onMounted(() => {
   menuEl.value.addEventListener('scroll', (e) => {
-    menuElScrollLeft.value = menuEl.value.scrollTop
+    menuElScrollLeft.value = menuEl.value.scrollLeft
   })
 })
 
-/**
- * 目录
- */
 const menuInfo = {}
 const temp = configExcel['画作'].map((item) => {
   return item['朝代']
@@ -129,18 +165,37 @@ for (const painting of configExcel['画作']) {
   }
   menuInfo[painting['朝代']].push(painting)
 }
-const ageCnToEn = {
-  '宋': 'Song',
-  '元': 'Yuan',
-  '明': 'Ming',
-  '清': 'Qing',
+
+const ageRenderInfo = {
+  '宋': {
+    En: 'Song',
+    artFontImg: require(`@/assets/images/painting-menu-item-title-song.png`),
+    coverBg: require(`@/assets/images/painting-menu-item-cover-bg-song.png`),
+  },
+  '元': {
+    En: 'Yuan',
+    artFontImg: require(`@/assets/images/painting-menu-item-title-yuan.png`),
+    coverBg: require(`@/assets/images/painting-menu-item-cover-bg-yuan.png`),
+  },
+  '明': {
+    En: 'Ming',
+    artFontImg: require(`@/assets/images/painting-menu-item-title-ming.png`),
+    coverBg: require(`@/assets/images/painting-menu-item-cover-bg-ming.png`),
+  },
+  '清': {
+    En: 'Qing',
+    artFontImg: require(`@/assets/images/painting-menu-item-title-qing.png`),
+    coverBg: require(`@/assets/images/painting-menu-item-cover-bg-qing.png`),
+  },
 }
+
 function getAuthorList(paintingGroup) {
   const temp = paintingGroup.map((item) => {
     return item['作者']
   })
   return Array.from(new Set(temp))
 }
+
 function getPaintingSizeString(raw) {
   const temp = raw.split('\n')
   let height = temp[0]
@@ -149,6 +204,7 @@ function getPaintingSizeString(raw) {
   width = width.substring(1, width.length - 2)
   return `${width}\u00D7${height} 厘米`
 }
+
 const paintingWidthWhenDesign = 240
 const paintingMarginWhenDesin = 75
 const specialDescWidthWhenDesin = 444
@@ -159,6 +215,7 @@ function getHiddenContentWidth(paintingGroup, ageName) {
   }
   return `${temp / windowSizeWhenDesignForRef.value * Number(windowSizeInCssForRef.value.substring(0, windowSizeInCssForRef.value.length - 2))}px`
 }
+
 const expandedAgeNameList = ref(new Set())
 function onClickAge(ageName) {
   if (expandedAgeNameList.value.has(ageName)) {
@@ -167,7 +224,10 @@ function onClickAge(ageName) {
     expandedAgeNameList.value.add(ageName)
   }
 }
-const specialDesc = configExcel['其他'][3]['修篁树石图'][1]['作品简介'].split('\n')[0]
+
+const specialDesc = configExcel['其他'][4]['修篁树石图'][1]['作品简介'].split('\n')[0]
+
+const isShowPaintingStyleDesc = ref(false)
 
 const isShowOperationTip = ref(true)
 watch(menuElScrollLeft, (v) => {
@@ -179,7 +239,7 @@ watch(menuElScrollLeft, (v) => {
 </script>
 
 <style lang="less" scoped>
-.painting-list-menu{
+.painting-list{
   position: absolute;
   left: 0;
   top: 0;
@@ -201,20 +261,20 @@ watch(menuElScrollLeft, (v) => {
       align-items: center;
       >.cover{
         flex: 0 0 auto;
-        height: 100%;
+        height: calc(534 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-left: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         padding-right: calc(22 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         writing-mode: vertical-lr;
+        background-size: cover;
+        background-repeat: no-repeat;
+        background-position: center center;
         >.age{
-          margin-top: calc(334 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-          font-family: KingHwa_OldSong, KingHwa_OldSong;
-          font-weight: 400;
-          font-size: calc(34 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-          color: #fff;
-          line-height: calc(40 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          margin-top: calc(171 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          width: calc(34 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          height: calc(44 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         }
         >.age-en{
-          margin-top: calc(334 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          margin-top: calc(176 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           font-family: KingHwa_OldSong, KingHwa_OldSong;
           font-weight: 400;
           font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -222,7 +282,7 @@ watch(menuElScrollLeft, (v) => {
           line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         }
         >.author-list{
-          margin-top: calc(334 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          margin-top: calc(176 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           font-family: KaiTi, KaiTi;
           font-weight: 400;
           font-size: calc(16 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
@@ -244,17 +304,42 @@ watch(menuElScrollLeft, (v) => {
         transition: width 1s;
         overflow: hidden;
         display: flex;
+        align-items: flex-end;
+        padding-bottom: calc(230 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
         background-color: #f9f7f2;
         height: 100%;
         >.special-desc{
           flex: 0 0 auto;
-          >img.logo{
-
+          width: calc(v-bind('specialDescWidthWhenDesin') / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          >img.title{
+            flex: 0 0 auto;
+            width: calc(133 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            height: calc(133 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            margin-right: calc(12 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
           }
-          >p{
-
+          >p.desc{
+            writing-mode: vertical-lr;
+            font-family: KaiTi, KaiTi;
+            font-weight: 400;
+            font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            color: #476446;
+            line-height: 2;
+            text-align: justified;
+            height: calc(552 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            letter-spacing: 0.15em;
           }
           >button.see-more{
+            width: calc(34 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            height: calc(94 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            background-image: url(@/assets/images/see-more-btn.png);
+            background-size: contain;
+            background-repeat: no-repeat;
+            background-position: center center;
+            margin-left: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+            transform: translateY(180%);
 
           }
         }
@@ -269,11 +354,11 @@ watch(menuElScrollLeft, (v) => {
           flex-direction: column;
           align-items: center;
           >.top-wrap{
-            height: 0;
-            width: 0;
-            margin-top: calc(297 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
             margin-bottom: calc(29 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
             position: relative;
+            display: flex;
+            justify-content: center;
+            align-items: center;
             >.author{
               writing-mode: vertical-lr;
               font-family: KingHwa_OldSong, KingHwa_OldSong;
@@ -281,9 +366,22 @@ watch(menuElScrollLeft, (v) => {
               font-size: calc(34 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
               color: #474747;
               white-space: pre;
-              position: absolute;
-              right: 0;
-              bottom: calc(18 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+              transform: translateY(-50%);
+              margin-right: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+              position: relative;
+              letter-spacing: 0.3em;
+              >img.bg{
+                width: calc(27 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+                position: absolute;
+                left: 0;
+                top: 50%;
+                transform: translate(-34%, 9%);
+                z-index: -1;
+              }
+            }
+            >.author.long{
+              transform: initial;
+              letter-spacing: initial;
             }
             >.title{
               writing-mode: vertical-lr;
@@ -292,9 +390,8 @@ watch(menuElScrollLeft, (v) => {
               font-size: calc(13 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
               color: #474747;
               white-space: pre;
-              position: absolute;
-              left: calc(11 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-              bottom: 0;
+              margin-right: calc(9 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+              letter-spacing: 0.2em;
             }
             >.type{
               writing-mode: vertical-lr;
@@ -303,9 +400,7 @@ watch(menuElScrollLeft, (v) => {
               font-size: calc(13 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
               color: #474747;
               white-space: pre;
-              position: absolute;
-              left: calc(31 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
-              bottom: calc(0 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+              letter-spacing: 0.2em;
             }
           }
           >.img-wrap{

+ 82 - 0
src/views/PaintingStyleDesc.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="painting-style-desc">
+    <div class="bg-left" />
+    <img
+      class="title"
+      src="@/assets/images/painting-style-title.png"
+      alt=""
+      draggable="false"
+    >
+    <div class="text">
+      {{ specialDesc }}
+    </div>
+    <BtnBack
+      class="button-back"
+      @click="emit('close')"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, watch, onMounted, inject } from "vue"
+import { useRoute, useRouter } from "vue-router"
+import { useStore } from "vuex"
+import useSizeAdapt from "@/useFunctions/useSizeAdapt"
+
+const route = useRoute()
+const router = useRouter()
+const store = useStore()
+
+const $env = inject('$env')
+
+const emit = defineEmits('close')
+
+const {
+  windowSizeInCssForRef,
+  windowSizeWhenDesignForRef,
+} = useSizeAdapt()
+
+const specialDesc = configExcel['其他'][4]['修篁树石图'][1]['作品简介']
+</script>
+
+<style lang="less" scoped>
+.painting-style-desc{
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  >.bg-left{
+    background: linear-gradient(90deg, #7b916b 0%, #94a586 100%);
+    position: absolute;
+    left: 0;
+    top: 0;
+    height: 100%;
+    width: calc(57 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    background: -1;
+  }
+  >img.title{
+    position: absolute;
+    top: calc(39 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    left: calc(1 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    width: calc(133 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    height: calc(133 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+  }
+  >.text{
+    position: absolute;
+    top: 24%;
+    right: 9.5%;
+    width: 67%;
+    height: 66%;
+    font-family: KaiTi, KaiTi;
+    font-weight: 400;
+    font-size: calc(20 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    color: #474747;
+    line-height: calc(23 / v-bind('windowSizeWhenDesignForRef') * v-bind('windowSizeInCssForRef'));
+    white-space: pre-line;
+    overflow: auto;
+    padding-right: 0.5em;
+  }
+}
+</style>

+ 2 - 4
src/views/PoemList.vue

@@ -45,7 +45,7 @@
       >
         <div class="inner-wrap">
           <div class="title-wrap">
-            <h1>《{{ item['标题'] }}》</h1>
+            <h1>《{{ item['标题(展示)'] }}》</h1>
             <div class="sub-title">
               <span class="author">{{ item['作者'] }}</span>
               <span class="age">{{ item['朝代'] }}</span>
@@ -59,7 +59,7 @@
     <BtnBack
       v-show="!isShowMenu"
       class="button-back"
-      @click="emit('close')"
+      @click="router.go(-1)"
     />
     <OperationTip
       class="operation-tip"
@@ -132,8 +132,6 @@ const {
   windowSizeWhenDesignForRef,
 } = useSizeAdapt()
 
-const emit = defineEmits(['close'])
-
 const poemList = configExcel['诗词']
 
 /**