From 920d01a97255aedc9c22509a9bc4148b9206f21b Mon Sep 17 00:00:00 2001
From: X1627315083 <1627315083@qq.com>
Date: Fri, 23 Jan 2026 21:42:43 +0800
Subject: [PATCH 01/23] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=BB=B4=E6=8A=A4?=
=?UTF-8?q?=E6=97=B6=E9=97=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/router/index.ts | 2 +-
src/views/Upgrade.vue | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/router/index.ts b/src/router/index.ts
index b264f4f2..f08f513e 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -532,7 +532,7 @@ function isTimeRangePassed(timeRange) {
router.beforeEach((to: any, from, next) => {
store.commit("set_view_loading", true);
//系统维护时间
- const time = '2026-01-23T21:00:00 - 2026-01-23T22:00:00';
+ const time = '2026-01-23T21:00:00 - 2026-01-23T23:00:00';
if (isTimeRangePassed(time) == 'in_progress') {
// 系统维护
const toName = to.name === 'upgrade';
diff --git a/src/views/Upgrade.vue b/src/views/Upgrade.vue
index 14527a10..ee1aa460 100644
--- a/src/views/Upgrade.vue
+++ b/src/views/Upgrade.vue
@@ -12,7 +12,7 @@
- Due to system server upgrades, maintenance will be carried out from 21:00 to 22:00 on January 19, 2026 (today).
+ Due to system server upgrades, maintenance will be carried out from 21:00 to 23:00 on January 19, 2026 (today).
The AiDA system will be temporarily unavailable during this period. We sincerely apologize for any inconvenience caused and thank you for your understanding.
@@ -20,7 +20,7 @@
- 由于系统服务器升级,我们将于1月23日21:00 至1月23日22:00进行升级。
+ 由于系统服务器升级,我们将于1月23日21:00 至1月23日23:00进行升级。
在此期间,AiDA系统将暂时无法访问。给您带来的不便,我们深表歉意,并感谢您的理解
From 07b7a6f1d71aecbeba363131f118b35aa54b5ad3 Mon Sep 17 00:00:00 2001
From: X1627315083 <1627315083@qq.com>
Date: Fri, 23 Jan 2026 22:31:51 +0800
Subject: [PATCH 02/23] FIX
---
src/router/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/router/index.ts b/src/router/index.ts
index f08f513e..b264f4f2 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -532,7 +532,7 @@ function isTimeRangePassed(timeRange) {
router.beforeEach((to: any, from, next) => {
store.commit("set_view_loading", true);
//系统维护时间
- const time = '2026-01-23T21:00:00 - 2026-01-23T23:00:00';
+ const time = '2026-01-23T21:00:00 - 2026-01-23T22:00:00';
if (isTimeRangePassed(time) == 'in_progress') {
// 系统维护
const toName = to.name === 'upgrade';
From b158341d6e787676f28c421d886b3c51678dac90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E9=B9=8F?= <2916022834@qq.com>
Date: Mon, 26 Jan 2026 16:47:03 +0800
Subject: [PATCH 03/23] =?UTF-8?q?=E5=8D=B0=E8=8A=B1=E7=BB=84=E7=A6=81?=
=?UTF-8?q?=E6=AD=A2=E5=A4=9A=E9=80=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../CanvasEditor/components/LayersPanel/LayersPanel.vue | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue b/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue
index b6971bb3..1ed62871 100644
--- a/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue
+++ b/src/component/Canvas/CanvasEditor/components/LayersPanel/LayersPanel.vue
@@ -584,15 +584,16 @@ function handleLayerClick(layer, event) {
// 如果不是多选模式,才可激活图层
// 1.如果是组,则设置组下的第一个子图层为活动图层
// 2.否则直接设置活动图层
- if (isGroupLayerType(layer) && layer.children && layer.children.length > 0) {
+ if (isGroupLayerType(layer) && layer.children && layer.children.length > 0 && !layer.isPrintTrimsGroup) {
// 如果是组图层,设置第一个子图层为活动图层
layerManager?.setAllActiveGroupLayerCanvasObject?.(layer);
setActiveLayer(layer.children[0].id, { parentId: layer.id });
} else {
+ let id = layer.isPrintTrimsGroup ? layer.children?.[0]?.id || layer.id : layer.id;
// 选中画布中的图层对象
- layerManager?.selectLayerObjects(layer.id);
+ layerManager?.selectLayerObjects(id);
// 否则直接设置当前图层为活动图层
- setActiveLayer(layer.id);
+ setActiveLayer(id);
layerManager?.updateLayersObjectsInteractivity();
}
}
From fb1d09d98efd80ee9bc54d328692d348ed487e45 Mon Sep 17 00:00:00 2001
From: X1627315083 <1627315083@qq.com>
Date: Tue, 27 Jan 2026 10:12:13 +0800
Subject: [PATCH 04/23] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B3=A8=E5=86=8C?=
=?UTF-8?q?=E8=BE=93=E5=85=A5=E9=AA=8C=E8=AF=81=E7=A0=81=E6=9C=80=E5=B0=8F?=
=?UTF-8?q?=E9=AB=98=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/component/HomePage/bindEmail.vue | 1 +
src/component/LoginPage/login/enterprise.vue | 2 +-
src/component/LoginPage/login/personal.vue | 1 +
src/component/LoginPage/login/school.vue | 2 +-
src/component/mainPage/signUp/registerModel.vue | 2 ++
5 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/component/HomePage/bindEmail.vue b/src/component/HomePage/bindEmail.vue
index d4b18e4d..dfe73a96 100644
--- a/src/component/HomePage/bindEmail.vue
+++ b/src/component/HomePage/bindEmail.vue
@@ -595,6 +595,7 @@ export default defineComponent({
.login_form_content {
margin-top: 4rem;
position: relative;
+ min-height: 34rem;
&[state="2"]{
height: 30rem;
>*{
diff --git a/src/component/LoginPage/login/enterprise.vue b/src/component/LoginPage/login/enterprise.vue
index c2265558..dadf84ce 100644
--- a/src/component/LoginPage/login/enterprise.vue
+++ b/src/component/LoginPage/login/enterprise.vue
@@ -790,7 +790,7 @@ export default defineComponent({
.login_form_content {
margin-top: 4rem;
position: relative;
-
+ min-height: 34rem;
&[state="2"] {
> * {
opacity: 0;
diff --git a/src/component/LoginPage/login/personal.vue b/src/component/LoginPage/login/personal.vue
index a597ba09..2712e61d 100644
--- a/src/component/LoginPage/login/personal.vue
+++ b/src/component/LoginPage/login/personal.vue
@@ -799,6 +799,7 @@ export default defineComponent({
.login_form_content {
position: relative;
+ min-height: 34rem;
&[state="2"] {
> * {
opacity: 0;
diff --git a/src/component/LoginPage/login/school.vue b/src/component/LoginPage/login/school.vue
index 6c49f25c..93e8c38f 100644
--- a/src/component/LoginPage/login/school.vue
+++ b/src/component/LoginPage/login/school.vue
@@ -826,7 +826,7 @@ export default defineComponent({
.login_form_content {
margin-top: 4rem;
position: relative;
-
+ min-height: 34rem;
&[state="2"] {
> * {
opacity: 0;
diff --git a/src/component/mainPage/signUp/registerModel.vue b/src/component/mainPage/signUp/registerModel.vue
index 9b3d52ed..fd499749 100644
--- a/src/component/mainPage/signUp/registerModel.vue
+++ b/src/component/mainPage/signUp/registerModel.vue
@@ -916,9 +916,11 @@ export default defineComponent({
.login_form_content {
margin-top: 4rem;
position: relative;
+ min-height: 34rem;
@media (max-width: 768px) {
margin-top: 2.4rem;
height: 20rem;
+ min-height: auto;
}
&[state="2"] {
> * {
From 03a9e2f52c91f7d89112ceb240001d8326364213 Mon Sep 17 00:00:00 2001
From: X1627315083 <1627315083@qq.com>
Date: Tue, 27 Jan 2026 10:15:20 +0800
Subject: [PATCH 05/23] fix
---
src/component/mainPage/signUp/registerModel.vue | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/component/mainPage/signUp/registerModel.vue b/src/component/mainPage/signUp/registerModel.vue
index fd499749..557afb9e 100644
--- a/src/component/mainPage/signUp/registerModel.vue
+++ b/src/component/mainPage/signUp/registerModel.vue
@@ -919,8 +919,10 @@ export default defineComponent({
min-height: 34rem;
@media (max-width: 768px) {
margin-top: 2.4rem;
- height: 20rem;
min-height: auto;
+ &[state="2"] {
+ height: 20rem;
+ }
}
&[state="2"] {
> * {
From 4dfa9433fd56af9d7decbf99fbd61e6ce3e64ab5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E9=B9=8F?= <2916022834@qq.com>
Date: Tue, 27 Jan 2026 11:01:33 +0800
Subject: [PATCH 06/23] =?UTF-8?q?=E7=94=BB=E5=B8=83=20=E9=83=A8=E4=BB=B6?=
=?UTF-8?q?=E9=80=89=E5=8F=96=E3=80=81=E5=8D=B0=E8=8A=B1=E7=A6=81=E7=94=A8?=
=?UTF-8?q?=E5=A4=9A=E9=80=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../FillGroupLayerBackgroundCommand.js | 5 +-
.../commands/LassoCutoutCommand.js | 12 +-
.../CanvasEditor/commands/PartCommands.js | 56 ++++
.../components/PartSelectorPanel.vue | 76 +----
.../components/SelectMenuPanel/index.vue | 13 +-
src/component/Canvas/CanvasEditor/index.vue | 8 +-
.../CanvasEditor/managers/CanvasManager.js | 6 +-
.../CanvasEditor/managers/PartManager.js | 316 ++++++++++++------
.../CanvasEditor/managers/ToolManager.js | 4 +-
.../Canvas/CanvasEditor/utils/helper.js | 1 +
src/component/Canvas/canvasExample.vue | 11 +-
src/component/Canvas/test.vue | 2 +-
12 files changed, 328 insertions(+), 182 deletions(-)
create mode 100644 src/component/Canvas/CanvasEditor/commands/PartCommands.js
diff --git a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js
index edd061ac..26f90e2c 100644
--- a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js
+++ b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js
@@ -106,7 +106,6 @@ export class FillGroupLayerBackgroundCommand extends Command {
});
}
}
-
// 判断fabricObjects是否是组对象
const firstObj = layer.fabricObjects?.[0] || null;
// 如果没有找到第一个对象,则直接添加到当前画布
@@ -173,8 +172,8 @@ export class FillGroupLayerBackgroundCommand extends Command {
}
const canvasObj = findObjectById(this.canvas, firstObj?.id)?.object;
if (
- (canvasObj && canvasObj.type === "group") ||
- canvasObj._objects?.length > 0
+ canvasObj && (canvasObj.type === "group" ||
+ canvasObj._objects?.length > 0)
) {
this.newFill.set({
left: 0,
diff --git a/src/component/Canvas/CanvasEditor/commands/LassoCutoutCommand.js b/src/component/Canvas/CanvasEditor/commands/LassoCutoutCommand.js
index a3ad1eaf..b69f2cdc 100644
--- a/src/component/Canvas/CanvasEditor/commands/LassoCutoutCommand.js
+++ b/src/component/Canvas/CanvasEditor/commands/LassoCutoutCommand.js
@@ -147,11 +147,11 @@ export class LassoCutoutCommand extends CompositeCommand {
}
// 确定源图层
- const sourceLayer = this.layerManager.getActiveLayer();
- if (!sourceLayer) {
- console.error("无法执行套索抠图:源图层无效");
- return false;
- }
+ // const sourceLayer = this.layerManager.getActiveLayer();
+ // if (!sourceLayer) {
+ // console.error("无法执行套索抠图:源图层无效");
+ // return false;
+ // }
// 获取源图层的所有对象(包括子图层)
// const sourceObjects = this._getLayerObjects(sourceLayer);
@@ -225,7 +225,7 @@ export class LassoCutoutCommand extends CompositeCommand {
const layers = this.layerManager.layers.value;
var topLayerIndex = 0;
- layers.forEach((layer, index) => {
+ if(this.originalLayer)layers.forEach((layer, index) => {
if (layer.id === this.originalLayer.id) {
topLayerIndex = index;
}else if (layer.children.length > 0) {
diff --git a/src/component/Canvas/CanvasEditor/commands/PartCommands.js b/src/component/Canvas/CanvasEditor/commands/PartCommands.js
new file mode 100644
index 00000000..c8e1178c
--- /dev/null
+++ b/src/component/Canvas/CanvasEditor/commands/PartCommands.js
@@ -0,0 +1,56 @@
+import { Command } from "./Command.js";
+
+/**
+ * 部件绘制命令
+ */
+export class PartDrawCommand extends Command {
+ constructor(options) {
+ super({
+ name: "部件绘制命令",
+ saveState: false,
+ });
+
+ this.canvas = options.canvas;
+ this.partManager = options.partManager;
+ this.partCanvas = options.partCanvas;
+ this.oldPartCanvas = this.partManager.partCanvas;
+ }
+ execute() {
+ this.partManager.drawPartCanvas(this.partCanvas);
+ return true;
+ }
+ undo() {
+ this.partManager.drawPartCanvas(this.oldPartCanvas);
+ return true;
+ }
+}
+/**
+ * 部件点选绘制命令
+ */
+export class PartPointDrawCommand extends Command {
+ constructor(options) {
+ super({
+ name: "部件点选绘制命令",
+ saveState: false,
+ });
+
+ this.canvas = options.canvas;
+ this.partManager = options.partManager;
+ this.partCanvas = options.partCanvas;
+ this.pointList = options.pointList;
+ this.oldPartCanvas = this.partManager.partCanvas;
+ this.oldPointList = [...this.partManager.pointList];
+ }
+ async execute() {
+ const list = [...this.pointList];
+ const canvas = this.partCanvas;
+ const res = await this.partManager.pointDrawPartCanvas(list, canvas);
+ return res;
+ }
+ async undo() {
+ const list = [...this.oldPointList];
+ const canvas = this.oldPartCanvas;
+ const res = await this.partManager.pointDrawPartCanvas(list, canvas);
+ return res;
+ }
+}
diff --git a/src/component/Canvas/CanvasEditor/components/PartSelectorPanel.vue b/src/component/Canvas/CanvasEditor/components/PartSelectorPanel.vue
index 658d647f..1bf5d790 100644
--- a/src/component/Canvas/CanvasEditor/components/PartSelectorPanel.vue
+++ b/src/component/Canvas/CanvasEditor/components/PartSelectorPanel.vue
@@ -20,13 +20,13 @@
- Left Click: Add
+ {{ t("Canvas.LeftClickAdd") }}

-
Right Click: Remove
+
{{ t("Canvas.RightClickRemove") }}
@@ -57,15 +57,15 @@
$t("Canvas.creation")
}}
-
+
- 清空当前点位
+ {{ $t("Canvas.TheClearlySelectedContent") }}
@@ -76,23 +76,9 @@
diff --git a/src/component/Canvas/CanvasEditor/components/SelectMenuPanel/index.vue b/src/component/Canvas/CanvasEditor/components/SelectMenuPanel/index.vue
index 6f8a54a4..447bd6b7 100644
--- a/src/component/Canvas/CanvasEditor/components/SelectMenuPanel/index.vue
+++ b/src/component/Canvas/CanvasEditor/components/SelectMenuPanel/index.vue
@@ -315,6 +315,7 @@
layerManager: props.layerManager,
layers: layers,
lastSelectLayerId: lastSelectLayerId,
+ isCommand,
});
if (isCommand) {
props.commandManager.execute(cmd);
@@ -336,6 +337,7 @@
const finalState = computeAngleState(angle, obj, initialState);
transformObject(obj, initialState, finalState, false);
if (!obj.hasOwnProperty("oldState")) obj.oldState = initialState;
+ props.canvasManager.beforeChangeCanvas([obj]);
};
const changeAngle = (angle, obj) => {
var initialState;
@@ -428,6 +430,7 @@
});
obj.set("fill", pattern);
props.canvas.renderAll();
+ props.canvasManager.beforeChangeCanvas([obj]);
};
const changeFillAngle = (angle, obj) => {
const fill = obj.get("fill");
@@ -447,6 +450,7 @@
});
obj.set("fill", pattern);
props.canvas.renderAll();
+ props.canvasManager.beforeChangeCanvas([obj]);
};
const changeFillOffset = (value, obj) => {
const pattern = new fabric.Pattern({
@@ -466,6 +470,7 @@
});
obj.set("fill", pattern);
props.canvas.renderAll();
+ props.canvasManager.beforeChangeCanvas([obj]);
};
const changeFillScale = (scale, obj) => {
const fill = obj.get("fill");
@@ -498,7 +503,8 @@
newGapY: gapY,
record: true,
});
- cmd.execute();
+ cmd.execute(false);
+ props.canvasManager.beforeChangeCanvas([obj]);
};
const changeFillGap = (gapX, gapY, obj) => {
if (obj.oldFill_) {
diff --git a/src/component/Canvas/CanvasEditor/index.vue b/src/component/Canvas/CanvasEditor/index.vue
index a80624c7..d1b21f2c 100644
--- a/src/component/Canvas/CanvasEditor/index.vue
+++ b/src/component/Canvas/CanvasEditor/index.vue
@@ -896,7 +896,7 @@ const changeCanvas = async (command) => {
...command, // 传递完整的命令数据
};
emit("changeCanvas", commandData);
- canvasManager.changeCanvas(commandData);
+ canvasManager.changeCanvas();
if ((command.canUndo || command.canRedo) && props.enabledRedGreenMode) {
setTimeout(async () => {
try {
diff --git a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
index abce88de..d203608b 100644
--- a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
@@ -74,6 +74,7 @@ export class CanvasManager {
this.props = options.props || {};
this.emit = options.emit || (() => {});
this.awaitCanvasRun = null;
+ this.canvasChangeing = false;
// 初始化画布
this.initializeCanvas();
}
@@ -338,6 +339,7 @@ export class CanvasManager {
setupCanvasEvents(activeElementId, layerManager) {
// 创建画布事件管理器
this.eventManager = new CanvasEventManager(this.canvas, {
+ canvasManager: this,
toolManager: this.toolManager,
animationManager: this.animationManager,
thumbnailManager: this.thumbnailManager,
@@ -1220,8 +1222,8 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
let scaleY = scale * 5 * v.fill_.height / flHeight;
let scaleXY = flWidth > flHeight ? scaleX : scaleY;
- let left = fill.offsetX - v.fill_.width * scale / 2;
- let top = fill.offsetY - v.fill_.height * scale / 2;
+ let left = fill.offsetX + v.fill_.width * scale / 2;
+ let top = fill.offsetY + v.fill_.height * scale / 2;
obj.scale = [scaleXY, scaleXY];
obj.angle = angle;
@@ -1670,7 +1672,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
let flipX = false;
let flipY = false;
let blendMode = BlendMode.MULTIPLY;
- if(item.type === "trims") blendMode = BlendMode.NORMAL;// 元素正常
+ // if(item.type === "trims") blendMode = BlendMode.NORMAL;// 元素正常
if(item.object){
opacity = item.object.opacity
flipX = item.object.flipX
@@ -1730,8 +1732,8 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
let scaleX_ = flWidth / image.width * (item.scale?.[0] || 1) / 5;
let scaleY_ = flHeight / image.height * (item.scale?.[1] || 1) / 5;
let scale = flWidth > flHeight ? scaleX_ : scaleY_;
- let offsetX = (item.location?.[0] || 0) + image.width * scale / 2
- let offsetY = (item.location?.[1] || 0) + image.height * scale / 2
+ let offsetX = (item.location?.[0] || 0) - image.width * scale / 2
+ let offsetY = (item.location?.[1] || 0) - image.height * scale / 2
let top = flTop - flHeight * flScaleY / 2
let left = flLeft - flWidth * flScaleX / 2
let scaleX = flScaleX
@@ -1743,7 +1745,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
let fillSource = image
let flipX = false;
let flipY = false;
- let blendMode = BlendMode.MULTIPLY;
+ let blendMode = BlendMode.NORMAL;
let fill_repeat = "repeat"
if(item.object){
top += item.object.top * flScaleY
@@ -1754,7 +1756,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
angle = item.object.angle
flipX = item.object.flipX
flipY = item.object.flipY
- blendMode = item.object.blendMode || BlendMode.MULTIPLY;
+ if(item.object.blendMode) blendMode = item.object.blendMode;
gapX = item.object.gapX
gapY = item.object.gapY
fillSource = imageAddGapToCanvas(image, gapX, gapY);
@@ -1797,10 +1799,10 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
name: name,
type: LayerType.BITMAP,
visible: true,
- locked: true,
+ locked: false,
opacity: opacity,
isPrintTrims: true,
- blendMode: BlendMode.MULTIPLY,
+ blendMode: blendMode,
fabricObjects: [rect.toObject(["id", "layerId", "layerName"])],
metadata: {sourceData: item},
})
@@ -1841,12 +1843,13 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
/**
* 画布事件变更后
*/
- async changeCanvas(){
+ async changeCanvas(fids = [], isBeforeChange = false){
+ if(!isBeforeChange) this.canvasChangeing = false;
const fixedLayerObj = this.getFixedLayerObject();
if(!fixedLayerObj) return console.warn("固定图层对象不存在", fixedLayerObj)
const colorObject = this.getLayerObjectById(SpecialLayerId.COLOR);
if(colorObject){
- const ids = this.layerManager.getBlendModeLayerIds(SpecialLayerId.SPECIAL_GROUP);
+ const ids = this.layerManager.getBlendModeLayerIds(SpecialLayerId.SPECIAL_GROUP).filter(id => !fids.includes(id));
if(ids.length === 0){
ids.unshift(SpecialLayerId.SPECIAL_GROUP);
await this.setObjecCliptInfo(colorObject);
@@ -1866,6 +1869,24 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
this.canvas.renderAll();
}
}
+ /** 画布变更之前 */
+ async beforeChangeCanvas(objects){
+ if(this.canvasChangeing) return;
+ const ids = objects.filter(v => {
+ return v.isPrintTrims && v.globalCompositeOperation && v.globalCompositeOperation !== BlendMode.NORMAL
+ }).map(v => v.layerId);
+ if(ids.length > 0){
+ this.canvasChangeing = true;
+ this.canvas.getObjects().forEach(v => {
+ if(ids.includes(v.layerId)){
+ v.globalCompositeOperation_ = v.globalCompositeOperation;
+ v.globalCompositeOperation = BlendMode.NORMAL;
+ }
+ })
+ this.canvas.renderAll();
+ await this.changeCanvas(ids, true);
+ }
+ }
/**
* 缩放红绿图模式内容以适应当前画布大小
diff --git a/src/component/Canvas/CanvasEditor/managers/events/CanvasEventManager.js b/src/component/Canvas/CanvasEditor/managers/events/CanvasEventManager.js
index 8c318cf5..8aa4593c 100644
--- a/src/component/Canvas/CanvasEditor/managers/events/CanvasEventManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/events/CanvasEventManager.js
@@ -6,6 +6,7 @@ import { OperationType, OperationTypes } from "../../utils/layerHelper";
export class CanvasEventManager {
constructor(canvas, options = {}) {
this.canvas = canvas;
+ this.canvasManager = options.canvasManager;
this.toolManager = options.toolManager || null;
this.animationManager = options.animationManager;
this.thumbnailManager = options.thumbnailManager;
@@ -691,7 +692,9 @@ export class CanvasEventManager {
// 清除临时状态记录
delete activeObj._initialTransformState;
}
- }
+ }else{
+ this.canvasManager.changeCanvas();
+ }
if (this.thumbnailManager && e.target) {
if (e.target.id) {
@@ -975,6 +978,13 @@ export class CanvasEventManager {
// 添加调试日志(可选)
// console.log(`捕获对象 ${obj.id} (${obj.type}) 的初始变换状态`);
}
+ const arrs = [];
+ if (e.target._objects) {
+ e.target._objects.forEach((v) => arrs.push(v));
+ } else {
+ arrs.push(e.target);
+ }
+ this.canvasManager.beforeChangeCanvas(arrs);
}
/**
diff --git a/src/component/Canvas/OverallCanvas/index.vue b/src/component/Canvas/OverallCanvas/index.vue
index 07a39d9b..7c304820 100644
--- a/src/component/Canvas/OverallCanvas/index.vue
+++ b/src/component/Canvas/OverallCanvas/index.vue
@@ -203,9 +203,9 @@
let scaleY = ((cheight / image.height) * item.scale[1]) / 5;
let scale = cwidth > cheight ? scaleX : scaleY;
let offsetX =
- (item.location[0] * cwidth) / props.width + (image.width * scale) / 2;
+ (item.location[0] * cwidth) / props.width - (image.width * scale) / 2;
let offsetY =
- (item.location[1] * cheight) / props.height +
+ (item.location[1] * cheight) / props.height -
(image.height * scale) / 2;
let angle = item.angle;
let gapX = item.object.gapX;
diff --git a/src/component/Canvas/canvasExample.vue b/src/component/Canvas/canvasExample.vue
index 84e86170..c80a8c46 100644
--- a/src/component/Canvas/canvasExample.vue
+++ b/src/component/Canvas/canvasExample.vue
@@ -342,16 +342,16 @@
level2Type: "Pattern",
designType: "Library",
path: "/src/assets/images/canvas/yinhua1.jpg",
- location: [250, 780],
- scale: [1.2, 1.6],
+ location: [800, 600],
+ scale: [1, 1],
angle: 0,
object: {
- top: 600,
- left: 800,
+ top: 300,
+ left: 400,
scaleX: 0.5,
scaleY: 0.5,
opacity: 1,
- angle: 45,
+ angle: 0,
flipX: false,
flipY: false,
blendMode: "multiply",
@@ -411,6 +411,7 @@
:clothingMinIOPath="clothingMinIOPath"
:clothingImageUrl="clothingImageUrl"
:clothingImageUrl2="clothingImageUrlInit"
+ @canvasLoadJsonSuccess="canvasLoadJsonSuccess"
:config="editorConfig"
:clothing-image-opts="{
imageMode: 'contains', // 设置底图包含在画布内
diff --git a/src/component/Detail/model/modelPosition.vue b/src/component/Detail/model/modelPosition.vue
index fed41c82..bc4a1540 100644
--- a/src/component/Detail/model/modelPosition.vue
+++ b/src/component/Detail/model/modelPosition.vue
@@ -189,6 +189,10 @@ export default defineComponent({
left: 0,
top: 0,
}
+ let startSize = {//记录初始缩放比例
+ width: 0,
+ height: 0,
+ }
moveableInstance.value.on('scaleStart', ({ target, direction }) => {
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
if (!frontStyle.mirror){
@@ -196,6 +200,10 @@ export default defineComponent({
let scaleY = frontStyle.style.transform.match(/scaleY\(([-\d.]+)\)/);
frontStyle.mirror = { x: scaleX[1] == '-1' ? true : false, y: scaleY[1] == '-1' ? true : false };
}
+ startSize.width = Number(parseInt(target.style.width))
+ startSize.height = Number(parseInt(target.style.height))
+ startPosition.left = Number(parseInt(target.style.left))
+ startPosition.top = Number(parseInt(target.style.top))
});
moveableInstance.value.on('rotateStart', ({ target, direction }) => {
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
@@ -241,7 +249,9 @@ export default defineComponent({
element.style.transform = transforms.join(' ').trim();
};
- moveableInstance.value.on('scale', ({ target, delta, direction }) => {
+ moveableInstance.value.on('scale', (e) => {
+ var { target, delta, direction, dist} = e
+ // console.log('scaleStart', e);
const frontStyle = detailData.frontBack.front[selectItem.imgDomIndex];
// 确保 mirror 对象存在并正确初始化
@@ -252,10 +262,14 @@ export default defineComponent({
// 清除可能存在的重复镜像变换
updateElementTransform(frontStyle);
- let width = parseFloat(frontStyle.style.width);
- let height = parseFloat(frontStyle.style.height);
- let left = parseFloat(frontStyle.style.left) || 0;
- let top = parseFloat(frontStyle.style.top) || 0;
+ // let width = parseFloat(frontStyle.style.width);
+ // let height = parseFloat(frontStyle.style.height);
+ // let left = parseFloat(frontStyle.style.left) || 0;
+ // let top = parseFloat(frontStyle.style.top) || 0;
+ let width = startSize.width
+ let height = startSize.height
+ let left = startPosition.left;
+ let top = startPosition.top;
let rotation = 0;
const originalRatio = width / height;
@@ -278,35 +292,34 @@ export default defineComponent({
};
// 根据旋转角度调整方向
- if (rotation !== 0) {
- direction = getAdjustedCorner({ x: direction[0], y: direction[1] }, rotation);
- direction = [direction.x, direction.y];
- }
-
+ // if (rotation !== 0) {
+ // direction = getAdjustedCorner({ x: direction[0], y: direction[1] }, rotation);
+ // direction = [direction.x, direction.y];
+ // }
const isDiagonal = Math.abs(direction[0]) === 1 && Math.abs(direction[1]) === 1;
- const processAxis = (axis, val, deltaVal, dir, pos, keepRatio = false, otherAxisResult = null) => {
+ const processAxis = (axis, val, distVal, dir, pos, keepRatio = false, otherAxisResult = null) => {
const mirrorKey = axis === 'width' ? 'x' : 'y';
const isWidth = axis === 'width';
- let newVal = val * deltaVal;
-
+ let newVal = val * distVal;
// 翻转处理 - 只在值真正变为负值时触发镜像
- if (newVal < 0) {
- frontStyle.mirror[mirrorKey] = !frontStyle.mirror[mirrorKey];
- newVal = Math.abs(newVal);
- } else if (newVal === 0) {
- // 防止值变为0
- newVal = 1;
- }
+ // if (newVal < 0) {
+ // frontStyle.mirror[mirrorKey] = !frontStyle.mirror[mirrorKey];
+ // newVal = Math.abs(newVal);
+ // } else if (newVal === 0) {
+ // // 防止值变为0
+ // newVal = 1;
+ // }
+ if(newVal < 10) newVal = 10;
// 位置调整
const shouldMove = (!frontStyle.mirror[mirrorKey] && dir === -1) || (frontStyle.mirror[mirrorKey] && dir === 1);
// 保持宽高比
- if (keepRatio && otherAxisResult) {
- newVal = isWidth ? otherAxisResult.newVal * originalRatio : otherAxisResult.newVal / originalRatio;
- }
+ // if (keepRatio && otherAxisResult) {
+ // newVal = isWidth ? otherAxisResult.newVal * originalRatio : otherAxisResult.newVal / originalRatio;
+ // }
const adjustPos = shouldMove ? pos - (newVal - val) : pos;
@@ -315,24 +328,32 @@ export default defineComponent({
// 处理缩放
if (isDiagonal) {
- const mainAxis = Math.abs(delta[0] - 1) > Math.abs(delta[1] - 1) ? 'width' : 'height';
- const crossAxis = mainAxis === 'width' ? 'height' : 'width';
+ // const mainAxis = Math.abs(dist[0] - 1) > Math.abs(dist[1] - 1) ? 'width' : 'height';
+ // const crossAxis = mainAxis === 'width' ? 'height' : 'width';
- const mainDir = mainAxis === 'width' ? direction[0] : direction[1];
- const crossDir = crossAxis === 'width' ? direction[0] : direction[1];
+ // const mainDir = mainAxis === 'width' ? dist[0] : dist[1];
+ // const crossDir = crossAxis === 'width' ? dist[0] : dist[1];
- const mainDelta = mainAxis === 'width' ? delta[0] : delta[1];
+ // const mainDelta = mainAxis === 'width' ? dist[0] : dist[1];
- const mainResult = processAxis(mainAxis, mainAxis === 'width' ? width : height, mainDelta, mainDir, mainAxis === 'width' ? left : top);
- const crossResult = processAxis(crossAxis, crossAxis === 'width' ? width : height, 1, crossDir, crossAxis === 'width' ? left : top, true, mainResult);
+ // const mainResult = processAxis(mainAxis, mainAxis === 'width' ? width : height, mainDelta, mainDir, mainAxis === 'width' ? left : top);
+ // const crossResult = processAxis(crossAxis, crossAxis === 'width' ? width : height, 1, crossDir, crossAxis === 'width' ? left : top, true, mainResult);
- frontStyle.style.width = mainAxis === 'width' ? mainResult.newVal + 'px' : crossResult.newVal + 'px';
- frontStyle.style.height = mainAxis === 'height' ? mainResult.newVal + 'px' : crossResult.newVal + 'px';
- frontStyle.style.left = mainAxis === 'width' ? mainResult.adjustPos + 'px' : crossResult.adjustPos + 'px';
- frontStyle.style.top = mainAxis === 'height' ? mainResult.adjustPos + 'px' : crossResult.adjustPos + 'px';
+ // frontStyle.style.width = mainAxis === 'width' ? mainResult.newVal + 'px' : crossResult.newVal + 'px';
+ // frontStyle.style.height = mainAxis === 'height' ? mainResult.newVal + 'px' : crossResult.newVal + 'px';
+ // frontStyle.style.left = mainAxis === 'width' ? mainResult.adjustPos + 'px' : crossResult.adjustPos + 'px';
+ // frontStyle.style.top = mainAxis === 'height' ? mainResult.adjustPos + 'px' : crossResult.adjustPos + 'px';
+ const scale = (dist[0] < 0 && dist[1] < 0) ? -Math.sqrt(dist[0] * dist[1]) : Math.sqrt(dist[0] * dist[1]);
+ const widthResult = processAxis('width', width, scale, direction[0], left);
+ const heightResult = processAxis('height', height, scale, direction[1], top);
+ frontStyle.style.width = widthResult.newVal + 'px';
+ frontStyle.style.height = heightResult.newVal + 'px';
+ frontStyle.style.left = widthResult.adjustPos + 'px';
+ frontStyle.style.top = heightResult.adjustPos + 'px';
+
} else {
- const widthResult = processAxis('width', width, delta[0], direction[0], left);
- const heightResult = processAxis('height', height, delta[1], direction[1], top);
+ const widthResult = processAxis('width', width, dist[0], direction[0], left);
+ const heightResult = processAxis('height', height, dist[1], direction[1], top);
frontStyle.style.left = widthResult.adjustPos + 'px';
frontStyle.style.top = heightResult.adjustPos + 'px';
From 62e7f34c982149abf5a320dcf6299b6d32eadaba 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, 30 Jan 2026 13:47:38 +0800
Subject: [PATCH 20/23] =?UTF-8?q?=E7=94=BB=E5=B8=83=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=E6=9B=B4=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Canvas/CanvasEditor/commands/LayerCommands.js | 9 +++++++--
.../Canvas/CanvasEditor/managers/CanvasManager.js | 9 +++++----
.../Canvas/CanvasEditor/managers/LayerManager.js | 13 +++++--------
3 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/src/component/Canvas/CanvasEditor/commands/LayerCommands.js b/src/component/Canvas/CanvasEditor/commands/LayerCommands.js
index 339fe361..88f9afb1 100644
--- a/src/component/Canvas/CanvasEditor/commands/LayerCommands.js
+++ b/src/component/Canvas/CanvasEditor/commands/LayerCommands.js
@@ -280,8 +280,13 @@ export class PasteLayerCommand extends Command {
isCut: undefined,
serializedObjects: undefined,
};
-
- if (this.insertIndex !== undefined && this.insertIndex !== null) {
+ if(this.newLayer.isPrintTrims){
+ this.layers.value.forEach((layer) => {
+ if (layer.isPrintTrimsGroup) {
+ layer.children.push(this.newLayer);
+ }
+ })
+ }else if (this.insertIndex !== undefined && this.insertIndex !== null) {
this.layers.value.splice(this.insertIndex, 0, this.newLayer);
} else {
this.layers.value.push(this.newLayer);
diff --git a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
index d203608b..f9e4e2b7 100644
--- a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
@@ -870,9 +870,9 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
return layerObjectByLayerId;
}
- getObjectsByIds(ids){
+ getObjectsByIdOrLayerId(ids){
const objects = this.canvas.getObjects().filter((obj) => {
- return ids.includes(obj.id);
+ return ids.includes(obj.id) || ids.includes(obj.layerId);
});
return objects;
}
@@ -1149,7 +1149,7 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
const glayer = this.layerManager.getLayerById(SpecialLayerId.SPECIAL_GROUP);
if(!glayer) return Promise.reject("印花和元素图层组不存在");
const ids = glayer.children.map((v) => v.id);
- const objects = this.getObjectsByIds(ids);
+ const objects = this.getObjectsByIdOrLayerId(ids);
const fixedLayerObj = this.getFixedLayerObject();
if(!fixedLayerObj) return Promise.reject("固定图层不存在");
const flWidth = fixedLayerObj.width
@@ -1161,7 +1161,8 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
const prints = [];
const trims = [];
objects.forEach((v) => {
- const sourceData = glayer.children.find((v_) => v_.id === v.id)?.metadata?.sourceData;
+ const label = glayer.children.find((v_) => (v_.id === v.layerId || v_.id === v.id));
+ const sourceData = label?.metadata?.sourceData;
if(!sourceData) return;
const obj = {
ifSingle: typeof v.fill === "string",
diff --git a/src/component/Canvas/CanvasEditor/managers/LayerManager.js b/src/component/Canvas/CanvasEditor/managers/LayerManager.js
index 4b23403f..b0935346 100644
--- a/src/component/Canvas/CanvasEditor/managers/LayerManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/LayerManager.js
@@ -1750,7 +1750,7 @@ export class LayerManager {
layer.serializedObjects = layer.fabricObjects
.map((obj) => {
if (typeof obj.toObject === "function") {
- return obj.toObject(["id", "layerId", "layerName"]);
+ return obj.toObject(["id", "layerId", "layerName", "fill_"]);
}
return null;
})
@@ -1763,7 +1763,7 @@ export class LayerManager {
if (layer.fabricObject) {
layer.serializedBackgroundObject =
typeof layer.fabricObject.toObject === "function"
- ? layer.fabricObject.toObject(["id", "layerId", "layerName"])
+ ? layer.fabricObject.toObject(["id", "layerId", "layerName", "fill_"])
: null;
delete layer.fabricObject;
@@ -1793,7 +1793,7 @@ export class LayerManager {
return layer.fabricObjects
.map((obj) => {
const { object } = findObjectById(this.canvas, obj.id);
- if (object) return object.toObject(["id", "layerId", "layerName"]);
+ if (object) return object.toObject(["id", "layerId", "layerName", "fill_"]);
return false;
})
.filter(Boolean);
@@ -1839,6 +1839,7 @@ export class LayerManager {
// 存储到剪贴板
this.clipboardData = layerCopy;
+ console.log("复制图层:", layerCopy);
const input = document.createElement("input");
input.value = "aida_copy_canvas_layer: " + layer.name;
document.body.appendChild(input);
@@ -1884,7 +1885,7 @@ export class LayerManager {
layerCopy.serializedObjects = layer.fabricObjects
.map((obj) =>
typeof obj.toObject === "function"
- ? obj.toObject(["id", "layerId", "layerName"])
+ ? obj.toObject(["id", "layerId", "layerName", "fill_"])
: null
)
.filter(Boolean);
@@ -1935,10 +1936,6 @@ export class LayerManager {
return this.clipboardData;
}
- /**
- * 粘贴图层
- * @returns {string} 新创建的图层ID
- */
/**
* 粘贴图层
* @returns {string} 新创建的图层ID
From 8588c74ffd5ff239df436ad92199ac0812fb5da6 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, 30 Jan 2026 13:54:21 +0800
Subject: [PATCH 21/23] =?UTF-8?q?=E5=9B=BE=E5=B1=82=E5=8F=AF=E4=BB=A5?=
=?UTF-8?q?=E6=8C=81=E7=BB=AD=E7=B2=98=E8=B4=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../CanvasEditor/managers/LayerManager.js | 4 +-
src/component/Canvas/canvasExample.vue | 62 +++++++++----------
2 files changed, 33 insertions(+), 33 deletions(-)
diff --git a/src/component/Canvas/CanvasEditor/managers/LayerManager.js b/src/component/Canvas/CanvasEditor/managers/LayerManager.js
index b0935346..6fc3078c 100644
--- a/src/component/Canvas/CanvasEditor/managers/LayerManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/LayerManager.js
@@ -1961,13 +1961,13 @@ export class LayerManager {
if (this.commandManager) {
// 使用命令管理器执行命令
const result = await this.commandManager.execute(command);
- this.clipboardData = null; // 清空剪贴板数据 复制一次
+ // this.clipboardData = null; // 清空剪贴板数据 复制一次
// 执行命令
return result;
}
const result = await command.execute();
- this.clipboardData = null; // 清空剪贴板数据 复制一次就清空,避免重复粘贴 出现 错误后也清空 总之就是清空 不用给自己找麻烦
+ // this.clipboardData = null; // 清空剪贴板数据 复制一次就清空,避免重复粘贴 出现 错误后也清空 总之就是清空 不用给自己找麻烦
// 执行命令
return result;
}
diff --git a/src/component/Canvas/canvasExample.vue b/src/component/Canvas/canvasExample.vue
index c80a8c46..19efe42a 100644
--- a/src/component/Canvas/canvasExample.vue
+++ b/src/component/Canvas/canvasExample.vue
@@ -337,28 +337,28 @@
color: { rgba: { r: 255, g: 0, b: 0, a: 1 } },
printObject: {
prints: [
- {
- ifSingle: false,
- level2Type: "Pattern",
- designType: "Library",
- path: "/src/assets/images/canvas/yinhua1.jpg",
- location: [800, 600],
- scale: [1, 1],
- angle: 0,
- object: {
- top: 300,
- left: 400,
- scaleX: 0.5,
- scaleY: 0.5,
- opacity: 1,
- angle: 0,
- flipX: false,
- flipY: false,
- blendMode: "multiply",
- gapX: 0,
- gapY: 0,
- },
- },
+ // {
+ // ifSingle: false,
+ // level2Type: "Pattern",
+ // designType: "Library",
+ // path: "/src/assets/images/canvas/yinhua1.jpg",
+ // location: [800, 600],
+ // scale: [1, 1],
+ // angle: 0,
+ // object: {
+ // top: 300,
+ // left: 400,
+ // scaleX: 0.5,
+ // scaleY: 0.5,
+ // opacity: 1,
+ // angle: 0,
+ // flipX: false,
+ // flipY: false,
+ // blendMode: "multiply",
+ // gapX: 0,
+ // gapY: 0,
+ // },
+ // },
// {
// ifSingle: true,
// level2Type: "Pattern",
@@ -368,15 +368,15 @@
// scale: [0.15, 0.2],
// angle: 0,
// },
- // {
- // ifSingle: true,
- // level2Type: "Pattern",
- // designType: "Library",
- // path: "/src/assets/images/canvas/yinhua1.jpg",
- // location: [700, 400],
- // scale: [0.1, 0.133],
- // angle: 0,
- // },
+ {
+ ifSingle: true,
+ level2Type: "Pattern",
+ designType: "Library",
+ path: "/src/assets/images/canvas/yinhua1.jpg",
+ location: [700, 400],
+ scale: [0.1, 0.133],
+ angle: 0,
+ },
],
},
});
From 0e0eed25665555c3fb8cfd53f9cf0873ae9ae8dc 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, 30 Jan 2026 14:12:17 +0800
Subject: [PATCH 22/23] fix
---
src/component/Canvas/CanvasEditor/managers/CanvasManager.js | 3 +++
src/component/Canvas/CanvasEditor/managers/PartManager.js | 4 ++--
src/component/Canvas/CanvasEditor/utils/layerHelper.js | 1 +
3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
index f9e4e2b7..9b0e0d9d 100644
--- a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
@@ -1486,6 +1486,9 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
if (a.isBackground) return -1;
if (b.isBackground) return 1;
})
+ // 排除的对象id
+ const excludedObjects = [SpecialLayerId.PART_SELECTOR];
+ json.canvas.objects = objects.filter((v) => !excludedObjects.includes(v.id));
}
diff --git a/src/component/Canvas/CanvasEditor/managers/PartManager.js b/src/component/Canvas/CanvasEditor/managers/PartManager.js
index 3f68adcc..8e4208b7 100644
--- a/src/component/Canvas/CanvasEditor/managers/PartManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/PartManager.js
@@ -1,6 +1,6 @@
import { fabric } from "fabric-with-all";
import { traceImageContour, imageToCanvas } from "../utils/helper";
-import { OperationType } from "../utils/layerHelper";
+import { OperationType, SpecialLayerId } from "../utils/layerHelper";
import { LassoCutoutCommand } from "../commands/LassoCutoutCommand";
import addIcon from "@/assets/images/canvas/add.png";
import removeIcon from "@/assets/images/canvas/remove.png";
@@ -72,7 +72,7 @@ export class PartManager {
this.activeTool = this.toolManager.activeTool;
this.rgba = { r: 0, g: 255, b: 0, a: 200 };
- this.partId = "part_selector";
+ this.partId = SpecialLayerId.PART_SELECTOR;
this.partGroup = null; // 当前选区对象
this.partCanvas = null;// 选区画布
this.rectangleObject = null; // 矩形对象
diff --git a/src/component/Canvas/CanvasEditor/utils/layerHelper.js b/src/component/Canvas/CanvasEditor/utils/layerHelper.js
index 7a164fe0..33187625 100644
--- a/src/component/Canvas/CanvasEditor/utils/layerHelper.js
+++ b/src/component/Canvas/CanvasEditor/utils/layerHelper.js
@@ -24,6 +24,7 @@ export const LayerType = {
export const SpecialLayerId = {
SPECIAL_GROUP: "group_special", // 特殊组
COLOR: "special_color", // 颜色图层
+ PART_SELECTOR: "part_selector", // 部件选择器图层
}
From 811e179889a698d779d622beafb4692a05547b43 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, 30 Jan 2026 14:52:10 +0800
Subject: [PATCH 23/23] fix
---
.../Canvas/CanvasEditor/managers/CanvasManager.js | 13 ++++++++++++-
.../Canvas/CanvasEditor/managers/LayerManager.js | 4 ++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
index 9b0e0d9d..75c547dd 100644
--- a/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/CanvasManager.js
@@ -1468,9 +1468,12 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
}
/** 修复JSON数据中的ID丢失问题 */
FixJsonIdLoss(json){
+ const layerIds = [];
const layers = json?.layers || [];
const objects = json?.canvas?.objects || [];
layers.forEach((layer) => {
+ layerIds.push(layer.id);
+ layer.children?.forEach((child) => layerIds.push(child.id));
if(!layer.fabricObjects?.[0]?.id && !layer.fabricObject?.id){
const obj = objects?.find((o) => o.layerId === layer.id);
if(obj) {
@@ -1488,7 +1491,15 @@ backgroundObject.scaleY,'CanvasManager resetCanvasSizeByFixedLayer')
})
// 排除的对象id
const excludedObjects = [SpecialLayerId.PART_SELECTOR];
- json.canvas.objects = objects.filter((v) => !excludedObjects.includes(v.id));
+ json.canvas.objects = objects.filter((v) => {
+ // 指定ID排除
+ if(excludedObjects.includes(v.id)) return false;
+
+ if(v.isBackground || v.isFixed) return true;
+ // 当前图层不存在当前对象
+ if(!layerIds.includes(v.layerId)) return false;
+ return true
+ });
}
diff --git a/src/component/Canvas/CanvasEditor/managers/LayerManager.js b/src/component/Canvas/CanvasEditor/managers/LayerManager.js
index 6fc3078c..b0935346 100644
--- a/src/component/Canvas/CanvasEditor/managers/LayerManager.js
+++ b/src/component/Canvas/CanvasEditor/managers/LayerManager.js
@@ -1961,13 +1961,13 @@ export class LayerManager {
if (this.commandManager) {
// 使用命令管理器执行命令
const result = await this.commandManager.execute(command);
- // this.clipboardData = null; // 清空剪贴板数据 复制一次
+ this.clipboardData = null; // 清空剪贴板数据 复制一次
// 执行命令
return result;
}
const result = await command.execute();
- // this.clipboardData = null; // 清空剪贴板数据 复制一次就清空,避免重复粘贴 出现 错误后也清空 总之就是清空 不用给自己找麻烦
+ this.clipboardData = null; // 清空剪贴板数据 复制一次就清空,避免重复粘贴 出现 错误后也清空 总之就是清空 不用给自己找麻烦
// 执行命令
return result;
}