Procházet zdrojové kódy

预览图片绽放

shizhongqi před 1 rokem
rodič
revize
eed9637183

+ 90 - 36
hdApp/src/components/RichMediaViewer/index.vue

@@ -58,7 +58,7 @@
 
         <!-- 文本展示 -->
         <view v-else-if="item.type === 3" class="text-block">
-          <text class="text-content">{{ item.content }}</text>ß
+          <text class="text-content">{{ item.content }}</text>
         </view>
       </view>
 
@@ -92,11 +92,48 @@
             indicator-color="rgba(255,255,255,0.5)"
             indicator-active-color="#fff"
             style="height: 100%; width: 100%"
+            :disable-touch="swiperDisabled"
           >
             <swiper-item v-for="(img, index) in currentImageList" :key="index" class="swiper-item">
+              <movable-area class="movable-area">
+                <movable-view
+                  class="movable-view"
+                  direction="all"
+                  scale
+                  :scale-value="imageScales[index]"
+                  @scale="onScale"
+                  @touchend="onScaleEnd"
+                >
+                  <view class="preview-image-wrapper">
+                    <!-- 预览占位符 -->
+                    <view v-if="!previewImageStatus[index]" class="preview-placeholder">
+                      <view class="placeholder-content">
+                        <zui-svg-icon icon="general-image" :width="40" :height="40" color="#ccc" />
+                        <text class="placeholder-text">加载中...</text>
+                      </view>
+                    </view>
+                    <!-- 预览图片 -->
+                    <image
+                      v-show="previewImageStatus[index]"
+                      :src="img"
+                      mode="widthFix"
+                      class="preview-image"
+                      @error="onPreviewImageError(index)"
+                      @load="onPreviewImageLoad(index)"
+                      @longpress="saveImage"
+                    />
+                  </view>
+                </movable-view>
+              </movable-area>
+            </swiper-item>
+          </swiper>
+
+          <!-- 单张图片预览 -->
+          <movable-area v-else class="movable-area">
+            <movable-view class="movable-view" direction="all" scale :scale-value="imageScales[0]" @scale="onScale" @touchend="onScaleEnd">
               <view class="preview-image-wrapper">
                 <!-- 预览占位符 -->
-                <view v-if="!previewImageStatus[index]" class="preview-placeholder">
+                <view v-if="!previewImageStatus[0]" class="preview-placeholder">
                   <view class="placeholder-content">
                     <zui-svg-icon icon="general-image" :width="40" :height="40" color="#ccc" />
                     <text class="placeholder-text">加载中...</text>
@@ -104,38 +141,17 @@
                 </view>
                 <!-- 预览图片 -->
                 <image
-                  v-show="previewImageStatus[index]"
-                  :src="img"
+                  v-show="previewImageStatus[0]"
+                  :src="currentPreviewImage"
                   mode="widthFix"
-                  class="preview-image"
-                  @error="onPreviewImageError(index)"
-                  @load="onPreviewImageLoad(index)"
+                  class="preview-image single"
+                  @error="onPreviewImageError(0)"
+                  @load="onPreviewImageLoad(0)"
                   @longpress="saveImage"
                 />
               </view>
-            </swiper-item>
-          </swiper>
-
-          <!-- 单张图片预览 -->
-          <view v-else class="preview-image-wrapper">
-            <!-- 预览占位符 -->
-            <view v-if="!previewImageStatus[0]" class="preview-placeholder">
-              <view class="placeholder-content">
-                <zui-svg-icon icon="general-image" :width="40" :height="40" color="#ccc" />
-                <text class="placeholder-text">加载中...</text>
-              </view>
-            </view>
-            <!-- 预览图片 -->
-            <image
-              v-show="previewImageStatus[0]"
-              :src="currentPreviewImage"
-              mode="widthFix"
-              class="preview-image single"
-              @error="onPreviewImageError(0)"
-              @load="onPreviewImageLoad(0)"
-              @longpress="saveImage"
-            />
-          </view>
+            </movable-view>
+          </movable-area>
         </view>
 
         <!-- 操作按钮区域 -->
