瀏覽代碼

Merge branch 'master' into lhd

natasha 1 月之前
父節點
當前提交
07fa194a15

+ 32 - 45
src/views/book/courseware/preview/components/audio/AudioPreview.vue

@@ -1,5 +1,5 @@
 <template>
-  <div ref="audioArea" class="audio-area" :style="getAreaStyle()">
+  <div ref="audioArea" class="audio-preview" :style="getAreaStyle()">
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
     <div ref="audioAreaBox" class="main">
@@ -189,64 +189,51 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.audio-area {
-  display: grid;
-  gap: 6px;
-  padding: 8px;
+@use '@/styles/mixin.scss' as *;
 
-  > .main {
-    margin: 0 auto;
+.audio-preview {
+  @include preview-base;
 
-    > span {
-      display: flex;
+  .view-independent {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 16px;
+
+    > li {
+      min-width: 280px;
     }
   }
 
-  .main {
-    grid-area: main;
-    width: 100%;
+  .view-icon {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 16px 50px;
+  }
 
-    .view-independent {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 16px;
+  .view-list {
+    display: flex;
+    flex-direction: column;
 
-      > li {
-        min-width: 280px;
+    :deep .el-carousel {
+      flex: 1;
+      background-color: #f8f8f8;
+      border-radius: 4px;
+
+      &__container {
+        height: 128px;
       }
-    }
 
-    .view-icon {
-      display: flex;
-      flex-wrap: wrap;
-      gap: 16px 50px;
+      &__item {
+        transition: none !important;
+      }
     }
 
-    .view-list {
+    .view-list-bottom {
       display: flex;
       flex-direction: column;
 
-      :deep .el-carousel {
-        flex: 1;
-        background-color: #f8f8f8;
-        border-radius: 4px;
-
-        &__container {
-          height: 128px;
-        }
-
-        &__item {
-          transition: none !important;
-        }
-      }
-
-      .view-list-bottom {
-        display: flex;
-        flex-direction: column;
-
-        li {
-          border-top: 1px solid #ccc;
-        }
+      li {
+        border-top: 1px solid #ccc;
       }
     }
   }

+ 2 - 2
src/views/book/courseware/preview/components/divider/DividerPreview.vue

@@ -18,7 +18,7 @@ export default {
   computed: {
     settingStyle() {
       return {
-        margin: `${this.data.property.height / 2}px auto ${this.data.property.height / 2}px`,
+        margin: `${this.data.property.height / 2}px auto`,
         border: 'none',
         borderTop: `1px ${this.data.property.line_type} ${this.data.property.color}`,
         width: `${this.data.property.width}px`,
@@ -26,7 +26,7 @@ export default {
     },
     settingWavyStyle() {
       return {
-        margin: `${this.data.property.height / 2}px auto ${this.data.property.height / 2}px`,
+        margin: `${this.data.property.height / 2}px auto`,
         width: `${this.data.property.width}px`,
         color: `${this.data.property.color}`,
         letterSpacing: `${this.data.property.width}px`,

+ 101 - 121
src/views/book/courseware/preview/components/picture/PicturePreview.vue

@@ -1,5 +1,5 @@
 <template>
-  <div ref="pictureArea" class="picture-area" :style="getAreaStyle()">
+  <div ref="pictureArea" class="picture-preview" :style="getAreaStyle()">
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
     <div ref="pictureAreaBox" class="main">
       <div class="view-area">
@@ -70,8 +70,9 @@ export default {
       viewLeftRightBtn: false,
       fileLen: 0,
       elementID: '',
-      pictureObserversMap: {},
       curPictureMemoIndex: 0,
+      isResizing: false,
+      resizeObserver: null,
     };
   },
   watch: {
@@ -80,8 +81,6 @@ export default {
         this.fileLen = val.file_list.length;
         if (this.fileLen > 0 && this.data.property.view_method === 'list') {
           const ele = this.$refs.pictureAreaBox;
-          // this.elementWidth = ele.clientWidth;
-          // this.elementHeight = ele.clientHeight;
 
           const sn_position = this.data.property.sn_position;
           const viewMemo = this.isEnable(this.data.property.view_memo);
@@ -130,49 +129,44 @@ export default {
         this.isViewLeftRightBtn();
         return;
       }
-      const mainEle = this.$refs.pictureArea;
-      // 检查元素是否包含已知的类名
-      mainEle.classList.forEach((className) => {
-        // 排除已知的类名
-        if (className !== 'audio-area') {
-          // 打印另一个类名
-          this.elementID = className;
-        }
-      });
-
-      const instanceName = `observer_${this.elementID}`;
-      this.pictureObserversMap[instanceName] = new ResizeObserver((entries) => {
+      this.resizeObserver = new ResizeObserver((entries) => {
         if (!this.getDragStatus()) return;
+        this.isResizing = true; // 标记为调整中
         for (let entry of entries) {
           window.requestAnimationFrame(() => {
             const sn_position = this.data.property.sn_position;
             const viewMemo = this.isEnable(this.data.property.view_memo);
             // 序号在上方和下方减去序号高度,在左右去掉padding(8*2)
+            let w = viewMemo ? (entry.contentRect.width - 16) * 0.8 : entry.contentRect.width - 16;
+            let h = entry.contentRect.height;
             if (sn_position.includes('top') || sn_position.includes('bottom')) {
-              this.elementWidth = viewMemo ? entry.contentRect.width * 0.8 : entry.contentRect.width;
-              this.elementHeight = entry.contentRect.height - 30;
+              w = viewMemo ? entry.contentRect.width * 0.8 : entry.contentRect.width;
+              h = entry.contentRect.height - 30;
+            }
+            // eslint-disable-next-line no-negated-condition
+            if (this.elementWidth !== w) {
+              this.elementWidth = w;
             } else {
-              this.elementWidth = viewMemo ? (entry.contentRect.width - 16) * 0.8 : entry.contentRect.width - 16;
-              this.elementHeight = entry.contentRect.height;
+              this.elementHeight = h;
             }
           });
         }
+
+        // 防抖:100ms 后恢复监听
+        setTimeout(() => {
+          this.isResizing = false;
+        }, 500);
       });
-      this.pictureObserversMap[instanceName].observe(this.$el);
+      this.resizeObserver.observe(this.$el);
     });
   },
   beforeDestroy() {
-    Object.values(this.pictureObserversMap).forEach((observer) => {
-      observer.disconnect();
-    });
+    // Object.values(this.pictureObserversMap).forEach((observer) => {
+    //   observer.disconnect();
+    // });
+    this.resizeObserver.disconnect();
   },
   methods: {
-    handleResize() {
-      const width = this.$refs.pictureAreaBox.clientWidth;
-      if (width !== this.elementWidth) {
-        this.elementWidth = width;
-      }
-    },
     // 是否显示左右箭头
     isViewLeftRightBtn() {
       // 计算底部列表图片宽度
@@ -219,116 +213,83 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.picture-area {
-  display: grid;
-  gap: 6px;
-  float: left;
-  padding: 8px;
-
-  > .main {
-    display: flex;
-    margin: 4px auto;
-
-    > span {
-      display: flex;
-    }
-  }
+@use '@/styles/mixin.scss' as *;
 
-  .main {
-    grid-area: main;
-    width: 100%;
+.picture-preview {
+  @include preview-base;
 
-    .view-area {
-      .memo-area {
-        float: left;
-        width: 15%;
-        padding-left: 5px;
-        text-align: left;
-        border-left: 1px solid #eee;
+  .view-area {
+    display: flex;
+    column-gap: 7px;
 
-        .title-div {
-          font-size: 16px;
-          font-weight: 600;
-        }
+    .memo-area {
+      padding-left: 5px;
+      text-align: left;
+      border-left: 1px solid #eee;
 
-        .memo-div {
-          color: #706f78;
-          overflow-wrap: break-word;
-        }
+      .title-div {
+        font-size: 16px;
+        font-weight: 600;
       }
 
-      :deep .el-carousel {
-        margin-bottom: 17px;
-        background-color: #d9d9d9;
-
-        &__container::before {
-          display: inline-block;
-          padding-bottom: 55%;
-          content: '';
-        }
+      .memo-div {
+        color: #706f78;
+        overflow-wrap: break-word;
+      }
+    }
 
-        &__container {
-          height: 100%;
-        }
+    :deep .el-carousel {
+      margin-bottom: 17px;
+      background-color: #d9d9d9;
 
-        &__item {
-          display: flex;
-          justify-content: center;
-          text-align: center;
-        }
+      &__container::before {
+        display: inline-block;
+        padding-bottom: 55%;
+        content: '';
       }
 
-      .container-box {
-        position: relative;
-
-        .left {
-          left: 0;
-        }
+      &__container {
+        height: 100%;
+      }
 
-        .arrow {
-          position: absolute;
-          top: 0;
-          z-index: 10;
-          height: 144px;
-          text-align: center;
-          background-color: rgba(0, 0, 0, 10%);
-          border-radius: 0;
-        }
+      &__item {
+        display: flex;
+        justify-content: center;
+        text-align: center;
+      }
+    }
 
-        .arrow:hover {
-          background-color: rgba(0, 0, 0, 30%);
-        }
+    .container-box {
+      position: relative;
 
-        .right {
-          right: 0;
-        }
+      .left {
+        left: 0;
+      }
 
-        .view-list-bottom {
-          display: flex;
-          flex-wrap: nowrap;
-          column-gap: 13px;
-          min-width: 144px;
-          overflow: hidden;
+      .arrow {
+        position: absolute;
+        top: 0;
+        z-index: 10;
+        height: 144px;
+        text-align: center;
+        background-color: rgba(0, 0, 0, 10%);
+        border-radius: 0;
+      }
 
-          li {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            background-color: #d9d9d9;
-          }
+      .arrow:hover {
+        background-color: rgba(0, 0, 0, 30%);
+      }
 
-          .el-image {
-            width: 144px;
-            height: 144px;
-            cursor: pointer;
-          }
-        }
+      .right {
+        right: 0;
       }
 
-      .view-independent {
+      .view-list-bottom {
         display: flex;
-        flex-wrap: wrap;
-        gap: 40px;
+        flex-wrap: nowrap;
+        column-gap: 13px;
+        min-width: 144px;
+        overflow: hidden;
 
         li {
           display: flex;
@@ -340,9 +301,28 @@ export default {
         .el-image {
           width: 144px;
           height: 144px;
+          cursor: pointer;
         }
       }
     }
+
+    .view-independent {
+      display: flex;
+      flex-wrap: wrap;
+      gap: 40px;
+
+      li {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        background-color: #d9d9d9;
+      }
+
+      .el-image {
+        width: 144px;
+        height: 144px;
+      }
+    }
   }
 }
 </style>