画布增加的新功能

This commit is contained in:
李志鹏
2026-01-02 11:24:11 +08:00
parent 1ae365b1f3
commit f8e4ab8cdb
59 changed files with 4401 additions and 1213 deletions

View File

@@ -35,7 +35,8 @@ import LayersPanel from "./components/LayersPanel/LayersPanel.vue";
import BrushControlPanel from "./components/BrushControlPanel.vue";
import TextEditorPanel from "./components/TextEditorPanel.vue"; // 引入文本编辑面板
import LiquifyPanel from "./components/LiquifyPanel.vue"; // 引入液化编辑面板
import SelectMenuPanel from "./components/SelectMenuPanel.vue"; // 引入选择工具菜单组件
import PalletPanel from "./components/PalletPanel/index.vue";
import SelectMenuPanel from "./components/SelectMenuPanel/index.vue"; // 引入选择工具菜单组件
import SelectionPanel from "./components/SelectionPanel.vue"; // 引入选区面板
import { LayerType, OperationType } from "./utils/layerHelper.js";
import { ToolManager } from "./managers/ToolManager.js";
@@ -64,6 +65,10 @@ const props = defineProps({
type: [Object, String],
default: "", // 默认空
},
otherData: {
type: [Object, null],
default: null, // 默认空对象
},
config: {
type: Object,
default: () => CanvasConfig, // 默认配置
@@ -78,7 +83,11 @@ const props = defineProps({
},
clothingImageUrl: {
type: String,
default: "", // 衣服底图URL
default: "", // 衣服底图URL-线稿
},
clothingImageUrl2: {
type: String,
default: "", // 衣服底图URL-上色
},
redGreenImageUrl: {
type: String,
@@ -250,6 +259,7 @@ onMounted(async () => {
canvasColor,
enabledRedGreenMode: props.enabledRedGreenMode,
isFixedErasable: props.isFixedErasable,
props,
});
canvasManager.canvas.activeLayerId = activeLayerId;
canvasManager.activeLayerId = activeLayerId;
@@ -307,6 +317,7 @@ onMounted(async () => {
canvas: canvasManager.canvas,
commandManager,
layerManager,
canvasManager,
toolManager,
isRedGreenMode,
pasteText: (text) => {
@@ -435,6 +446,12 @@ onMounted(async () => {
canvasManager.canvas.width,
canvasManager.canvas.height
);
if(props.otherData && !props.otherData.canvasId) {
await canvasManager?.createOtherLayers(props.otherData);
await layerManager?.layerSort?.rearrangeObjects();
}
}
// // 设置固定图层是否可擦除
@@ -720,42 +737,7 @@ function deleteFun() {
}
function removeLayer(layerId) {
// Check if this is the last layer - prevent deletion
var isChild = false;
var parentLength = 0;
layers.value.forEach((layer) => {
if(layer.children.some(v => v.id == layerId)){
isChild = true;
parentLength = layer.children.length;
}
})
if(isChild && parentLength == 1 || layers.value.length <= 3){
console.warn(
"Cannot delete the last layer. At least one layer must remain."
);
return;
}
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() {
@@ -902,13 +884,17 @@ const changeCanvas = async (command) => {
...command, // 传递完整的命令数据
};
emit("changeCanvas", commandData);
if (command.canUndo || command.canRedo) {
if ((command.canUndo || command.canRedo) && props.enabledRedGreenMode) {
setTimeout(async () => {
const imageData = await canvasManager.exportImage({
restoreOpacityInRedGreen: true, // 恢复红绿图模式下的透明度
isCropByBg: true,
});
emit("trigger-red-green-mouseup", imageData);
try {
const imageData = await canvasManager.exportImage({
restoreOpacityInRedGreen: true, // 恢复红绿图模式下的透明度
isCropByBg: true,
});
emit("trigger-red-green-mouseup", imageData);
} catch (error) {
}
}, 100);
}
};
@@ -918,6 +904,14 @@ const cropImage = (url) => {
return cropImageRef.value.open(url)
};
provide("cropImage", cropImage); // 提供给子组件使用
// 颜色选择器组件
const palletPanelRef = ref(null);
const palletPanel = (url) => {
return palletPanelRef.value.open(url)
};
provide("palletPanel", palletPanel); // 提供给子组件使用
// 处理画布容器的拖放事件
const isDragOver = ref(false);
@@ -1030,6 +1024,10 @@ defineExpose({
isEnhanceImg,
});
},
// 导出颜色图层
exportColorLayer: () => {
return canvasManager.exportColorLayer();
},
/**
* 移动图层位置
* @param {string} layerId 图层ID
@@ -1245,6 +1243,7 @@ defineExpose({
:commandManager="commandManager"
:selectionManager="selectionManager"
:layerManager="layerManager"
:canvasManager="canvasManager"
:toolManager="toolManager"
:activeTool="activeTool"
/>
@@ -1269,6 +1268,7 @@ defineExpose({
?
</button>
</div>
</div>
<!-- 图层面板组件 -->
@@ -1298,9 +1298,11 @@ defineExpose({
</div>
</transition>
<!-- 裁剪图片组件 -->
<CropImage ref="cropImageRef" />
</div>
<!-- 裁剪图片组件 -->
<CropImage ref="cropImageRef" />
<!-- 颜色选择器组件 -->
<PalletPanel ref="palletPanelRef" />
<!-- <div class="footer-actions">
<button class="share-btn">Share</button>