diff --git a/src/assets/icons/CThemeColor.svg b/src/assets/icons/CThemeColor.svg index 3bf50549..da1e05d9 100644 --- a/src/assets/icons/CThemeColor.svg +++ b/src/assets/icons/CThemeColor.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js index 4b3eef5c..e4f5622c 100644 --- a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js +++ b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js @@ -24,9 +24,10 @@ export class FillGroupLayerBackgroundCommand extends Command { this.oldFillColor = null; this.newFill = null; - const { layer } = findLayerRecursively(this.layers.value, this.layerId); + const { layer, parent } = findLayerRecursively(this.layers.value, this.layerId); this.layer = layer; + this.parent = parent; this.group = null; @@ -65,7 +66,7 @@ export class FillGroupLayerBackgroundCommand extends Command { scaleY: clippingMaskFabricObject.scaleY || 1, // type: "fill", }); - this.newFill.clipPath = clippingMaskFabricObject; + // this.newFill.clipPath = clippingMaskFabricObject; // this.newFill.dirty = true; // this.newFill.setCoords(); } else { @@ -102,29 +103,56 @@ export class FillGroupLayerBackgroundCommand extends Command { // canvasObj.addWithUpdate(); canvasObj.setCoords(); canvasObj.setObjectsCoords(); - // canvasObj.dirty = true; // 标记为脏对象 + canvasObj.dirty = true; // 标记为脏对象 // this.canvas.renderAll(); // this.group = canvasObj; } else if (layer.fabricObjects && layer.fabricObjects.length > 0) { // 普通对象,组成新组 - const layerObjects = this.canvas.getObjects().filter((obj) => obj.layerId === this.layerId); + const layerObjects = + this.canvas.getObjects().filter((obj) => obj.layerId === this.layerId) || []; + // layerObjects?.forEach((obj) => { + // obj.clipPath = null; + // obj.dirty = true; + // obj.setCoords(); + // }); let insertIndex = this.canvas.getObjects()?.findIndex((obj) => obj.id === firstObj?.id) ?? 0; insertIndex = insertIndex === -1 ? 0 : insertIndex; - + layerObjects.forEach((obj) => { + obj.clipPath = null; + }); this.group = new fabric.Group([this.newFill, ...layerObjects]); this.group.set({ id: layerObjects[0]?.id || generateId("group-"), - layerId: layerObjects[0]?.layerId, + layerId: this.layer?.id, }); - this.group.setCoords(); - removeCanvasObjectByObject(this.canvas, layerObjects[0]); - insertObjectAtZIndex(this.canvas, this.group, insertIndex, false); + // this.group.setCoords(); + // this.group.setObjectsCoords(); + // this.group.dirty = true; // 标记为脏对象 + if (this.parent?.clippingMask) { + const clipPath = await restoreFabricObject(this.parent?.clippingMask, this.canvas); + clipPath.clipPath = null; + clipPath.set({ absolutePositioned: true }); + this.group.clipPath = clipPath; + } + layer.fabricObjects = [this.group.toObject(["id", "layerId"]) || this.group]; + // removeCanvasObjectByObject(this.canvas, layerObjects?.[0]); + insertObjectAtZIndex(this.canvas, this.group, insertIndex, false, true); } + // this.group?.addWithUpdate?.(); // layer.fabricObjects = [this.group?.toObject?.(["id", "layerId"]) || this.group]; - this.canvas.renderAll(); + // this.canvas.renderAll(); layer.fill = null; // this.newFill.toObject(["id", "layerId"]); layer.fillColor = this.fillColor; + // 取消激活对象 + + this.canvas.discardActiveObject(); // 取消当前活动对象 + // 重新排序 + await this.layerManager?.sortLayersWithTool?.(); + // 更新画布上对象的可选择状态 + await this.layerManager?.updateLayersObjectsInteractivity?.(); + this.canvas.renderAll(); + this.canvasManager.thumbnailManager?.generateLayerThumbnail(this.layer.id); return true; } @@ -159,19 +187,25 @@ export class FillGroupLayerBackgroundCommand extends Command { this.group = null; } + this.canvas.discardActiveObject(); // 取消当前活动对象 + // 重新排序 + await this.layerManager?.sortLayersWithTool?.(); + // 更新画布上对象的可选择状态 + await this.layerManager?.updateLayersObjectsInteractivity?.(); + this.canvasManager.thumbnailManager?.generateLayerThumbnail(this.layer.id); return true; } _collectOriginalObjects() { - if (this.layer.children && this.layer.children.length > 0) { + if (this.layer?.children && this.layer?.children.length > 0) { // 如果是组图层,收集所有子图层的fabric对象 return this.layer.children .flatMap((child) => child.fabricObjects || []) .map((obj) => { return findObjectById(this.canvas.value, obj.id)?.object || obj; }); - } else if (this.layer.fabricObjects && this.layer.fabricObjects.length > 0) { + } else if (this.layer?.fabricObjects && this.layer?.fabricObjects?.length > 0) { // 如果是普通图层,直接返回其fabric对象 return this.layer.fabricObjects.map((obj) => { return findObjectById(this.canvas.value, obj.id)?.object || obj; diff --git a/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue b/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue index 4def5915..69a3dcf0 100644 --- a/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue +++ b/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue @@ -653,35 +653,35 @@ function buildContextMenuItems(layer) { action: () => deleteSelectedLayers(), }, // 组合图层 - { - label: "填充图层", - icon: "CThemeColor", - disabled: - layer.isBackground || - layer.isFixed || - !layerManager?.canRasterizeLayer?.(layer.id) || - layer.isGroup || - layer?.children?.length > 0, // 如果是组图层或有子图层则禁用 - action: () => { - // 调用浏览器原生颜色选择器 - fillColorRef.value.click(); - currLayerId.value = layer.id; - // // 监听颜色选择器的变化 - // fillColorRef.value.addEventListener("change", () => { - // const selectedColor = fillColor.value; - // layerManager - // .fillLayerBackground(layer.id, selectedColor) - // .then(() => { - // console.log(`✅ 已填充图层 ${layer.name} 背景颜色: ${selectedColor}`); - // }) - // .catch((error) => { - // console.error(`❌ 填充图层 ${layer.name} 背景颜色失败:`, error); - // }); - // }); - // 隐藏右键菜单 - hideContextMenu(); - }, - }, + // { + // label: "填充图层", + // icon: "CThemeColor", + // disabled: + // layer.isBackground || + // layer.isFixed || + // !layerManager?.canRasterizeLayer?.(layer.id) || + // layer.isGroup || + // layer?.children?.length > 0, // 如果是组图层或有子图层则禁用 + // action: () => { + // // 调用浏览器原生颜色选择器 + // fillColorRef.value.click(); + // currLayerId.value = layer.id; + // // // 监听颜色选择器的变化 + // // fillColorRef.value.addEventListener("change", () => { + // // const selectedColor = fillColor.value; + // // layerManager + // // .fillLayerBackground(layer.id, selectedColor) + // // .then(() => { + // // console.log(`✅ 已填充图层 ${layer.name} 背景颜色: ${selectedColor}`); + // // }) + // // .catch((error) => { + // // console.error(`❌ 填充图层 ${layer.name} 背景颜色失败:`, error); + // // }); + // // }); + // // 隐藏右键菜单 + // hideContextMenu(); + // }, + // }, // 组合图层 { label: "组合图层", @@ -1512,14 +1512,14 @@ async function moveGroupToGroup(draggedLayer, fromParentId, toParentId, newIndex
- + /> -->

{{ $t("图层") }} {{ selectedLayerIds.length > 0 ? `(${selectedLayerIds.length})` : "" }} diff --git a/src/component/Canvas/CanvasEditor/components/ToolsSidebar.vue b/src/component/Canvas/CanvasEditor/components/ToolsSidebar.vue index 74814430..a7a5c631 100644 --- a/src/component/Canvas/CanvasEditor/components/ToolsSidebar.vue +++ b/src/component/Canvas/CanvasEditor/components/ToolsSidebar.vue @@ -1,6 +1,6 @@