浏览代码

feat(editor): 实现图层复制功能并优化图层管理

- 在图层菜单中添加复制选项
- 重构复制逻辑至 PictureEditor 的 layer mixin 中
- 移除旧的复制方法实现
- 优化图层排序以兼容 Vue3 响应式系统
- 修复图层删除后画布未重新渲染的问题
- 更新营销编辑器模板中的图层操作菜单
panqiuyao 6 天之前
父节点
当前提交
928667fb73

+ 0 - 25
frontend/src/views/components/PictureEditor/mixin/edit/index.js

@@ -146,31 +146,6 @@ export default  {
       this.fcanvas.requestRenderAll()
 
     },
-    //复制
-    copy(){
-      if(!this.judge()) return;
-      const self = this;
-      const name = this.editLayer.name
-      const sort = this.editLayer.sort
-      this.editLayer.clone((cloned)=> {
-        cloned.clone((clonedObj)=> {
-          self.fcanvas.discardActiveObject();
-          clonedObj.set({
-            left: clonedObj.left + 10,
-            top: clonedObj.top + 10,
-            sort:sort+1,
-            name:name,
-            id:self.getNextLayersId(),
-            evented: true,
-          });
-          self.fcanvas.add(clonedObj);
-          self.fcanvas.setActiveObject(clonedObj);
-          self.getLayers()
-          self.updateCanvasState()
-          self.fcanvas.requestRenderAll()
-        });
-      });
-    },
     //合并组
     setGroup(){
       const group = this.fcanvas.getActiveObject().toGroup();

+ 32 - 2
frontend/src/views/components/PictureEditor/mixin/layer/index.js

@@ -88,7 +88,10 @@ export default  {
     //获取排序后的图层
     getLayers(updateCanvasState = true){
       let layers = this.fcanvas.getObjects().sort(this.DescSort)
-      this.layers = this.computedLayerSort(layers).sort(this.AscSort)
+      // Vue3 下避免 Proxy 影响 Fabric 对象的引用比较,统一 markRaw
+      this.layers = this.computedLayerSort(layers)
+        .sort(this.AscSort)
+        .map(obj => markRaw(obj))
       if(updateCanvasState) this.updateCanvasState();
       this.$emit('update:isEmpty', this.layers.length === 0)
     },
@@ -146,6 +149,7 @@ export default  {
       }
       this.islayerSelect = true;
       this.fcanvas.remove(item)
+      this.fcanvas.requestRenderAll()
       this.undoAfterSelectLayers();
       this.getLayers()
     },
@@ -304,7 +308,33 @@ export default  {
       this.layersSort = sort;
       return layers;
 
-    }
+    },
+
+    //复制
+    copy(item){
+      const editLayer = item
+      const self = this;
+      const name = editLayer.name
+      const sort = editLayer.sort
+      editLayer.clone((cloned)=> {
+        cloned.clone((clonedObj)=> {
+          self.fcanvas.discardActiveObject();
+          clonedObj.set({
+            left: clonedObj.left + 10,
+            top: clonedObj.top + 10,
+            sort:sort+1,
+            name:name,
+            id:self.getNextLayersId(),
+            evented: true,
+          });
+          self.fcanvas.add(clonedObj);
+          self.fcanvas.setActiveObject(clonedObj);
+          self.getLayers()
+          self.updateCanvasState()
+          self.fcanvas.requestRenderAll()
+        });
+      });
+    },
   }
 
 }

文件差异内容过多而无法显示
+ 0 - 0
frontend/src/views/components/marketingEdit/canvas.json


+ 1 - 0
frontend/src/views/components/marketingEdit/tpl/layer.js

@@ -39,6 +39,7 @@ export default function() {
                   <div class="menu-item" @click.stop="move(item,'bringToFront'); closeLayerMenu()">置顶</div>
                   <div class="menu-item" @click.stop="move(item,'sendToBack'); closeLayerMenu()">置底</div>
                   <div class="menu-item danger" @click.stop="delLayers(item); closeLayerMenu()">删除</div>
+                  <div class="menu-item danger" @click.stop="copy(item); closeLayerMenu()">复制</div>
                 </div>
               </div>
             </div>

部分文件因为文件数量过多而无法显示