@@ -186,7 +202,10 @@ export default {
       currentImageIndex: 0,
       previewImageStatus: {}, // 预览图片加载状态
       IMGHOST,
-      throttledCheckVisibility: null
+      throttledCheckVisibility: null,
+      imageScales: {}, // 图片缩放比例
+      currentScale: 1, // 当前实时缩放值
+      swiperDisabled: false // 是否禁用swiper滑动
     };
   },
   created() {
@@ -343,6 +362,8 @@ export default {
       this.showImagePreview = true;
       // 初始化预览图片状态
       this.previewImageStatus = { 0: false };
+      this.$set(this.imageScales, 0, 1);
+      this.currentScale = 1;
     },
 
     // 预览小图(支持左右滑动)
@@ -357,10 +378,14 @@ export default {
       this.showImagePreview = true;
       // 初始化预览图片状态
       const newStatus = {};
+      const newScales = {};
       fullImageList.forEach((_, imgIndex) => {
         newStatus[imgIndex] = false;
+        newScales[imgIndex] = 1;
       });
       this.previewImageStatus = newStatus;
+      this.imageScales = newScales;
+      this.currentScale = 1;
     },
 
     // 关闭图片预览
@@ -370,14 +395,36 @@ export default {
       this.currentImageList = [];
       this.currentImageIndex = 0;
       this.previewImageStatus = {};
+      this.imageScales = {};
+      this.swiperDisabled = false;
+      this.currentScale = 1;
     },
 
     // swiper变化事件
     onSwiperChange(e) {
+      // 重置上一张图片的缩放
+      this.$set(this.imageScales, this.currentImageIndex, 1);
+
       this.currentImageIndex = e.detail.current;
       this.currentPreviewImage = this.currentImageList[this.currentImageIndex];
+      this.currentScale = this.imageScales[this.currentImageIndex] || 1;
+      this.swiperDisabled = this.currentScale !== 1;
     },
 
+    // 图片缩放时触发
+    onScale(e) {
+      this.currentScale = e.detail.scale;
+      if (this.currentImageList.length > 1) {
+        this.swiperDisabled = this.currentScale !== 1;
+      }
+    },
+
+    // 缩放手势结束时触发
+    onScaleEnd() {
+      this.$set(this.imageScales, this.currentImageIndex, this.currentScale);
+    },
+
+
     // 上一张图片
     prevImage() {
       if (this.currentImageIndex > 0) {
@@ -690,6 +737,18 @@ export default {
   }
 }
 
+.movable-area {
+  width: 100%;
+  height: 100%;
+}
+.movable-view {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
 .preview-image-wrapper {
   position: relative;
   width: 100%;
@@ -785,11 +844,6 @@ export default {
   .small-images-container {
     .small-image-item {
       width: calc(50% - 6rpx);
-
-      /* gap属性可以处理间距,无需额外设置 */
-      /* &:nth-child(odd) {
-        margin-right: 6rpx;
-      } */
     }
   }
 

+ 86 - 28
mallApp/src/components/RichMediaViewer/index.vue

@@ -92,11 +92,47 @@
             indicator-color="rgba(255,255,255,0.5)"
             indicator-active-color="#fff"
             style="height: 100%; width: 100%;"
+            :disable-touch="swiperDisabled"
           >
             <swiper-item v-for="(img, index) in currentImageList" :key="index" class="swiper-item">
+              <movable-area class="movable-area">
+                <movable-view
+                  class="movable-view"
+                  direction="all"
+                  scale
+                  :scale-value="imageScales[index]"
+                  @scale="onScale"
+                  @touchend="onScaleEnd"
+                >
+                  <view class="preview-image-wrapper">
+                    <!-- 预览占位符 -->
+                    <view v-if="!previewImageStatus[index]" class="preview-placeholder">
+                      <view class="placeholder-content">
+                        <zui-svg-icon icon="general-image" :width="40" :height="40" color="#ccc" />
+                        <text class="placeholder-text">加载中...</text>
+                      </view>
+                    </view>
+                    <!-- 预览图片 -->
+                    <image
+                      v-show="previewImageStatus[index]"
+                      :src="img"
+                      mode="widthFix"
+                      class="preview-image"
+                      @error="onPreviewImageError(index)"
+                      @load="onPreviewImageLoad(index)"
+                    />
+                  </view>
+                </movable-view>
+              </movable-area>
+            </swiper-item>
+          </swiper>
+
+          <!-- 单张图片预览 -->
+          <movable-area v-else class="movable-area">
+            <movable-view class="movable-view" direction="all" scale :scale-value="imageScales[0]" @scale="onScale" @touchend="onScaleEnd">
               <view class="preview-image-wrapper">
                 <!-- 预览占位符 -->
-                <view v-if="!previewImageStatus[index]" class="preview-placeholder">
+                <view v-if="!previewImageStatus[0]" class="preview-placeholder">
                   <view class="placeholder-content">
                     <zui-svg-icon icon="general-image" :width="40" :height="40" color="#ccc" />
                     <text class="placeholder-text">加载中...</text>
@@ -104,36 +140,16 @@
                 </view>
                 <!-- 预览图片 -->
                 <image
-                  v-show="previewImageStatus[index]"
-                  :src="img"
+                  v-show="previewImageStatus[0]"
+                  :src="currentPreviewImage"
                   mode="widthFix"
-                  class="preview-image"
-                  @error="onPreviewImageError(index)"
-                  @load="onPreviewImageLoad(index)"
+                  class="preview-image single"
+                  @error="onPreviewImageError(0)"
+                  @load="onPreviewImageLoad(0)"
                 />
               </view>
-            </swiper-item>
-          </swiper>
-
-          <!-- 单张图片预览 -->
-          <view v-else class="preview-image-wrapper">
-            <!-- 预览占位符 -->
-            <view v-if="!previewImageStatus[0]" class="preview-placeholder">
-              <view class="placeholder-content">
-                <zui-svg-icon icon="general-image" :width="40" :height="40" color="#ccc" />
-                <text class="placeholder-text">加载中...</text>
-              </view>
-            </view>
-            <!-- 预览图片 -->
-            <image
-              v-show="previewImageStatus[0]"
-              :src="currentPreviewImage"
-              mode="widthFix"
-              class="preview-image single"
-              @error="onPreviewImageError(0)"
-              @load="onPreviewImageLoad(0)"
-            />
-          </view>
+            </movable-view>
+          </movable-area>
         </view>
       </view>
     </view>
@@ -169,6 +185,9 @@ export default {
       previewImageStatus: {}, // 预览图片加载状态
       IMGHOST: this.$constant.imgUrl,
       throttledCheckVisibility: null,
+      imageScales: {}, // 图片缩放比例
+      currentScale: 1, // 当前实时缩放值
+      swiperDisabled: false // 是否禁用swiper滑动
     }
   },
   created() {
@@ -292,6 +311,8 @@ export default {
       this.showImagePreview = true
       // 初始化预览图片状态
       this.previewImageStatus = { 0: false }
+      this.$set(this.imageScales, 0, 1)
+      this.currentScale = 1
     },
 
     // 预览小图(支持左右滑动)
@@ -306,10 +327,14 @@ export default {
       this.showImagePreview = true
       // 初始化预览图片状态
       const newStatus = {}
+      const newScales = {}
       fullImageList.forEach((_, imgIndex) => {
         newStatus[imgIndex] = false
+        newScales[imgIndex] = 1
       })
       this.previewImageStatus = newStatus
+      this.imageScales = newScales
+      this.currentScale = 1
     },
 
     // 关闭图片预览
@@ -319,12 +344,33 @@ export default {
       this.currentImageList = []
       this.currentImageIndex = 0
       this.previewImageStatus = {}
+      this.imageScales = {}
+      this.swiperDisabled = false
+      this.currentScale = 1
     },
 
     // swiper变化事件
     onSwiperChange(e) {
+      // 重置上一张图片的缩放
+      this.$set(this.imageScales, this.currentImageIndex, 1)
+
       this.currentImageIndex = e.detail.current
       this.currentPreviewImage = this.currentImageList[this.currentImageIndex]
+      this.currentScale = this.imageScales[this.currentImageIndex] || 1
+      this.swiperDisabled = this.currentScale !== 1
+    },
+
+    // 图片缩放时触发
+    onScale(e) {
+      this.currentScale = e.detail.scale
+      if (this.currentImageList.length > 1) {
+        this.swiperDisabled = this.currentScale !== 1
+      }
+    },
+
+    // 缩放手势结束时触发
+    onScaleEnd() {
+      this.$set(this.imageScales, this.currentImageIndex, this.currentScale)
     },
 
     // 上一张图片
@@ -654,6 +700,18 @@ export default {
   }
 }
 
+.movable-area {
+  width: 100%;
+  height: 100%;
+}
+.movable-view {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
 .preview-image-wrapper {
   position: relative;
   width: 100%;