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 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
- {{ t("Canvas.Scale") }}: {{ currentZoom }}%
-
-
-
+
+ {{ t("Canvas.Scale") }}: {{ currentZoom }}%
+
+
+
+
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
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;