diff --git a/src/component/Canvas/CanvasEditor/commands/FillRepeatCommand.js b/src/component/Canvas/CanvasEditor/commands/FillRepeatCommand.js index 7104d0ec..d223957e 100644 --- a/src/component/Canvas/CanvasEditor/commands/FillRepeatCommand.js +++ b/src/component/Canvas/CanvasEditor/commands/FillRepeatCommand.js @@ -52,85 +52,112 @@ export class FillRepeatCommand extends Command { console.warn("当前对象不能平铺", object.type); return false; } - console.log("===========", object.toObject(["id", "layerId", "layerName"])) this.oldObjects = object; - const img = await new Promise((resolve, reject) => { - if (object.type === "rect") { - let source = object.fill.source; - resolve(source); - } else if (object.type === "image") { - // resolve(object.getElement()); - // fabric.Image.fromURL( - // object.src, - // v => resolve(v), - // { crossOrigin: "anonymous" } - // ); - const imgElement = object.getElement(); - // 创建透明 Canvas - const tcanvas = document.createElement('canvas'); - tcanvas.width = imgElement.width; - tcanvas.height = imgElement.height; - const ctx = tcanvas.getContext('2d'); - ctx.clearRect(0, 0, tcanvas.width, tcanvas.height); - ctx.drawImage(imgElement, 0, 0); - resolve(tcanvas); - } - }); - const fill_ = { - source: FillSourceToBase64(img), - gapX: 0, - gapY: 0, - width: img.width, - height: img.height, - }; - const bgObject = this.canvasManager.getBackgroundLayerObject(); - const pattern = new fabric.Pattern({ - source: img, - repeat: this.fillRepeat, - patternTransform: object.fill?.hasOwnProperty("patternTransform") ? object.fill.patternTransform : createPatternTransform(scale, 0), - offsetX: object.fill?.hasOwnProperty("offsetX") ? object.fill.offsetX : bgObject.width / 2, // 水平偏移 - offsetY: object.fill?.hasOwnProperty("offsetY") ? object.fill.offsetY : bgObject.height / 2, // 垂直偏移 - }); - const rect = new fabric.Rect({ - id: object.id, - layerId: object.layerId, - layerName: object.layerName, - fill_, - }); - layer.fabricObjects = [rect.toObject(["id", "layerId", "layerName"])]; - this.oldLocked = layer.locked; - // this.oldIsDisableUnlock = layer.isDisableUnlock; - // layer.isDisableUnlock = true; - if (this.oldObjects.type === "rect") { - rect.set({ - width: object.width, - height: object.height, - top: object.top, - left: object.left, - originX: object.originX, - originY: object.originY, - angle: object.angle, - scaleX: object.scaleX, - scaleY: object.scaleY, - flipX: object.flipX, - flipY: object.flipY, + if (this.fillRepeat === "no-repeat") { + const fill_ = object.fill_; + const image = await new Promise((resolve, reject) => { + fabric.Image.fromURL( + fill_.source, + v => resolve(v), + { crossOrigin: "anonymous" } + ); }); + image.set({ + id: object.id, + layerId: object.layerId, + layerName: object.layerName, + ...(fill_.originalInfo || { + top: object.top, + left: object.left, + }) + }); + layer.fabricObjects = [image.toObject(["id", "layerId", "layerName"])]; + this.oldLocked = layer.locked; + layer.locked = false; + + this.canvas.add(image); + this.canvas.remove(object); } else { - let scaleX = bgObject.scaleX || 1; - let scaleY = bgObject.scaleY || 1; - rect.set({ - width: bgObject.width, - height: bgObject.height, - top: bgObject.top - bgObject.height * scaleY / 2, - left: bgObject.left - bgObject.width * scaleX / 2, - scaleX, - scaleY, + const img = await new Promise((resolve, reject) => { + if (object.type === "rect") { + let source = object.fill.source; + resolve(source); + } else if (object.type === "image") { + const imgElement = object.getElement(); + // 创建透明 Canvas + const tcanvas = document.createElement('canvas'); + tcanvas.width = imgElement.width; + tcanvas.height = imgElement.height; + const ctx = tcanvas.getContext('2d'); + ctx.clearRect(0, 0, tcanvas.width, tcanvas.height); + ctx.drawImage(imgElement, 0, 0); + resolve(tcanvas); + } }); - layer.locked = true; + const fill_ = object.fill_ || { + source: FillSourceToBase64(img), + gapX: 0, + gapY: 0, + width: img.width, + height: img.height, + originalInfo: { + top: object.top, + left: object.left, + scaleX: object.scaleX, + scaleY: object.scaleY, + width: object.width, + height: object.height, + } + }; + const bgObject = this.canvasManager.getBackgroundLayerObject(); + const pattern = new fabric.Pattern({ + source: img, + repeat: this.fillRepeat, + patternTransform: object.fill?.hasOwnProperty("patternTransform") ? object.fill.patternTransform : createPatternTransform(scale, 0), + offsetX: object.fill?.hasOwnProperty("offsetX") ? object.fill.offsetX : bgObject.width / 2, // 水平偏移 + offsetY: object.fill?.hasOwnProperty("offsetY") ? object.fill.offsetY : bgObject.height / 2, // 垂直偏移 + }); + const rect = new fabric.Rect({ + id: object.id, + layerId: object.layerId, + layerName: object.layerName, + fill_, + }); + layer.fabricObjects = [rect.toObject(["id", "layerId", "layerName"])]; + this.oldLocked = layer.locked; + // this.oldIsDisableUnlock = layer.isDisableUnlock; + // layer.isDisableUnlock = true; + if (this.oldObjects.type === "rect") { + rect.set({ + width: object.width, + height: object.height, + top: object.top, + left: object.left, + originX: object.originX, + originY: object.originY, + angle: object.angle, + scaleX: object.scaleX, + scaleY: object.scaleY, + flipX: object.flipX, + flipY: object.flipY, + }); + } else { + let scaleX = bgObject.scaleX || 1; + let scaleY = bgObject.scaleY || 1; + rect.set({ + width: bgObject.width, + height: bgObject.height, + top: bgObject.top - bgObject.height * scaleY / 2, + left: bgObject.left - bgObject.width * scaleX / 2, + scaleX, + scaleY, + }); + layer.locked = true; + } + rect.set("fill", pattern); + this.canvas.add(rect); + this.canvas.remove(object); } - rect.set("fill", pattern); - this.canvas.add(rect); - this.canvas.remove(object); await this.layerManager?.updateLayersObjectsInteractivity(); await this.layerManager?.sortLayersWithTool?.(); await this.canvasManager.thumbnailManager?.generateLayerThumbnail( diff --git a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js index 0aca6020..d5e8b9de 100644 --- a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js +++ b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js @@ -1162,68 +1162,6 @@ export class CanvasManager { } getJSON() { - // // 简化图层数据,在loadJSON时要根据id恢复引用 - // const simplifyLayers = (layers) => { - // return layers.map((layer) => { - // if (layer?.children?.length) { - // layer.children = layer.children.map((child) => { - // return { - // id: child.id, - // type: child.type, - // layerId: child.layerId, - // layerName: child.layerName, - // isBackground: child.isBackground, - // isLocked: child.isLocked, - // isVisible: child.isVisible, - // isFixed: child.isFixed, - // parentId: child.parentId, - // fabricObject: child.fabricObject - // ? { - // id: child.fabricObject.id, - // type: child.fabricObject.type, - // layerId: child.fabricObject.layerId, - // layerName: child.fabricObject.layerName, - // } - // : {}, - // fabricObjects: - // child.fabricObjects?.map((obj) => ({ - // id: obj.id, - // type: obj.type, - // layerId: obj.layerId, - // layerName: obj.layerName, - // })) || [], - // }; - // }); - // } - // return { - // id: layer.id, - // type: layer.type, - // layerId: layer.layerId, - // layerName: layer.layerName, - // isBackground: layer.isBackground, - // isLocked: layer.isLocked, - // isVisible: layer.isVisible, - // isFixed: layer.isFixed, - // parentId: layer.parentId, - // fabricObject: child.fabricObject - // ? { - // id: child.fabricObject.id, - // type: child.fabricObject.type, - // layerId: child.fabricObject.layerId, - // layerName: child.fabricObject.layerName, - // } - // : {}, - // fabricObjects: - // child.fabricObjects?.map((obj) => ({ - // id: obj.id, - // type: obj.type, - // layerId: obj.layerId, - // layerName: obj.layerName, - // })) || [], - // children: layer.children, - // }; - // }); - // }; try { // 清除画布中选中状态 // this.canvas.discardActiveObject(); @@ -1669,18 +1607,19 @@ export class CanvasManager { }) children.push(layer); }; - if(children.length === 0){ - let layer = createLayer({ - id: generateId("layer_image_"), - name: t("Canvas.EmptyLayer"), - type: LayerType.BITMAP, - visible: true, - locked: false, - opacity: 1.0, - fabricObjects: [], - }) - children.push(layer); - } + // if(children.length === 0){ + // let layer = createLayer({ + // id: generateId("layer_image_"), + // name: t("Canvas.EmptyLayer"), + // type: LayerType.BITMAP, + // visible: true, + // locked: false, + // opacity: 1.0, + // fabricObjects: [], + // }) + // children.push(layer); + // } + if(children.length === 0) return; const groupRect = new fabric.Rect({}); await this.setObjecCliptInfo(groupRect); // 插入组图层 diff --git a/src/component/Canvas/CanvasEditor/utils/layerHelper.js b/src/component/Canvas/CanvasEditor/utils/layerHelper.js index 534b985e..21e1daba 100644 --- a/src/component/Canvas/CanvasEditor/utils/layerHelper.js +++ b/src/component/Canvas/CanvasEditor/utils/layerHelper.js @@ -191,6 +191,7 @@ export function createLayer(options = {}) { generateId("layer_") || `layer_${Date.now()}_${Math.floor(Math.random() * 1000)}`; return { + ...options, id: id, // 图层基本属性 name: options.name || `图层 ${id.substring(id.lastIndexOf("_") + 1)}`, diff --git a/src/component/Canvas/CanvasEditor/utils/objectHelper.js b/src/component/Canvas/CanvasEditor/utils/objectHelper.js index 8c8fb42e..7042de27 100644 --- a/src/component/Canvas/CanvasEditor/utils/objectHelper.js +++ b/src/component/Canvas/CanvasEditor/utils/objectHelper.js @@ -63,9 +63,10 @@ export async function restoreFabricObject(serializedObject, canvas) { * 获取对象黑白通道画布 * @param {fabric.Object} object - 要处理的 fabric 对象 * @param {ImageData} revData - 相反的ImageData,白通道的相同位置是否为透明,revData为白色为透明,黑色为不透明 + * @param {number} diff - 差值,默认 25 * @returns {HTMLCanvasElement|null} 包含黑白通道的画布,或 null 如果失败 */ -export function getObjectAlphaToCanvas(object, revData) { +export function getObjectAlphaToCanvas(object, revData, diff = 30) { const image = object.getElement(); const { width, height } = image; if (!width || !height) { @@ -88,7 +89,7 @@ export function getObjectAlphaToCanvas(object, revData) { const revB = revData?.data[i + 2] || 0; const revA = revData?.data[i + 3] || 0; if (r || g || b || a) { - if (revR || revG || revB || revA) { + if (revR > diff || revG > diff || revB > diff || revA > diff) { data.data[i + 0] = 0; data.data[i + 1] = 0; data.data[i + 2] = 0;