From 4030f54334be92eec7cc19347092f631cf352517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BF=97=E9=B9=8F?= <2916022834@qq.com> Date: Wed, 5 Nov 2025 16:28:37 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=BB=E5=B8=83=E9=97=AE=E9=A2=98id=E4=B8=A2?= =?UTF-8?q?=E5=A4=B1=E3=80=81=E6=92=A4=E5=9B=9E...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FillGroupLayerBackgroundCommand.js | 58 ++++++++++++------- .../CanvasEditor/commands/LayerCommands.js | 30 ++++++---- .../commands/RasterizeLayerCommand.js | 4 +- .../CanvasEditor/commands/TextCommands.js | 8 ++- .../components/BrushControlPanel.vue | 6 +- .../CanvasEditor/components/BrushPanel.vue | 2 +- .../components/KeyboardShortcutHelp.vue | 2 +- .../components/LayersPanel/contextMenu.less | 4 +- .../components/LayersPanel/layersPanel.css | 6 +- .../components/LayersPanel/layersPanel.less | 6 +- .../components/css/layersPanel.css | 6 +- src/component/Canvas/CanvasEditor/index.vue | 50 ++++++++++------ .../CanvasEditor/managers/LayerManager.js | 3 +- .../managers/animation/AnimationManager.js | 6 +- .../managers/events/KeyboardManager.js | 19 ++++++ .../Canvas/ExistsImageList/ToolButton.vue | 1 + src/component/Canvas/canvasExample.vue | 45 +++++++++++++- 17 files changed, 182 insertions(+), 74 deletions(-) diff --git a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js index cf5c8f89..b38a3954 100644 --- a/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js +++ b/src/component/Canvas/CanvasEditor/commands/FillGroupLayerBackgroundCommand.js @@ -42,13 +42,25 @@ export class FillGroupLayerBackgroundCommand extends Command { this.firstObj = null; // 用于存储组图层的原始对象 } - async execute() { - const layer = this.layer; + async execute(isUndo = false) { + const { layer, parent } = findLayerRecursively( + this.layers.value, + this.layerId + ); + this.layer = layer; + this.parent = parent; + console.log("==========",layer); if (!layer) return false; - this.oldFill = layer.fill ?? null; - this.oldFillColor = layer.oldFillColor ?? null; - + if(!isUndo){ + this.oldFill = layer.fill ?? null; + this.oldFillColor = layer.fillColor ?? null; + if(this.oldFill){ + // 移除旧的填充对象 + removeCanvasObjectByObject(this.canvas, this.oldFill); + } + } + const fillColor = isUndo ? this.oldFillColor : this.fillColor; // 构建填充对象 let clippingMaskFabricObject = null; if (layer.clippingMask) { @@ -63,7 +75,7 @@ export class FillGroupLayerBackgroundCommand extends Command { height: clippingMaskFabricObject.height, left: clippingMaskFabricObject.left || 0, top: clippingMaskFabricObject.top || 0, - fill: this.fillColor, + fill: fillColor, layerId: this.layerId, id: this.oldFill?.id || generateId("fill-"), selectable: false, @@ -84,7 +96,7 @@ export class FillGroupLayerBackgroundCommand extends Command { height: originalInfo.height, left: originalInfo.left + originalInfo.width / 2 || 0, top: originalInfo.top + originalInfo.height / 2 || 0, - fill: this.fillColor, + fill: fillColor, layerId: this.layerId, id: this.oldFill?.id || generateId("fill-"), selectable: false, @@ -111,7 +123,7 @@ export class FillGroupLayerBackgroundCommand extends Command { height: clippingMaskFabricObject.height, left: clippingMaskFabricObject.left || 0, top: clippingMaskFabricObject.top || 0, - fill: this.fillColor, + fill: fillColor, layerId: this.layerId, id: this.oldFill?.id || generateId("fill-"), selectable: false, @@ -127,7 +139,7 @@ export class FillGroupLayerBackgroundCommand extends Command { height: this.canvasManager?.canvasHeight?.value || this.canvas.height, left: this.canvas.width / 2 || 0, top: this.canvas.height / 2 || 0, - fill: this.fillColor, + fill: fillColor, layerId: this.layerId, id: this.oldFill?.id || generateId("fill-"), selectable: false, @@ -143,8 +155,8 @@ export class FillGroupLayerBackgroundCommand extends Command { layer.fabricObjects = [ this.newFill.toObject(["id", "layerId"]) || this.newFill, ]; - layer.fill = null; // this.newFill.toObject(["id", "layerId"]); - layer.fillColor = this.fillColor; + layer.fill = this.newFill; // this.newFill.toObject(["id", "layerId"]); + layer.fillColor = fillColor; // 取消激活对象 this.canvas.discardActiveObject(); // 取消当前活动对象 @@ -222,8 +234,8 @@ export class FillGroupLayerBackgroundCommand extends Command { // this.group?.addWithUpdate?.(); // layer.fabricObjects = [this.group?.toObject?.(["id", "layerId"]) || this.group]; // this.canvas.renderAll(); - layer.fill = null; // this.newFill.toObject(["id", "layerId"]); - layer.fillColor = this.fillColor; + layer.fill = this.newFill; // this.newFill.toObject(["id", "layerId"]); + layer.fillColor = fillColor; // 取消激活对象 this.canvas.discardActiveObject(); // 取消当前活动对象 @@ -237,14 +249,11 @@ export class FillGroupLayerBackgroundCommand extends Command { return true; } async undo() { - this.layer.fillColor = this.oldFillColor; - this.layer.fill = this.oldFill; - - if (!this.originalInfo && this.firstObj) { + if (!this.originalInfo && this.layer.fill) { this.canvas.discardActiveObject(); - this.canvas.remove(this.firstObj); + this.canvas.remove(this.layer.fill); this.canvas.renderAll(); - this.canvasManager.thumbnailManager?.generateLayerThumbnail( + this.parent && this.canvasManager.thumbnailManager?.generateLayerThumbnail( this.parent.id ); this.canvasManager.thumbnailManager?.generateLayerThumbnail( @@ -264,7 +273,8 @@ export class FillGroupLayerBackgroundCommand extends Command { canvasObj?._objects?.length > 0 ) { // 移除新添加的填充对象 - if (canvasObj._objects?.[0] === this.newFill) { + // if (canvasObj._objects?.[0] === this.newFill) { + if (/^fill-/.test(canvasObj._objects?.[0]?.id)) { canvasObj._objects.shift(); canvasObj.addWithUpdate(); canvasObj.setCoords(); @@ -284,6 +294,14 @@ export class FillGroupLayerBackgroundCommand extends Command { this.canvas.renderAll(); this.group = null; } + if(this.oldFill){ + this.layer.fill = this.oldFill; + this.layer.fillColor = this.oldFillColor; + return this.execute(true); + }else{ + this.layer.fill = null; + this.layer.fillColor = null; + } this.canvas.discardActiveObject(); // 取消当前活动对象 // 重新排序 diff --git a/src/component/Canvas/CanvasEditor/commands/LayerCommands.js b/src/component/Canvas/CanvasEditor/commands/LayerCommands.js index 1dffba96..2b258631 100644 --- a/src/component/Canvas/CanvasEditor/commands/LayerCommands.js +++ b/src/component/Canvas/CanvasEditor/commands/LayerCommands.js @@ -70,7 +70,7 @@ export class AddLayerCommand extends Command { undo() { // 从图层列表删除该图层 - this.layers.value = this.beforeLayers; + this.layers.value = [...this.beforeLayers]; // 恢复原活动图层 this.activeLayerId.value = this.oldActiveLayerId; @@ -563,6 +563,12 @@ export class RemoveLayerCommand extends Command { allObjects.push(object); } } + layer.fabricObjects?.forEach((fabric) => { + const { object } = findObjectById(this.canvas, fabric.id); + if (object && !allObjects.includes(object)) { + allObjects.push(object); + } + }); // 递归收集子图层的对象 if (layer.children && Array.isArray(layer.children)) { @@ -609,7 +615,7 @@ export class RemoveLayerCommand extends Command { // this.canvas.renderAll(); // } await this.layerManager?.updateLayersObjectsInteractivity?.(); - // this.canvas.renderAll(); + this.canvas.renderAll(); console.log( `✅ 已移除图层: ${this.removedLayer.name} (ID: ${this.layerId}),包含 ${this.originalObjects.length} 个对象` @@ -2013,7 +2019,7 @@ export class LayerObjectsToGroupCommand extends Command { console.error("图层或Canvas未初始化"); return null; } - + this.activeLayer = this.layerManager.getActiveLayer(); // 查找图层中是否已有组对象 const existingGroup = this._findExistingGroup(); this.existingGroupId = existingGroup?.id || null; @@ -2067,10 +2073,10 @@ export class LayerObjectsToGroupCommand extends Command { } // 更新交互性 - this.layerManager?.updateLayersObjectsInteractivity?.(false); - - // 更新缩略图 - this._updateThumbnail(); + this.layerManager?.updateLayersObjectsInteractivity?.(false).then(()=>{ + // 更新缩略图 + this._updateThumbnail(); + }); }); // 标记为非首次执行 @@ -2220,7 +2226,7 @@ export class LayerObjectsToGroupCommand extends Command { async undo() { if (!this.activeLayer || !this.canvas || !this.groupObjectId) return; - + this.activeLayer = this.layerManager.getActiveLayer(); try { await optimizeCanvasRendering(this.canvas, async () => { if (this.wasGroupCreated) { @@ -2338,7 +2344,7 @@ export class LayerObjectsToGroupCommand extends Command { // 将对象添加回画布 this.canvas.add(obj); - restoredObjects.push(obj); + restoredObjects.push(obj.toObject("id", "layerId", "layerName")); console.log( `✅ 恢复原始对象 ${obj.id || obj.type} 到位置 (${position.left}, ${ @@ -2537,9 +2543,9 @@ export class LayerObjectsToGroupCommand extends Command { * @private */ _updateThumbnail() { - // this.canvas?.thumbnailManager?.generateLayerThumbnail?.( - // this.activeLayer.id - // ); + this.canvas?.thumbnailManager?.generateLayerThumbnail?.( + this.activeLayer.id + ); } getInfo() { diff --git a/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js b/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js index 3e9731aa..6b180729 100644 --- a/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js +++ b/src/component/Canvas/CanvasEditor/commands/RasterizeLayerCommand.js @@ -343,7 +343,7 @@ export class RasterizeLayerCommand extends Command { visible: this.layer.visible, locked: this.layer.locked, opacity: this.layer.opacity, - fabricObjects: [rasterizedImage], + fabricObjects: [], }); // 更新图像对象的图层关联 @@ -353,7 +353,7 @@ export class RasterizeLayerCommand extends Command { layerId: this.rasterizedLayerId, layerName: this.rasterizedLayer.name, }); - + this.rasterizedLayer.fabricObjects = [rasterizedImage.toObject(["id", "layerId", "layerName"])] // 在适当位置添加新的组合图层 this._replaceLayerInStructure(); diff --git a/src/component/Canvas/CanvasEditor/commands/TextCommands.js b/src/component/Canvas/CanvasEditor/commands/TextCommands.js index 24c47c62..4b02f510 100644 --- a/src/component/Canvas/CanvasEditor/commands/TextCommands.js +++ b/src/component/Canvas/CanvasEditor/commands/TextCommands.js @@ -1,4 +1,4 @@ -import { generateId, optimizeCanvasRendering } from "../utils/helper"; +import { generateId, optimizeCanvasRendering, getLayerObjectsZIndex } from "../utils/helper"; import { createLayer, LayerType, OperationType } from "../utils/layerHelper"; import { Command } from "./Command"; import i18n from "@/lang/index.ts"; @@ -536,6 +536,12 @@ export class CreateTextCommand extends Command { if (this.textObject && this.canvas) { this.canvas.remove(this.textObject); } + const layerObjects = getLayerObjectsZIndex(this.canvas, this.layerId); + layerObjects.forEach((obj) => { + if (obj.id === this.textObject?.id) { + this.canvas.remove(obj.object); + } + }); // 智能移除创建的图层 if (this.layerId && this.layerManager) { diff --git a/src/component/Canvas/CanvasEditor/components/BrushControlPanel.vue b/src/component/Canvas/CanvasEditor/components/BrushControlPanel.vue index 6ef70614..310b6a60 100644 --- a/src/component/Canvas/CanvasEditor/components/BrushControlPanel.vue +++ b/src/component/Canvas/CanvasEditor/components/BrushControlPanel.vue @@ -488,7 +488,7 @@ watch( display: flex; justify-content: center; align-items: center; - background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% / 10px 10px; + background: repeating-conic-gradient(#F9FAFA 0% 25%, #ffffff 0% 50%) 50% / 10px 10px; border-radius: 6px; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); margin-bottom: 5px; @@ -518,7 +518,7 @@ watch( left: 0; width: 100%; height: 100%; - background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% / 10px 10px; + background: repeating-conic-gradient(#F9FAFA 0% 25%, #ffffff 0% 50%) 50% / 10px 10px; } .opacity-color { @@ -542,7 +542,7 @@ watch( font-size: 14px; font-weight: 500; color: #333; - background: #f5f5f5; + background: #F9FAFA; padding: 2px 8px; border-radius: 4px; min-width: 50px; diff --git a/src/component/Canvas/CanvasEditor/components/BrushPanel.vue b/src/component/Canvas/CanvasEditor/components/BrushPanel.vue index b625358b..9d0aab2c 100644 --- a/src/component/Canvas/CanvasEditor/components/BrushPanel.vue +++ b/src/component/Canvas/CanvasEditor/components/BrushPanel.vue @@ -1938,7 +1938,7 @@ const brushStore = BrushStore; } .shadow-preview-box { - background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% / 10px 10px; + background: repeating-conic-gradient(#F9FAFA 0% 25%, #ffffff 0% 50%) 50% / 10px 10px; border-radius: 8px; padding: 30px; display: flex; diff --git a/src/component/Canvas/CanvasEditor/components/KeyboardShortcutHelp.vue b/src/component/Canvas/CanvasEditor/components/KeyboardShortcutHelp.vue index e1d19484..98800b47 100644 --- a/src/component/Canvas/CanvasEditor/components/KeyboardShortcutHelp.vue +++ b/src/component/Canvas/CanvasEditor/components/KeyboardShortcutHelp.vue @@ -484,7 +484,7 @@ h3 { } .shortcuts-table th { - background-color: #f5f5f5; + background-color: #F9FAFA; } .touch-tips { diff --git a/src/component/Canvas/CanvasEditor/components/LayersPanel/contextMenu.less b/src/component/Canvas/CanvasEditor/components/LayersPanel/contextMenu.less index 305571dd..dcfe0296 100644 --- a/src/component/Canvas/CanvasEditor/components/LayersPanel/contextMenu.less +++ b/src/component/Canvas/CanvasEditor/components/LayersPanel/contextMenu.less @@ -42,7 +42,7 @@ position: relative; &:hover:not(.disabled) { - background-color: #f5f5f5; + background-color: #F9FAFA; } &:active:not(.disabled) { @@ -76,7 +76,7 @@ } &.hovered { - background-color: #f5f5f5; + background-color: #F9FAFA; } } diff --git a/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.css b/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.css index 3bfac5b2..232a2738 100644 --- a/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.css +++ b/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.css @@ -61,12 +61,12 @@ .action-btn[disabled] { opacity: 0.5; cursor: not-allowed; - background-color: #f5f5f5; + background-color: #F9FAFA; color: #bfbfbf; border-color: #e6e6e6; } .action-btn[disabled]:hover { - background-color: #f5f5f5; + background-color: #F9FAFA; color: #bfbfbf; border-color: #e6e6e6; } @@ -196,7 +196,7 @@ justify-content: center; overflow: hidden; flex: none; - background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% / 1rem 1rem; + background: repeating-conic-gradient(#F9FAFA 0% 25%, #ffffff 0% 50%) 50% / 1rem 1rem; border: 1px solid #e0e0e0; } .layer-thumbnail { diff --git a/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.less b/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.less index a74a29bf..e90cbe5a 100644 --- a/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.less +++ b/src/component/Canvas/CanvasEditor/components/LayersPanel/layersPanel.less @@ -72,12 +72,12 @@ &[disabled] { opacity: 0.5; cursor: not-allowed; - background-color: #f5f5f5; + background-color: #F9FAFA; color: #bfbfbf; border-color: #e6e6e6; &:hover { - background-color: #f5f5f5; + background-color: #F9FAFA; color: #bfbfbf; border-color: #e6e6e6; } @@ -244,7 +244,7 @@ justify-content: center; overflow: hidden; flex: none; - background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% / + background: repeating-conic-gradient(#F9FAFA 0% 25%, #ffffff 0% 50%) 50% / 1rem 1rem; border: 1px solid #e0e0e0; } diff --git a/src/component/Canvas/CanvasEditor/components/css/layersPanel.css b/src/component/Canvas/CanvasEditor/components/css/layersPanel.css index 6c97b6db..047214da 100644 --- a/src/component/Canvas/CanvasEditor/components/css/layersPanel.css +++ b/src/component/Canvas/CanvasEditor/components/css/layersPanel.css @@ -60,12 +60,12 @@ .action-btn[disabled] { opacity: 0.5; cursor: not-allowed; - background-color: #f5f5f5; + background-color: #F9FAFA; color: #bfbfbf; border-color: #e6e6e6; } .action-btn[disabled]:hover { - background-color: #f5f5f5; + background-color: #F9FAFA; color: #bfbfbf; border-color: #e6e6e6; } @@ -195,7 +195,7 @@ justify-content: center; overflow: hidden; flex: none; - background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% / 1rem 1rem; + background: repeating-conic-gradient(#F9FAFA 0% 25%, #ffffff 0% 50%) 50% / 1rem 1rem; border: 1px solid #e0e0e0; } .layer-thumbnail { diff --git a/src/component/Canvas/CanvasEditor/index.vue b/src/component/Canvas/CanvasEditor/index.vue index 6ab169bb..63d40b12 100644 --- a/src/component/Canvas/CanvasEditor/index.vue +++ b/src/component/Canvas/CanvasEditor/index.vue @@ -114,6 +114,10 @@ const props = defineProps({ type: Boolean, default: false, }, + hideCanvas: { + type: Boolean, + default: false, // 是否隐藏画布-隐藏关闭部分功能 + }, }); // 引用和状态 @@ -171,6 +175,15 @@ function toggleShortcutHelp() { showShortcutHelp.value = !showShortcutHelp.value; } +watch(()=>props.hideCanvas, (newVal)=>{ + console.log("==========是否隐藏画布",newVal) + if(newVal){ + keyboardManager?.removeEvents() + }else { + keyboardManager?.init() + } +}) + // 工具选择处理 function handleToolSelect(tool) { activeTool.value = tool; @@ -693,25 +706,26 @@ function removeLayer(layerId) { return; } - if (canvasManager && canvasManager.canvas) { - const layerToRemove = layers.value.find((l) => l.id === layerId); - if (layerToRemove) { - const elementIds = layerToRemove?.fabricObjects?.map((e) => e.id); - elementIds.forEach((elementId) => { - const objectToRemove = canvasManager.canvas - .getObjects() - .find((obj) => obj.id === elementId); - if (objectToRemove) { - canvasManager.canvas.remove(objectToRemove); - } - }); - if (activeLayerId.value === layerId) { - activeElementId.value = null; - } - canvasManager.canvas.renderAll(); - } - } layerManager.removeLayer(layerId); +// 此处删除画布上内容导致撤回操作无效(多余) +// if (canvasManager && canvasManager.canvas) { +// const layerToRemove = layers.value.find((l) => l.id === layerId); +// if (layerToRemove) { +// const elementIds = layerToRemove?.fabricObjects?.map((e) => e.id); +// elementIds.forEach((elementId) => { +// const objectToRemove = canvasManager.canvas +// .getObjects() +// .find((obj) => obj.id === elementId); +// if (objectToRemove) { +// canvasManager.canvas.remove(objectToRemove); +// } +// }); +// if (activeLayerId.value === layerId) { +// activeElementId.value = null; +// } +// canvasManager.canvas.renderAll(); +// } +// } } function triggerImageUpload() { diff --git a/src/component/Canvas/CanvasEditor/managers/LayerManager.js b/src/component/Canvas/CanvasEditor/managers/LayerManager.js index 2497c55d..50320aa1 100644 --- a/src/component/Canvas/CanvasEditor/managers/LayerManager.js +++ b/src/component/Canvas/CanvasEditor/managers/LayerManager.js @@ -1819,7 +1819,8 @@ export class LayerManager { } // 检查是否是唯一的普通图层 - const normalLayers = this.layers.value.filter((l) => !l.isBackground); + const normalLayers = this.layers.value.filter((l) => !l.isBackground && !l.isFixed); + console.log("普通图层:", normalLayers) if (normalLayers.length === 1) { console.warn("不能剪切唯一的普通图层"); return null; diff --git a/src/component/Canvas/CanvasEditor/managers/animation/AnimationManager.js b/src/component/Canvas/CanvasEditor/managers/animation/AnimationManager.js index c9250732..fae2d949 100644 --- a/src/component/Canvas/CanvasEditor/managers/animation/AnimationManager.js +++ b/src/component/Canvas/CanvasEditor/managers/animation/AnimationManager.js @@ -69,7 +69,7 @@ export class AnimationManager { // 如果变化太小,直接应用缩放 if (Math.abs(targetZoom - currentZoom) < 0.01) { - this._applyZoom(point, targetZoom); + // this._applyZoom(point, targetZoom); return; } @@ -121,7 +121,7 @@ export class AnimationManager { this._zoomAnimation = null; // 确保最终状态准确 - this._applyZoom(point, targetZoom, true); + // this._applyZoom(point, targetZoom, true); }, }; @@ -817,7 +817,7 @@ export class AnimationManager { this._wasZooming = false; // 确保最终状态准确 - this._applyZoom(point, targetZoom, true); + // this._applyZoom(point, targetZoom, true); }, }); } diff --git a/src/component/Canvas/CanvasEditor/managers/events/KeyboardManager.js b/src/component/Canvas/CanvasEditor/managers/events/KeyboardManager.js index c97c48d7..b2fd6364 100644 --- a/src/component/Canvas/CanvasEditor/managers/events/KeyboardManager.js +++ b/src/component/Canvas/CanvasEditor/managers/events/KeyboardManager.js @@ -215,6 +215,25 @@ export class KeyboardManager { console.log(`键盘管理器已初始化,平台: ${this.platform}, 触摸设备: ${this.isTouchDevice}`); } + /** + * hide模式下,关闭快捷键 + */ + removeEvents() { + // 移除键盘事件监听 + this.container.removeEventListener("keydown", this._handleKeyDown); + this.container.removeEventListener("keyup", this._handleKeyUp); + + // 如果是触摸设备,移除触摸事件监听 + if (this.isTouchDevice) { + this.container.removeEventListener("touchstart", this._handleTouchStart); + this.container.removeEventListener("touchmove", this._handleTouchMove); + this.container.removeEventListener("touchend", this._handleTouchEnd); + this.container.removeEventListener("touchcancel", this._handleTouchEnd); + } + } + + + /** * 处理键盘按下事件 * @param {KeyboardEvent} event 键盘事件 diff --git a/src/component/Canvas/ExistsImageList/ToolButton.vue b/src/component/Canvas/ExistsImageList/ToolButton.vue index 5c51ff9a..f9606771 100644 --- a/src/component/Canvas/ExistsImageList/ToolButton.vue +++ b/src/component/Canvas/ExistsImageList/ToolButton.vue @@ -159,6 +159,7 @@ onUnmounted(() => { white-space: nowrap; font-size: 1.2rem; z-index: 9999; + pointer-events: none; } .tool-tooltip:before { diff --git a/src/component/Canvas/canvasExample.vue b/src/component/Canvas/canvasExample.vue index d67bdd41..e0b82da9 100644 --- a/src/component/Canvas/canvasExample.vue +++ b/src/component/Canvas/canvasExample.vue @@ -157,7 +157,30 @@ function canvasProject() { console.warn("没有找到保存的画布项目"); } } - +const exportJSON = () => { + console.log("导出JSON"); + // 实现导出JSON逻辑 + const json = canvasEditor.value.getJSON(); + // 导出JSON文件 + const blob = new Blob([json], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "canvas_project.json"; + a.click(); + URL.revokeObjectURL(url); +}; +// 复制JSON +const copyJSON = () => { + console.log("复制JSON"); + // 实现复制JSON逻辑 + const json = canvasEditor.value.getJSON(); + // 复制JSON到剪贴板 + navigator.clipboard.writeText(json); +}; +const getLayers = ()=>{ + console.log("==========layers",canvasEditor.value?.layers) +} // 处理自定义工具点击 const handleCustomToolClick = (tool) => { tool.action(); @@ -255,6 +278,26 @@ const isShowLeft = ref(true);
更换底图
+
+ +
保存画布
+
+
+ +
读取画布
+
+
+ +
导出JSON
+
+
+ +
复制JSON
+
+
+ +
查询图层
+