ソースを参照

feat(PictureEditor): 添加图片尺寸调整功能

- 在图片编辑模块中新增尺寸调整工具
- 实现图片宽高独立调整功能
- 添加保持宽高比选项
- 集成到图片编辑工具栏中
- 实现图片尺寸实时预览和更新
- 支持比例锁定的智能缩放功能
panqiuyao 6 日 前
コミット
69068a0fae

+ 81 - 2
frontend/src/views/components/PictureEditor/mixin/edit/index.js

@@ -56,7 +56,14 @@ export default  {
       clipSettings: {
         ...DEFAULT_CLIP_SETTINGS,
       },
-      strokeObj: null // 用于引用当前描边图形
+      strokeObj: null, // 用于引用当前描边图形
+      imageSize: {
+        width: 100,
+        height: 100,
+        keepRatio: true,
+        originalRatio: 1, // 原始宽高比
+        lastAdjusted: 'width' // 最后调整的维度 ('width' 或 'height')
+      }
     }
   },
   props: {
@@ -96,6 +103,9 @@ export default  {
       }
 
       this.fontFamilyStyle = this.editLayer.fontFamily
+
+
+
       this.opacityValue = (this.editLayer && typeof this.editLayer.opacity === 'number')
         ? this.editLayer.opacity
         : 1
@@ -126,7 +136,19 @@ export default  {
           }
           break;
         case "image":
-
+          // 计算原始宽高比(基于图片的原始尺寸)
+          const originalWidth = this.editLayer.width || 100;
+          const originalHeight = this.editLayer.height || 100;
+          const originalRatio = originalWidth / originalHeight;
+
+          // 更新图片尺寸显示
+          this.imageSize = {
+            width: Math.round(this.editLayer.getScaledWidth() || originalWidth),
+            height: Math.round(this.editLayer.getScaledHeight() || originalHeight),
+            keepRatio: true,
+            originalRatio: originalRatio,
+            lastAdjusted: 'width'
+          };
 
           // 优先使用默认值
           let imageSettings = { ...DEFAULT_CLIP_SETTINGS };
@@ -170,6 +192,21 @@ export default  {
         fill: this.editLayer?.fill ?? '#000000',
         textAlign: this.editLayer?.textAlign ?? 'left',
       }
+
+      // 更新图片尺寸显示
+      if (this.editLayer && this.editLayer.type === 'image') {
+        const originalWidth = this.editLayer.width || 100;
+        const originalHeight = this.editLayer.height || 100;
+        const originalRatio = originalWidth / originalHeight;
+
+        this.imageSize = {
+          width: Math.round(this.editLayer.getScaledWidth() || originalWidth),
+          height: Math.round(this.editLayer.getScaledHeight() || originalHeight),
+          keepRatio: this.imageSize.keepRatio, // 保持当前的保持比例设置
+          originalRatio: originalRatio,
+          lastAdjusted: this.imageSize.lastAdjusted || 'width'
+        };
+      }
     }
   },
   created() {
@@ -567,6 +604,48 @@ export default  {
       // 更新画布状态
       this.updateCanvasState();
       this.fcanvas.requestRenderAll();
+    },
+
+    // 更新图片尺寸
+    updateImageSize(adjustedField) {
+      if (!this.judge() || this.editLayer.type !== 'image') return;
+
+      const { width, height, keepRatio } = this.imageSize;
+      const originalWidth = this.editLayer.width;
+      const originalHeight = this.editLayer.height;
+
+      if (keepRatio) {
+        // 保持宽高比的情况下,使用Fabric.js内置的scaleToWidth/scaleToHeight
+        // 这些函数本身就会保持比例
+        if (adjustedField === 'width') {
+          this.editLayer.scaleToWidth(width);
+          // 更新UI显示
+          this.imageSize.height = Math.round(this.editLayer.getScaledHeight());
+        } else {
+          this.editLayer.scaleToHeight(height);
+          // 更新UI显示
+          this.imageSize.width = Math.round(this.editLayer.getScaledWidth());
+        }
+      } else {
+        // 不保持比例的情况下,直接设置scaleX和scaleY
+        const scaleX = width / originalWidth;
+        const scaleY = height / originalHeight;
+
+        this.editLayer.set({
+          scaleX: scaleX,
+          scaleY: scaleY
+        });
+      }
+
+      // 重新计算边界和位置
+      this.editLayer.setCoords();
+
+      // 更新画布状态(撤销功能)
+      this.updateCanvasState();
+      this.fcanvas.requestRenderAll();
+
+      // 更新剪裁预览(如果有剪裁)
+      this.updateClipPreview && this.updateClipPreview(true);
     }
 
   }

+ 1 - 0
frontend/src/views/components/PictureEditor/mixin/edit/module/image.js

@@ -7,6 +7,7 @@ let image = ()=>{
       <div class="edit-wrap">
           <div class="title step-label"><span class="step-row_color">编辑内容</span></div>
           ${tools.flip()}
+          ${tools.size()}
           ${tools.straw()}
           ${tools.opacity()}
           ${tools.cutout()}

+ 36 - 0
frontend/src/views/components/PictureEditor/mixin/edit/module/tools.js

@@ -36,6 +36,42 @@ export default  {
           </div>
       `
   },
+  size(){
+    return `
+          <div class="title_two">尺寸</div>
+          <div class="flex left mar-top-10">
+            <div class="label fs-14 c-333 te-l" style="width: 35px;">宽</div>
+            <el-input-number
+              v-model="imageSize.width"
+              @change="updateImageSize('width')"
+              :min="1"
+              :max="5000"
+              :step="1"
+              size="small"
+              :controls="false"
+              style="width:100px;"
+            />
+            <span class="mar-left-10 c-999 fs-12">px</span>
+          </div>
+          <div class="flex left mar-top-10">
+            <div class="label fs-14 c-333 te-l" style="width: 35px;">高</div>
+            <el-input-number
+              v-model="imageSize.height"
+              @change="updateImageSize('height')"
+              :min="1"
+              :max="5000"
+              :step="1"
+              size="small"
+              :controls="false"
+              style="width:100px;"
+            />
+            <span class="mar-left-10 c-999 fs-12">px</span>
+          </div>
+          <div class="flex left mar-top-10">
+            <el-checkbox v-model="imageSize.keepRatio" size="small">保持比例</el-checkbox>
+          </div>
+      `
+  },
 cutout(){
   return `
     <div class="title_two">剪裁</div>