Kaynağa Gözat

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

任一存 1 yıl önce
ebeveyn
işleme
a4834028d4

Dosya farkı çok büyük olduğundan ihmal edildi
+ 11 - 1
public/configExcel.js


BIN
public/configMultiMedia/paintings/竹禽图卷.jpg


BIN
src/assets/images/icon_change.png


src/assets/images/painting-box-back.png → src/assets/images/painting-box-close.png


BIN
src/assets/images/painting-box-img/ba.png


BIN
src/assets/images/painting-box-img/big-view.png


BIN
src/assets/images/painting-box-open.png


+ 358 - 0
src/components/PaintingDetailBox.vue

@@ -0,0 +1,358 @@
+<script setup>
+import { ref, onMounted, computed } from 'vue'
+
+const props = defineProps({
+  direction: {
+    type: String,
+    default: "横",
+  },
+  url: {
+    type: String,
+    default: "",
+  }
+})
+
+const isRow = computed(() => {
+  return props.direction
+})
+// 画作是否超过了屏幕(可以拖动)
+const isMove = ref(false)
+const imgWidth = ref(0)
+const imgHeight = ref(0)
+const pageHeight = ref(0)
+const zhouMove = ref(3)
+const tiemrr = ref(-1)
+// 画轴移动
+const isFlag = ref(false)
+const moveLoc = ref(0)
+// 横轴左侧大盒子的宽度
+const leftBoxWidth = ref(0)
+
+const mousemoveFu = (e, flag) => {
+  let ev = e || event
+  if (isFlag.value && isMove.value) {
+    if (isRow.value === "竖") {
+      // 最大能往下移动的距离
+      const maxNum = imgHeight.value - window.innerHeight
+
+      // 向上是负  向下是正
+      let temp = moveLoc.value + ev.movementY * (flag ? -5 : 1)
+
+      if (-temp < 0) temp = 0
+      else if (-temp >= maxNum) temp = -maxNum
+
+      moveLoc.value = temp
+    } else {
+      // 最大能往右移动的距离
+      const maxNum = imgWidth.value - leftBoxWidth.value
+      // 向左是负 向右是正
+      let temp = moveLoc.value + ev.movementX * (flag ? -5 : 1)
+      if (-temp < 0) temp = 0
+      else if (-temp >= maxNum) temp = -maxNum
+      moveLoc.value = temp
+    }
+  }
+}
+
+onMounted(() => {
+  const element = document.querySelector('#myElement')
+
+  const resizeObserver = new ResizeObserver(entries => {
+    for (let entry of entries) {
+      console.log(`Width changed to ${entry.contentRect.width}`)
+      // 在这里执行你的逻辑
+      // 判断画轴有没有超过屏幕
+      const pageHeightWindow = window.innerHeight
+      pageHeight.value = pageHeightWindow
+
+      moveLoc.value = 0
+      setTimeout(() => {
+        if (isRow.value === "竖") {
+          const dom = document.querySelector(".imgBox")
+          if (dom.offsetHeight > pageHeightWindow) {
+            isMove.value = true
+            imgWidth.value = dom.offsetWidth
+            imgHeight.value = dom.offsetHeight
+          }
+        } else {
+          const leftBoxWidthDom = document.querySelector(".leftBxo")
+          const leftBoxWidthDomWidth = leftBoxWidthDom.offsetWidth
+          leftBoxWidth.value = leftBoxWidthDomWidth
+          const dom = document.querySelector(".imgBoxHH")
+          if (dom.offsetWidth > leftBoxWidthDomWidth) {
+            isMove.value = true
+            imgWidth.value = dom.offsetWidth
+            imgHeight.value = dom.offsetHeight
+          }
+        }
+      }, 200)
+      tiemrr.value = setInterval(() => {
+        if (zhouMove.value >= 99) clearInterval(tiemrr.value)
+        zhouMove.value = zhouMove.value + 1
+      }, 30)
+    }
+  })
+
+  resizeObserver.observe(element)
+
+})
+</script>
+
+<template>
+  <div
+    id="myElement"
+    class="box"
+  >
+    <div
+      :class="`leftBxo ${isMove ? '' : isRow === '横' ? '' : 'leftBxoCenter'}`"
+    >
+      <!-- 左侧加号 -->
+      <div
+        class="addIcon"
+        @click="lookBigImg"
+      >
+        <el-image
+          :src="require('@/assets/images/painting-box-img/big-view.png')"
+          :max-scale="7"
+          :min-scale="0.2"
+          :preview-src-list="[props.url]"
+          fit="cover"
+        />
+        <!-- <img
+          src="@/assets/images/painting-box-img/big-view.png"
+          alt=""
+        > -->
+      </div>
+
+      <!--  ---------竖------- 大盒子 -->
+      <div
+        v-if="isRow === '竖'"
+        :class="`imgBox ${isMove ? '' : 'imgBoxMove'}`"
+        :style="`clip-path: rect(0 100% ${zhouMove}% 0);
+        transform: translateY(${moveLoc}px)
+        `"
+        @mousedown="isFlag = true"
+        @mouseup="isFlag = false"
+        @mouseleave="isFlag = false"
+        @mousemove="mousemoveFu"
+      >
+        <!-- 画轴的移动 -->
+        <img
+          class="zhou"
+          src="@/assets/images/painting-box-img/zhou.png"
+          alt=""
+          :style="`bottom:${100 - zhouMove}%`"
+        >
+
+        <img
+          :src="`${props.url}`"
+          alt=""
+        >
+      </div>
+
+      <!-- ------------横----------大盒子 -->
+      <div
+        v-else
+        :class="`imgBoxHH ${isMove ? '' : 'imgBoxHHMove'}`"
+        :style="`clip-path: rect(0 ${zhouMove}% 100% 0);
+        transform: translateX(${moveLoc}px) translateY(-50%)
+        `"
+        @mousedown="isFlag = true"
+        @mouseup="isFlag = false"
+        @mouseleave="isFlag = false"
+        @mousemove="mousemoveFu"
+      >
+        <!-- 画轴的移动 -->
+        <img
+          class="zhou"
+          src="@/assets/images/painting-box-img/zhouH.png"
+          alt=""
+          :style="`right:${100 - zhouMove}%`"
+        >
+
+        <img
+          :src="`${props.url}`"
+          alt=""
+        >
+      </div>
+
+      <!-- 右侧小盒子 -->
+      <div
+        v-if="isMove"
+        class="smImgBox"
+      >
+        <div
+          class="smImgBoxMain"
+          :style="`width:${imgWidth / 5}px; height:${imgHeight / 5}px`"
+        >
+          <div
+            v-if="isRow === '竖'"
+            class="smBoxBor"
+            :style="`height:${pageHeight / 5}px;transform: translateY(${
+              -moveLoc / 5
+            }px)`"
+            @mousedown="isFlag = true"
+            @mouseup="isFlag = false"
+            @mouseleave="isFlag = false"
+            @mousemove="(e) => mousemoveFu(e, true)"
+          />
+
+          <div
+            v-else
+            class="smBoxBorHH"
+            :style="`width:${leftBoxWidth / 5}px;transform: translateX(${
+              -moveLoc / 5
+            }px)`"
+            @mousedown="isFlag = true"
+            @mouseup="isFlag = false"
+            @mouseleave="isFlag = false"
+            @mousemove="(e) => mousemoveFu(e, true)"
+          />
+          <img
+            :src="
+              props.url
+            "
+            alt=""
+          >
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang='less' scoped>
+::v-deep(.el-image-viewer__actions__inner .el-icon:last-child),
+::v-deep(.el-image-viewer__actions__inner .el-icon:nth-last-child(2)){
+  display: none;
+}
+::v-deep(.el-image-viewer__btn .el-icon){
+  margin: auto 10px;
+}
+::deep(.el-image-viewer__actions){
+  width: 200px;
+}
+::deep(.el-image-viewer__actions__inner){
+  justify-content: center;
+}
+.box {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  .leftBxo {
+    // background-color: aquamarine;
+    width: 100%;
+    height: 100%;
+    position: relative;
+    text-align: center;
+    position: relative;
+    overflow: hidden;
+    .addIcon {
+      position: absolute;
+      bottom: 50px;
+      left: 50px;
+      cursor: pointer;
+      font-size: 30px;
+    }
+
+    // 竖大盒子
+    .imgBox {
+      cursor: grab;
+      height: auto;
+      overflow: hidden;
+      width: 46%;
+      // padding: 5% 3%;
+      padding:15% 3% 5% 3%;
+      white-space: nowrap;
+      display: inline-block;
+      background-image: url("@/assets/images/painting-box-img/ba.png");
+      background-size: 95% 100%;
+      background-repeat: no-repeat;
+      background-position: center;
+      position: relative;
+
+      .zhou {
+        position: absolute;
+        bottom: 100%;
+        left: 0;
+        width: 100%;
+      }
+      & > img {
+        pointer-events: none;
+        width: 100%;
+        display: inline-block;
+      }
+    }
+    .imgBoxMove {
+      cursor: default;
+      display: flex;
+      align-items: center;
+      margin: 0 auto;
+    }
+
+    // 横大盒子
+    .imgBoxHH {
+      cursor: grab;
+      width: auto;
+      overflow: hidden;
+      height: 55%;
+      padding: 3% 5%;
+      white-space: nowrap;
+      display: inline-block;
+      background-image: url("@/assets/images/painting-box-img/baH.png");
+      background-size: 100% 100%;
+      position: relative;
+      top: 50%;
+      .zhou {
+        position: absolute;
+        right: 100%;
+        top: 0;
+        height: 100%;
+      }
+      & > img {
+        pointer-events: none;
+        height: 100%;
+        display: inline-block;
+      }
+    }
+    .imgBoxHHMove {
+      cursor: default;
+    }
+
+    .smImgBox {
+      position: absolute;
+      bottom: 5px;
+      right: 5px;
+      background-color: rgba(0, 0, 0, 0.5);
+      padding: 10px 20px;
+      .smImgBoxMain {
+        overflow: hidden;
+        position: relative;
+        .smBoxBor {
+          cursor: grab;
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 100%;
+          border: 1px solid #fff;
+        }
+        .smBoxBorHH {
+          cursor: grab;
+          position: absolute;
+          top: 0;
+          left: 0;
+          height: 100%;
+          border: 1px solid #fff;
+        }
+        & > img {
+          height: 100%;
+          width: 100%;
+        }
+      }
+    }
+  }
+  .leftBxoCenter {
+    display: flex;
+    align-items: center;
+  }
+}
+</style>

+ 207 - 0
src/components/PaintingInfoBox.vue

@@ -0,0 +1,207 @@
+<script setup>
+import { ref, computed } from "vue"
+
+// 1-作品简介  2-作者简介
+const curState = computed(() => {
+  return props.state
+})
+
+const isCloseInfo = ref(false)
+
+const props = defineProps({
+  title: {
+    type: String,
+    required: true,
+  },
+  author: {
+    type: String,
+    required: true,
+  },
+  subtitle: {
+    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,
+  },
+  state: {
+    type: Number,
+    default: 1,
+  },
+  size: {
+    type: Object,
+    default: () => {
+      return {
+        width: 1,
+        height: 1,
+      }
+    },
+  },
+})
+
+const newTitle = computed(() => {
+  return props.title.split('\n')
+})
+</script>
+
+<template>
+  <div
+    class="info-box"
+    :class="{ 'info-box-close': isCloseInfo }"
+  >
+    <img
+      class="close-btn"
+      :src="require(`@/assets/images/painting-box-${isCloseInfo ? 'open':'close'}.png`)"
+      alt=""
+      @click="isCloseInfo = !isCloseInfo"
+    >
+    <div class="detail-box">
+      <div class="top">
+        <div class="title">
+          <div>{{ curState == 1 ? newTitle[0] : "作者简介" }}</div>
+          <div style="font-size: 20px;margin-top: 5px">
+            {{ newTitle.length>1 ? newTitle[1] : "" }}
+          </div>
+        </div>
+        <div
+          class="exchange"
+          @click="curState == 1 ? (curState = 2) : (curState = 1)"
+        >
+          <img
+            src="@/assets/images/icon_change.png"
+            alt=""
+          >
+          {{ curState == 1 ? "作者" : "作品" }}
+        </div>
+      </div>
+      <div class="line" />
+      <div
+        v-if="curState == 1"
+        class="bottom"
+      >
+        <p>{{ props.author }}</p>
+        <p>{{ props.size.width }} x {{ props.size.height }} 厘米</p>
+        <p>{{ props.subtitle }}</p>
+        <p>{{ props.location }}</p>
+        <br>
+        <p>{{ props.paintingDesc }}</p>
+      </div>
+      <div
+        v-else-if="curState == 2"
+        class="bottom"
+      >
+        <p>{{ props.authorDesc.length >0? props.authorDesc:'暂无信息' }}</p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="less" scoped>
+.info-box {
+  width: 60%;
+  height: 100%;
+  background: url(@/assets/images/painting-box-bg.png);
+  background-size: 100% 100%;
+  position: relative;
+  transition: width 1.5s ease;
+  .close-btn {
+    position: absolute;
+    top: 50%;
+    left: 1.5%;
+    transform: translateY(-50%);
+    cursor: pointer;
+    z-index: 10;
+  }
+  .detail-box {
+    width: 95%;
+    height: 100%;
+    position: absolute;
+    // background: rgba(153, 205, 50, 0.39);
+    right: 0;
+    padding: 7% 7% 0;
+    opacity: 1;
+    transition: opacity 1.5s ease;
+    white-space: nowrap;
+    .top {
+      width: 100%;
+      height: 65px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .title {
+        color: #ffecb0;
+        font-size: 44px;
+        font-family: "KingHwa_OldSong";
+        white-space: pre-wrap;
+      }
+      .exchange {
+        display: flex;
+        align-items: center;
+        color: #e1edd9;
+        font-size: 20px;
+        font-family: "KaiTi";
+        cursor: pointer;
+      }
+    }
+    .line {
+      width: 100%;
+      height: 1px;
+      background: #ffffff;
+      margin-top: 20px;
+    }
+    .bottom {
+      width: 100%;
+      margin-top: 20px;
+      height: 89%;
+      overflow: auto;
+      font-size: 30px;
+      line-height: 35px;
+      padding: 10px 40px 0 0 ;
+      color: #E1EDD9;
+      font-family: 'KaiTi';
+      p{
+        white-space: pre-wrap;
+      }
+      &::-webkit-scrollbar {
+        width: 4px;
+      }
+      /* 滚动条轨道(track)的样式 */
+      &::-webkit-scrollbar-track {
+        background: #f1f1f100; /* 轨道的背景颜色 */
+      }
+
+      /* 滚动条滑块(thumb)的样式 */
+      &::-webkit-scrollbar-thumb {
+        background: #e1edd942; /* 滑块的背景颜色 */
+        border-radius: 50px;
+      }
+    }
+  }
+}
+.info-box-close{
+  width: 2%;
+  background-size: cover;
+  >.detail-box {
+    // opacity: 0;
+    width: 0;
+    display: none;
+  }
+}
+</style>

+ 5 - 11
src/views/HomeView.vue

@@ -1,6 +1,6 @@
 <script setup>
-import { ref, inject, computed } from "vue"
-import { useRoute, useRouter } from "vue-router"
+import { ref, computed } from "vue"
+import { useRouter } from "vue-router"
 import { useStore } from "vuex"
 import Startup from "@/views/StartupView.vue"
 import useRollFu from "../rollFu.js"
@@ -9,7 +9,7 @@ import HotspotDetail3 from "@/views/HotspotDetail3.vue"
 import HotspotDetail1 from "@/views/HotspotDetail1.vue"
 
 const store = useStore()
-
+const router = useRouter()
 
 const { handleScroll } = useRollFu()
 
@@ -103,7 +103,7 @@ const scrollFu = (val) => {
     >
       <div
         class="page2-box"
-        @click="isShowPaintingDesc = true"
+        @click="() => {router.push('/painting-detail?idx=home')}"
       >
         <img
           src="@/assets/images/icon_home_detail-min.png"
@@ -114,7 +114,7 @@ const scrollFu = (val) => {
       <div
         class="page2-box"
         style="margin-top: 10px"
-        @click="isShowAuthorDesc = true"
+        @click="() => {router.push('/painting-detail?idx=home&state=2')}"
       >
         <img
           src="@/assets/images/icon_home_author-min.png"
@@ -274,12 +274,6 @@ const scrollFu = (val) => {
     // background: rgba(60, 89, 71, 0.65);
     background: url(@/assets/images/bg-mask.png);
     background-size: 100% 100%;
-    // backdrop-filter: blur(
-    //   calc(
-    //     22 / v-bind("windowSizeWhenDesignForRef") *
-    //       v-bind("windowSizeInCssForRef")
-    //   )
-    // );
   }
 
   > .startup {

+ 55 - 2
src/views/PaintingDetail.vue

@@ -1,10 +1,63 @@
 <script setup>
+import { onMounted, inject } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import PaintingDetailBox from '@/components/PaintingDetailBox.vue'
+import paintingInfoBox from '@/components/PaintingInfoBox.vue'
+
+const route = useRoute()
+const router = useRouter()
+
+
+const $env = inject("$env")
+
+
+const getPaintingSize = (raw) => {
+  const temp = raw.split('\n')
+  let height = temp[0]
+  let width = temp[1]
+  height = Number(height.substring(1, height.length - 2))
+  width = Number(width.substring(1, width.length - 2))
+  return {
+    width,
+    height,
+  }
+}
+
+//  idx 传入下标index
+const paintingInfo = route.query.idx == 'home' ? configExcel['首页画作'][0] : configExcel['画作'][route.query.idx]
+onMounted(() => {
+  console.log(paintingInfo)
+})
 </script>
 
 <template>
-  <div class="home" />
+  <div class="home">
+    <!-- 左侧图片交互区 -->
+    <PaintingDetailBox
+      :direction="paintingInfo['方向'] ? '横':'竖'"
+      :url="`${$env.BASE_URL}configMultiMedia/paintings/${paintingInfo['标题']}.jpg`"
+    />
+    <!-- 右侧信息展示区 -->
+    <paintingInfoBox
+      :title="paintingInfo['标题(展示)']"
+      :author="paintingInfo['注音']?paintingInfo['注音']:paintingInfo['作者']"
+      :age="paintingInfo['朝代']"
+      :subtitle="paintingInfo['装裱\/材质\/笔类型']"
+      :location="paintingInfo['馆藏']"
+      :painting-desc="paintingInfo['简介']"
+      :author-desc="paintingInfo['作者简介']"
+      :size="paintingInfo['尺寸'] ? getPaintingSize(paintingInfo['尺寸']) : ''"
+      :state="route.query.state ? Number(route.query.state) : 1"
+    />
+    <BtnBack @click="router.back()" />
+  </div>
 </template>
 
 <style lang='less' scoped>
-
+.home{
+  width: 100%;
+  height: 100%;
+  background: linear-gradient( 180deg, #AFCEA5 0%, #34492E 100%);
+  display:flex;
+}
 </style>