浏览代码

mod:剪裁处理

panqiuyao 6 月之前
父节点
当前提交
833a2e6939
共有 1 个文件被更改,包括 89 次插入36 次删除
  1. 89 36
      frontend/src/views/components/PictureEditor/mixin/edit/index.js

+ 89 - 36
frontend/src/views/components/PictureEditor/mixin/edit/index.js

@@ -4,6 +4,22 @@ import Teleport from '@/components/Teleport'
 import * as TextboxConfig from './module/TextboxConfig'
 import fabric from "../../js/fabric-adapter";
 import {markRaw} from "vue";
+// 将默认的 clipSettings 提取为常量
+const DEFAULT_CLIP_SETTINGS = {
+  shape: '',
+  width: 100,
+  height: 100,
+  radius: 50,
+  offsetX: 0,
+  offsetY: 0,
+  showClipStroke: true,
+  strokeColor: '#000000',
+  strokeWidth: 2,
+  rectRadius: 0,
+  svgUrl: '',
+  svgWidth: 100,
+  svgHeight: 100,
+};
 
 export default  {
   components: {
@@ -22,22 +38,9 @@ export default  {
       },
 
       clipSettings: {
-        shape: 'rect',      // 形状类型
-        width: 100,         // 矩形宽度
-        height: 100,        // 矩形高度
-        radius: 50,         // 圆形半径
-        offsetX: 0,         // 水平偏移
-        offsetY: 0,          // 垂直偏移
-        showClipStroke: true,  // 是否显示描边
-        strokeColor: '#000000',    // 描边颜色
-        strokeWidth: 2,            // 描边宽度
-        rectRadius: 0,              // 矩形圆角
-
-        shape: 'rect',      // 初始值保持不变
-        svgUrl: 'http://ossimg.valimart.net/uploads/20250610/FAxaPqxhgoj0Ub3uTU3omWMzyMYCoHdpgIK4qSXb.svg', // 添加默认SVG地址
-        svgWidth: 100,      // 可根据实际需求调整
-        svgHeight: 100      // 可根据实际需求调整
-      }
+        ...DEFAULT_CLIP_SETTINGS,
+      },
+      strokeObj: null // 用于引用当前描边图形
     }
   },
   props: {
@@ -65,22 +68,54 @@ export default  {
   watch: {
     editLayer(){
       this.fontFamilyStyle = this.editLayer.fontFamily
-      if(this.editLayer.type === "textbox"){
-        if(this.editLayer.shadow){
-          this.shadowText = {
-            x:this.editLayer.shadow.offsetX || 0,
-            y:this.editLayer.shadow.offsetY || 0,
-            vague:this.editLayer.shadow.blur || 0,
-            color:this.editLayer.shadow.color || '#000',
+      switch (this.editLayer.type){
+        case "textbox":
+          if(this.editLayer.shadow){
+            this.shadowText = {
+              x:this.editLayer.shadow.offsetX || 0,
+              y:this.editLayer.shadow.offsetY || 0,
+              vague:this.editLayer.shadow.blur || 0,
+              color:this.editLayer.shadow.color || '#000',
+            }
+          }else{
+            this.shadowText = {
+              x:0,
+              y:0,
+              vague:0,
+              color:'#000'
+            }
           }
-        }else{
-          this.shadowText = {
-            x:0,
-            y:0,
-            vague:0,
-            color:'#000'
+          break;
+        case "image":
+
+
+          // 优先使用默认值
+          let imageSettings = { ...DEFAULT_CLIP_SETTINGS };
+          // 若已有 clipPath,合并其中的属性
+          if (this.editLayer.clipPath) {
+            imageSettings = {
+              ...imageSettings,
+              width: this.editLayer.clipPath.width || imageSettings.width,
+              height: this.editLayer.clipPath.height || imageSettings.height,
+              offsetX: this.editLayer.clipPath.left || imageSettings.offsetX,
+              offsetY: this.editLayer.clipPath.top || imageSettings.offsetY,
+              shape: this.editLayer.clipPath.type || imageSettings.shape,
+            };
           }
-        }
+
+          // 如果没有剪裁路径,则 shape 为 ""
+          if (!this.editLayer.clipPath) {
+            imageSettings.shape = '';
+          }
+
+          // 更新 clipSettings,用于 UI 显示
+          this.clipSettings = imageSettings;
+
+          // 同步描边图形(如果存在)
+          if (this.editLayer.strokeObj) {
+            this.fcanvas.add(markRaw(this.editLayer.strokeObj));
+          }
+          break;
       }
     },
   },
@@ -262,8 +297,15 @@ export default  {
     async applyClipPath() {
       if (!this.judge()) return;
 
+
       const { shape, width, height, radius, offsetX, offsetY, rectRadius } = this.clipSettings;
 
+
+      if (shape === '') {
+        // 选择“无”时,直接清除剪裁
+        this.clearClipPath();
+        return;
+      }
       try {
         // 创建纯剪裁区域(不带描边)
         let clipObj;
@@ -331,11 +373,13 @@ export default  {
     updateClipStroke() {
       if (!this.judge() || !this.clipSettings.showClipStroke) return;
 
-      const { shape, width, height, radius, offsetX, offsetY,
-        strokeColor, strokeWidth, rectRadius } = this.clipSettings;
+      const { shape, width, height, radius, offsetX, offsetY, strokeColor, strokeWidth, rectRadius } = this.clipSettings;
 
-      // 移除旧的描边图形
-      this.removeClipStroke();
+      // 移除当前对象已有的描边图形(如果存在)
+      if (this.editLayer.strokeObj) {
+        this.fcanvas.remove(this.editLayer.strokeObj);
+        this.editLayer.strokeObj = null;
+      }
 
       // 创建新的描边图形
       let strokeObj;
@@ -366,9 +410,9 @@ export default  {
         });
       }
 
-      // 添加到画布
+      // 将描边图形绑定到当前对象
+      this.editLayer.strokeObj = strokeObj;
       this.fcanvas.add(markRaw(strokeObj));
-      this.clipStrokeObject = strokeObj;
       this.fcanvas.requestRenderAll();
     },
     removeClipStroke() {
@@ -382,7 +426,16 @@ export default  {
     clearClipPath() {
       if (!this.judge()) return;
 
+      // 清除剪裁路径
       this.editLayer.set({ clipPath: null });
+
+      // 移除描边图形(如果存在)
+      if (this.editLayer.strokeObj) {
+        this.fcanvas.remove(this.editLayer.strokeObj);
+        this.editLayer.strokeObj = null;
+      }
+
+      // 更新画布状态
       this.updateCanvasState();
       this.fcanvas.requestRenderAll();
     }