From 01d09f4c34d79c59bca1fc7e12245f5cabefa5b5 Mon Sep 17 00:00:00 2001 From: "X1627315083@163.com" <1627315083@qq.com> Date: Thu, 5 Feb 2026 17:38:27 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8Doverall=E5=8D=B0=E8=8A=B1?= =?UTF-8?q?=E5=92=8C=E7=94=BB=E5=B8=83=E4=B8=AD=E5=8D=B0=E8=8A=B1scale?= =?UTF-8?q?=E4=B8=8D=E5=90=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Detail/DesignDetail.vue | 1 - src/component/Detail/detailRight/editPrintElement.vue | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/component/Detail/DesignDetail.vue b/src/component/Detail/DesignDetail.vue index b5450632..1778ba2a 100644 --- a/src/component/Detail/DesignDetail.vue +++ b/src/component/Detail/DesignDetail.vue @@ -759,7 +759,6 @@ export default defineComponent({ const uploadSelectDetail = async ()=>{//更新选中的detail // await detailDom.canvasBox.saveCanvas() const allInfo = await (detailDom.canvasBox as any).getCanvasElement() - console.log(allInfo) let color:any = {} if(allInfo.color?.color?.rgba || allInfo.color?.color?.gradient){ let canvasColor = allInfo.color.color; diff --git a/src/component/Detail/detailRight/editPrintElement.vue b/src/component/Detail/detailRight/editPrintElement.vue index 4fcf2db0..ae2b63a8 100644 --- a/src/component/Detail/detailRight/editPrintElement.vue +++ b/src/component/Detail/detailRight/editPrintElement.vue @@ -273,7 +273,7 @@ export default defineComponent({ minIOPath:data.minIOPath || data.originalUrl, path:data.url, priority:printIndex, - scale, + scale:editPrintElementData.stateOverallSingle == 'single'?scale:[1,1], globalCompositeOperation:'', } getItemPosition(item) @@ -361,7 +361,7 @@ export default defineComponent({ //overall left = item.location[0] / editPrintElementData.sketchWH.scale[0] top = item.location[1] / editPrintElementData.sketchWH.scale[1] - item.scale = [1,1] + item.scale = item.scale || [1,1] } let pattern = { centers:{left:0,top:0}, From b50dbbc2468e2a1a9a05cc1280c09f53ae08a972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E9=B9=8F?= <2916022834@qq.com> Date: Fri, 6 Feb 2026 10:36:31 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E9=83=A8=E4=BB=B6?= =?UTF-8?q?=E9=80=89=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Detail/canvas/index.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/component/Detail/canvas/index.vue b/src/component/Detail/canvas/index.vue index ac0c3544..dde6d912 100644 --- a/src/component/Detail/canvas/index.vue +++ b/src/component/Detail/canvas/index.vue @@ -12,7 +12,6 @@ is-edit :clothingImageUrl="selectDetail.path" :clothingImageUrl2="selectDetail.maskUrl || selectDetail.layersObject[0].maskUrl" - :clothingMinIOPath="selectDetail.minIOPath" showFixedLayer :canvasJSON="canvasJSON" @canvasLoadJsonSuccess="canvasLoadJsonSuccess" From 13024cdd9992e6c64b58f18f0829c811a15181ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E9=B9=8F?= <2916022834@qq.com> Date: Fri, 6 Feb 2026 13:07:06 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E7=94=BB=E5=B8=83loading?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/Canvas/CanvasEditor/index.vue | 3330 ++++++++--------- .../CanvasEditor/managers/CanvasManager.js | 6 +- .../CanvasEditor/managers/LayerManager.js | 8 +- .../CanvasEditor/managers/PartManager.js | 24 +- .../Canvas/CanvasEditor/utils/LayerSort.js | 41 +- .../Canvas/CanvasEditor/utils/objectHelper.js | 21 +- src/component/Canvas/canvasExample.vue | 1 + src/component/Detail/canvas/index.vue | 4 +- 8 files changed, 1709 insertions(+), 1726 deletions(-) diff --git a/src/component/Canvas/CanvasEditor/index.vue b/src/component/Canvas/CanvasEditor/index.vue index 53f4455b..882c556f 100644 --- a/src/component/Canvas/CanvasEditor/index.vue +++ b/src/component/Canvas/CanvasEditor/index.vue @@ -1,1739 +1,1717 @@ diff --git a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js index b7583264..84fc497b 100644 --- a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js +++ b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js @@ -9,7 +9,6 @@ import { isGroupLayer, OperationType, OperationTypes, - findLayer, createLayer, LayerType, SpecialLayerId, @@ -20,7 +19,6 @@ import { AnimationManager } from "./animation/AnimationManager"; import { createCanvas } from "../utils/canvasFactory"; import { CanvasEventManager } from "./events/CanvasEventManager"; import CanvasConfig from "../config/canvasConfig"; -import { RedGreenModeManager } from "./RedGreenModeManager"; import { EraserStateManager } from "./EraserStateManager"; import { deepClone, @@ -1337,7 +1335,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer') } } loadJSON(json, calllBack) { - + this.canvas.loading.value = true; // 确保传入的json是字符串格式 if (typeof json === "object") { json = JSON.stringify(json); @@ -1509,7 +1507,6 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer') */ async createOtherLayers(otherData) { if (!otherData) return console.warn("otherData 为空不需要添加"); - this.canvas.loading.value = true; let resolve = ()=>{}; this.awaitCanvasRun = ()=>(new Promise((v) => resolve = v)) const otherData_ = JSON.parse(JSON.stringify(otherData)); @@ -1557,7 +1554,6 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer') console.log("==========创建其他图层成功"); resolve(); this.awaitCanvasRun = null; - this.canvas.loading.value = false; } // 设置画布对象的裁剪信息 diff --git a/src/component/Canvas/CanvasEditor/managers/LayerManager.js b/src/component/Canvas/CanvasEditor/managers/LayerManager.js index b0935346..ab64fa9f 100644 --- a/src/component/Canvas/CanvasEditor/managers/LayerManager.js +++ b/src/component/Canvas/CanvasEditor/managers/LayerManager.js @@ -1580,7 +1580,7 @@ export class LayerManager { /** * 排序图层,确保图层顺序: 普通图层 > 固定图层 > 背景图层 */ - sortLayers() { + async sortLayers() { // 对图层进行排序:背景图层在最底层(数组最后),固定图层在中间 this.layers.value.sort((a, b) => { // 如果a是背景图层,它应该排在后面(最底层) @@ -1604,17 +1604,17 @@ export class LayerManager { }); // 更新画布对象顺序 - this._rearrangeObjects(); + await this._rearrangeObjects(); } /** * 重新排列画布上的对象以匹配图层顺序 * @private */ - _rearrangeObjects() { + async _rearrangeObjects() { if (this.layerSort) { // 使用LayerSort的高级排序 - this.layerSort.rearrangeObjects(); + await this.layerSort.rearrangeObjects(); return; } diff --git a/src/component/Canvas/CanvasEditor/managers/PartManager.js b/src/component/Canvas/CanvasEditor/managers/PartManager.js index 8e4208b7..2cf19608 100644 --- a/src/component/Canvas/CanvasEditor/managers/PartManager.js +++ b/src/component/Canvas/CanvasEditor/managers/PartManager.js @@ -90,16 +90,17 @@ export class PartManager { if (toolId === OperationType.PART_ERASER) { this.setEraserTool(); - } else if (toolId === OperationType.PART || toolId === OperationType.PART_RECTANGLE) { - this.clearPointData(); - this.resetPartObject(); - } - if (toolId === OperationType.PART_ERASER || toolId === OperationType.PART_BRUSH) { - if (this.pointList.length > 0) { - this.clearPointData(); - this.resetPartObject(); - } - } + } + // else if (toolId === OperationType.PART || toolId === OperationType.PART_RECTANGLE) { + // this.clearPointData(); + // this.resetPartObject(); + // } + // if (toolId === OperationType.PART_ERASER || toolId === OperationType.PART_BRUSH) { + // if (this.pointList.length > 0) { + // this.clearPointData(); + // this.resetPartObject(); + // } + // } // 如果从非选区工具切换到选区工具,初始化事件 if (!wasActive && this.isActive) { @@ -380,7 +381,8 @@ export class PartManager { box: [...this.pointList], }); const image = await this.loadImageToObject(url); - const canvas = getObjectAlphaToCanvas(image, null, 0, this.rgba); + const data = this.partCanvas?.getContext("2d")?.getImageData(0, 0, this.partCanvas.width, this.partCanvas.height); + const canvas = getObjectAlphaToCanvas(image, data, 0, this.rgba, !!data); this.partDrawCommand(canvas); } /** 获取分隔后图片 */ diff --git a/src/component/Canvas/CanvasEditor/utils/LayerSort.js b/src/component/Canvas/CanvasEditor/utils/LayerSort.js index d7c16369..ad12bafe 100644 --- a/src/component/Canvas/CanvasEditor/utils/LayerSort.js +++ b/src/component/Canvas/CanvasEditor/utils/LayerSort.js @@ -30,27 +30,30 @@ export class LayerSort { if (canvasObjects.length === 0) return; // 使用画布渲染优化 - await optimizeCanvasRendering(this.canvas, () => { - // 计算每个对象应该在的 z-index 位置 - const objectZIndexMap = this.calculateObjectZIndexes(); + await new Promise((resolve) => { + optimizeCanvasRendering(this.canvas, () => { + // 计算每个对象应该在的 z-index 位置 + const objectZIndexMap = this.calculateObjectZIndexes(); - // 按照新的 z-index 排序对象 - const sortedObjects = canvasObjects - .map((obj) => ({ - object: obj, - targetZIndex: objectZIndexMap.get(obj.id) ?? -1, - })) - .filter((item) => item.targetZIndex >= 0) // 过滤掉无效对象 - .sort((a, b) => a.targetZIndex - b.targetZIndex); + // 按照新的 z-index 排序对象 + const sortedObjects = canvasObjects + .map((obj) => ({ + object: obj, + targetZIndex: objectZIndexMap.get(obj.id) ?? -1, + })) + .filter((item) => item.targetZIndex >= 0) // 过滤掉无效对象 + .sort((a, b) => a.targetZIndex - b.targetZIndex); - // 使用 fabric.js 的 moveTo 方法重新排序 - sortedObjects.forEach((item, index) => { - const currentIndex = this.canvas.getObjects().indexOf(item.object); - if (currentIndex !== index && currentIndex !== -1) { - // 将对象移动到正确的位置 - this.canvas.moveTo(item.object, index); - } - }); + // 使用 fabric.js 的 moveTo 方法重新排序 + sortedObjects.forEach((item, index) => { + const currentIndex = this.canvas.getObjects().indexOf(item.object); + if (currentIndex !== index && currentIndex !== -1) { + // 将对象移动到正确的位置 + this.canvas.moveTo(item.object, index); + } + }); + resolve(); + }); }); } diff --git a/src/component/Canvas/CanvasEditor/utils/objectHelper.js b/src/component/Canvas/CanvasEditor/utils/objectHelper.js index d52d02fc..7caa973d 100644 --- a/src/component/Canvas/CanvasEditor/utils/objectHelper.js +++ b/src/component/Canvas/CanvasEditor/utils/objectHelper.js @@ -65,9 +65,10 @@ export async function restoreFabricObject(serializedObject, canvas) { * @param {ImageData} revData - 相反的ImageData,白通道的相同位置是否为透明,revData为白色为透明,黑色为不透明 * @param {number} diff - 差值,默认 25 * @param {Object} rgba - 自定义 rgba 值,默认 { r: 255, g: 255, b: 255, a: 255 } + * @param {boolean} isMerge - 是否合并,true=合并revData,false=反转revData * @returns {HTMLCanvasElement|null} 包含黑白通道的画布,或 null 如果失败 */ -export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 255, g: 255, b: 255, a: 255 }) { +export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 255, g: 255, b: 255, a: 255 }, isMerge = false) { const image = object.getElement(); if (image.nodeName !== "IMG" && image.nodeName !== "CANVAS") { console.warn("对象不是图片"); @@ -93,18 +94,20 @@ export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 2 const revG = revData?.data[i + 1] || 0; const revB = revData?.data[i + 2] || 0; const revA = revData?.data[i + 3] || 0; + let isHave = false; if (r || g || b || a) { if (revR > diff || revG > diff || revB > diff || revA > diff) { - data.data[i + 0] = 0; - data.data[i + 1] = 0; - data.data[i + 2] = 0; - data.data[i + 3] = 0; + isHave = false; } else { - data.data[i + 0] = rgba.r; - data.data[i + 1] = rgba.g; - data.data[i + 2] = rgba.b; - data.data[i + 3] = rgba.a; + isHave = true; } + } + if (isMerge && (revR || revG || revB || revA)) isHave = true; + if (isHave) { + data.data[i + 0] = rgba.r; + data.data[i + 1] = rgba.g; + data.data[i + 2] = rgba.b; + data.data[i + 3] = rgba.a; } else { data.data[i + 0] = 0; data.data[i + 1] = 0; diff --git a/src/component/Canvas/canvasExample.vue b/src/component/Canvas/canvasExample.vue index 7a961666..513e2778 100644 --- a/src/component/Canvas/canvasExample.vue +++ b/src/component/Canvas/canvasExample.vue @@ -333,6 +333,7 @@ ]); const canvasLoadJsonSuccess = () => { console.log("画布加载JSON成功"); + return; canvasEditor.value?.updateOtherLayers({ color: { rgba: { r: 255, g: 0, b: 0, a: 1 } }, printObject: { diff --git a/src/component/Detail/canvas/index.vue b/src/component/Detail/canvas/index.vue index dde6d912..6023a4e6 100644 --- a/src/component/Detail/canvas/index.vue +++ b/src/component/Detail/canvas/index.vue @@ -51,9 +51,9 @@ -
+
From 1428f191dda118ce529404b0592281e27be0847b Mon Sep 17 00:00:00 2001 From: "X1627315083@163.com" <1627315083@qq.com> Date: Fri, 6 Feb 2026 14:17:46 +0800 Subject: [PATCH 4/4] fix --- .../Detail/detailRight/overallSetting/RepeatSetting.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue b/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue index 05a30feb..b7c6d5ab 100644 --- a/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue +++ b/src/component/Detail/detailRight/overallSetting/RepeatSetting.vue @@ -25,7 +25,7 @@
Gap X Gap Y { // let scaleValue = props.object?.scale/10; // return props.object?.scale/10; - return props.object?.scale[0] * 100; + return (props.object?.scale[0] * 100).toFixed(0); }); const scalePrint = computed(() => { let index = sketchWH.value[0] > sketchWH.value[1]?0:1;