zq 11 месяцев назад
Родитель
Сommit
bf7ee0298e

+ 2 - 0
src/views/book/courseware/data/picture.js

@@ -21,6 +21,8 @@ export function getPictureData() {
     title: '图片',
     single_size: 2, // 单位MB
     total_size: 100, // 单位MB
+    min_width: '144', // 大于等于最小缩略图宽度
+    min_height: '306', // 大于等于2倍缩略图宽度加间隙高度
     property: getPictureProperty(),
     file_info_list: [],
     file_id_list: [], // 文件 id['20032-121212', '20032-121216']

+ 125 - 25
src/views/book/courseware/preview/components/picture/PicturePreview.vue

@@ -1,21 +1,30 @@
 <template>
-  <div class="picture_area" :style="getAreaStyle()">
+  <div class="picture-area" :style="getAreaStyle()">
     <SerialNumberPosition :property="data.property" />
 
-    <div class="main">
-      <div class="view_area">
-        <el-carousel
-          v-if="'list' === data.property.view_method"
-          ref="picture_carousel"
-          class="view_independent"
-          indicator-position="none"
-          :autoplay="false"
-        >
-          <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
-            <el-image :id="file.file_id" :src="file.file_url" fit="contain" />
-          </el-carousel-item>
-        </el-carousel>
-        <ul class="view_list">
+    <div ref="pictureArea" class="main">
+      <div class="view-area">
+        <template v-if="'list' === data.property.view_method">
+          <el-carousel ref="pictureCarousel" class="view-list" indicator-position="none" :autoplay="false">
+            <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
+              <el-image :id="file.file_id" :src="file.file_url" fit="contain" />
+            </el-carousel-item>
+          </el-carousel>
+          <div class="container-box">
+            <button v-if="viewLeftRightBtn" class="arrow left" @click="scroll(-1)">
+              <SvgIcon icon-class="pre" />
+            </button>
+            <ul ref="container" class="view-list-bottom" :style="{ width: elementWidth + 'px' }">
+              <li v-for="(file, i) in data.file_list" :key="i" @click="handleIndicatorClick(i)">
+                <el-image :id="file.file_id" :src="file.file_url" fit="contain" />
+              </li>
+            </ul>
+            <button v-if="viewLeftRightBtn" class="arrow right" @click="scroll(1)">
+              <SvgIcon icon-class="next" />
+            </button>
+          </div>
+        </template>
+        <ul v-else class="view-independent">
           <li v-for="(file, i) in data.file_list" :key="i" @click="handleIndicatorClick(i)">
             <el-image :id="file.file_id" :src="file.file_url" fit="contain" />
           </li>
@@ -36,21 +45,69 @@ export default {
     return {
       data: getPictureData(),
       curImgIndex: 0,
+      elementWidth: 0,
+      viewLeftRightBtn: false,
+      fileLen: 0,
     };
   },
+  watch: {
+    data: {
+      handler(val) {
+        this.fileLen = val.file_list.length;
+        if (this.fileLen > 0) {
+          // this.initResizeObserver();
+          this.elementWidth = this.$refs.pictureArea.clientWidth;
+          window.addEventListener('resize', this.handleResize);
+        }
+      },
+      deep: true,
+    },
+    elementWidth(newWidth, oldWidth) {
+      // console.log(`宽度从 ${oldWidth} 变为 ${newWidth}`);
+      this.elementWidth = newWidth;
+      this.isViewLeftRightBtn();
+    },
+  },
+  beforeDestroy() {
+    window.removeEventListener('resize', this.handleResize);
+  },
   methods: {
+    handleResize() {
+      const width = this.$refs.pictureArea.clientWidth;
+      if (width !== this.elementWidth) {
+        this.elementWidth = width;
+      }
+    },
+    // 是否显示左右箭头
+    isViewLeftRightBtn() {
+      // 计算底部列表图片宽度
+      let listWidth = this.fileLen * this.data.min_width + 13 * (this.fileLen - 1);
+      if (listWidth > this.elementWidth) {
+        this.viewLeftRightBtn = true;
+      } else {
+        this.viewLeftRightBtn = false;
+      }
+      this.$forceUpdate();
+    },
     handleIndicatorClick(index) {
       // 获取 Carousel 实例
-      const carousel = this.$refs.picture_carousel;
+      const carousel = this.$refs.pictureCarousel;
       // 切换到对应索引的图片
       carousel.setActiveItem(index);
     },
+    // 滚动图片列表
+    scroll(direction) {
+      const container = this.$refs.container;
+      const step = Number(this.data.min_width) + 13; // 每次滚动的距离
+      this.scrollPosition += step * direction;
+      container.scrollLeft += step * direction;
+    },
   },
 };
 </script>
 
 <style lang="scss" scoped>
-.picture_area {
+.picture-area {
   display: grid;
   gap: 6px;
   padding: 8px;
@@ -68,11 +125,11 @@ export default {
     grid-area: main;
     width: 100%;
 
-    .view_area {
+    .view-area {
       width: 100%;
 
       :deep .el-carousel {
-        margin-bottom: 16px;
+        margin-bottom: 17px;
         background-color: #d9d9d9;
 
         &__container::before {
@@ -92,11 +149,53 @@ export default {
         }
       }
 
-      .view_list {
-        display: grid;
-        grid-template-columns: repeat(6, 1fr);
-        grid-auto-rows: auto;
-        gap: 21px 32px;
+      .container-box {
+        position: relative;
+
+        .arrow {
+          position: absolute;
+          top: 0;
+          z-index: 10;
+          height: 144px;
+          text-align: center;
+          background-color: rgba(0, 0, 0, 10%);
+          border-radius: 0;
+        }
+
+        .arrow:hover {
+          background-color: rgba(0, 0, 0, 20%);
+        }
+
+        .right {
+          right: 0;
+        }
+
+        .view-list-bottom {
+          display: flex;
+          flex-wrap: nowrap;
+          column-gap: 13px;
+          min-width: 144px;
+          overflow: hidden;
+
+          li {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            background-color: #d9d9d9;
+          }
+
+          .el-image {
+            width: 144px;
+            height: 144px;
+            cursor: pointer;
+          }
+        }
+      }
+
+      .view-independent {
+        display: flex;
+        flex-wrap: wrap;
+        gap: 40px;
 
         li {
           display: flex;
@@ -106,7 +205,8 @@ export default {
         }
 
         .el-image {
-          cursor: pointer;
+          width: 144px;
+          height: 144px;
         }
       }
     }