feat: 完善选区功能,新增组图层自由编辑
This commit is contained in:
@@ -373,6 +373,7 @@ function findParentLayerId() {
|
||||
'fixed-layer': layer.isBackground || layer.isFixed,
|
||||
},
|
||||
]"
|
||||
:data-layer-id="layer.id"
|
||||
@click="handleClick"
|
||||
@dblclick="handleDoubleClick"
|
||||
@touchstart="handleTouchStart"
|
||||
|
||||
@@ -39,6 +39,7 @@ const emit = defineEmits([
|
||||
"update:editing-name",
|
||||
"root-layers-sort",
|
||||
"child-layers-sort",
|
||||
"cross-level-move", // 新增:跨层级移动事件
|
||||
"select-child-layer",
|
||||
"start-child-layer-edit",
|
||||
"child-context-menu",
|
||||
@@ -73,6 +74,79 @@ const forwardEvent = (eventName, ...args) => {
|
||||
|
||||
// 处理根级图层拖拽排序
|
||||
const handleRootLayersSort = (event) => {
|
||||
console.log("🔄 拖拽结束事件:", event);
|
||||
console.log("📍 当前组件信息:", {
|
||||
isChild: props.isChild,
|
||||
parentLayerId: props.parentLayerId,
|
||||
groupName: props.groupName,
|
||||
});
|
||||
|
||||
// 清理拖拽样式
|
||||
const sortableContainers = document.querySelectorAll(".sortable-layers");
|
||||
sortableContainers.forEach((container) => {
|
||||
container.classList.remove("drag-mode", "drop-target", "drop-invalid");
|
||||
});
|
||||
|
||||
// 检查是否为跨层级拖拽
|
||||
const { from, to, oldIndex, newIndex, item } = event;
|
||||
const isFromDifferentContainer = from !== to;
|
||||
|
||||
if (isFromDifferentContainer) {
|
||||
console.log("🔀 检测到跨层级拖拽");
|
||||
|
||||
// 获取被拖拽的图层ID
|
||||
const draggedLayerId =
|
||||
item.getAttribute("data-layer-id") ||
|
||||
props.sortableRootLayers[oldIndex]?.id;
|
||||
|
||||
if (!draggedLayerId) {
|
||||
console.error("❌ 无法获取被拖拽的图层ID");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取容器类型信息
|
||||
const fromContainerType = from.getAttribute("data-container-type");
|
||||
const toContainerType = to.getAttribute("data-container-type");
|
||||
const fromParentId = from.getAttribute("data-parent-id");
|
||||
const toParentId = to.getAttribute("data-parent-id");
|
||||
|
||||
console.log("📦 拖拽信息:", {
|
||||
fromContainerType,
|
||||
toContainerType,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
draggedLayerId,
|
||||
});
|
||||
|
||||
// 验证拖拽的有效性
|
||||
if (
|
||||
!validateCrossLevelMove(
|
||||
draggedLayerId,
|
||||
fromContainerType,
|
||||
toContainerType,
|
||||
fromParentId,
|
||||
toParentId
|
||||
)
|
||||
) {
|
||||
console.warn("⚠️ 无效的跨层级移动,操作被取消");
|
||||
return;
|
||||
}
|
||||
|
||||
// 发送跨层级移动事件
|
||||
emit("cross-level-move", {
|
||||
layerId: draggedLayerId,
|
||||
fromContainerType,
|
||||
toContainerType,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex,
|
||||
oldIndex,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 普通的同层级拖拽排序
|
||||
if (props.isChild) {
|
||||
// 子图层事件处理
|
||||
// 确保排序只影响当前组图层的children,而不是全局layers
|
||||
@@ -87,6 +161,92 @@ const handleRootLayersSort = (event) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 验证跨层级移动的有效性
|
||||
const validateCrossLevelMove = (
|
||||
layerId,
|
||||
fromType,
|
||||
toType,
|
||||
fromParentId,
|
||||
toParentId
|
||||
) => {
|
||||
// 查找图层
|
||||
const layer = findLayerInHierarchy(layerId, fromType, fromParentId);
|
||||
|
||||
if (!layer) {
|
||||
console.error("找不到要移动的图层:", layerId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否为不可移动的图层
|
||||
if (layer.isBackground || layer.isFixed) {
|
||||
console.warn("背景层和固定层不能移动");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否试图将组图层移动到自己的子层级中(防止循环引用)
|
||||
if (toType === "child" && toParentId && isDescendantOf(toParentId, layerId)) {
|
||||
console.warn("不能将图层移动到自己的子层级中");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// 在层级结构中查找图层
|
||||
const findLayerInHierarchy = (layerId, containerType, parentId) => {
|
||||
if (containerType === "root") {
|
||||
return props.layers.find((layer) => layer.id === layerId);
|
||||
} else if (containerType === "child" && parentId) {
|
||||
const parent = props.layers.find((layer) => layer.id === parentId);
|
||||
return parent?.children?.find((child) => child.id === layerId);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// 检查是否为子层级关系(防止循环引用)
|
||||
const isDescendantOf = (ancestorId, layerId) => {
|
||||
const checkChildren = (children) => {
|
||||
if (!children) return false;
|
||||
for (const child of children) {
|
||||
if (child.id === layerId) return true;
|
||||
if (child.children && checkChildren(child.children)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const ancestor = props.layers.find((layer) => layer.id === ancestorId);
|
||||
return ancestor ? checkChildren(ancestor.children) : false;
|
||||
};
|
||||
|
||||
// 拖拽开始事件
|
||||
const handleDragStart = (event) => {
|
||||
console.log("🎯 开始拖拽:", event);
|
||||
const { item } = event;
|
||||
|
||||
// 为拖拽元素添加数据属性
|
||||
if (item) {
|
||||
item.setAttribute("data-dragging", "true");
|
||||
|
||||
// 添加拖拽相关的样式类
|
||||
const sortableContainers = document.querySelectorAll(".sortable-layers");
|
||||
sortableContainers.forEach((container) => {
|
||||
container.classList.add("drag-mode");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 拖拽添加事件(当元素被拖拽到新容器时)
|
||||
const handleDragAdd = (event) => {
|
||||
console.log("➕ 拖拽添加:", event);
|
||||
// 这个事件在跨容器拖拽时会触发
|
||||
};
|
||||
|
||||
// 拖拽移除事件(当元素被从容器中移除时)
|
||||
const handleDragRemove = (event) => {
|
||||
console.log("➖ 拖拽移除:", event);
|
||||
// 这个事件在跨容器拖拽时会触发
|
||||
};
|
||||
|
||||
const canDeleteComputed = computed(() => {
|
||||
// 如果是子图层,检查父图层是否可以删除
|
||||
if (props.isChild) {
|
||||
@@ -106,18 +266,33 @@ const canDeleteComputed = computed(() => {
|
||||
<VueDraggable
|
||||
:model-value="sortableRootLayers"
|
||||
@end="handleRootLayersSort"
|
||||
@add="handleDragAdd"
|
||||
@remove="handleDragRemove"
|
||||
@start="handleDragStart"
|
||||
class="sortable-layers"
|
||||
:animation="200"
|
||||
:data-container-type="isChild ? 'child' : 'root'"
|
||||
:data-parent-id="isChild ? parentLayerId : null"
|
||||
:animation="250"
|
||||
:disabled="false"
|
||||
handle=".layer-drag-handle"
|
||||
ghost-class="ghost"
|
||||
chosen-class="chosen"
|
||||
drag-class="drag"
|
||||
:group="groupName"
|
||||
:group="{
|
||||
name: groupName,
|
||||
pull: true,
|
||||
put: true,
|
||||
}"
|
||||
:swap-threshold="0.5"
|
||||
:empty-insert-threshold="5"
|
||||
:force-fallback="false"
|
||||
:fallback-tolerance="3"
|
||||
:scroll-sensitivity="100"
|
||||
:scroll-speed="10"
|
||||
>
|
||||
<!-- 遍历可排序的根级图层 -->
|
||||
<template v-for="(layer, index) in sortableRootLayers" :key="layer.id">
|
||||
<div class="layer-group">
|
||||
<div class="layer-group" :data-layer-id="layer.id">
|
||||
<!-- 使用 LayerItem 子组件 -->
|
||||
<!-- :thumbnail-url="getLayerThumbnail(layer.id)" -->
|
||||
|
||||
@@ -193,7 +368,7 @@ const canDeleteComputed = computed(() => {
|
||||
:expanded-group-ids="expandedGroupIds"
|
||||
:isChild="true"
|
||||
:parentLayerId="layer.id"
|
||||
group-name="layers-child"
|
||||
:group-name="groupName"
|
||||
@layer-click="(...args) => forwardEvent('layer-click', ...args)"
|
||||
@layer-double-click="
|
||||
(...args) => forwardEvent('layer-double-click', ...args)
|
||||
@@ -222,6 +397,9 @@ const canDeleteComputed = computed(() => {
|
||||
@child-layers-sort="
|
||||
(...args) => forwardEvent('child-layers-sort', ...args)
|
||||
"
|
||||
@cross-level-move="
|
||||
(...args) => forwardEvent('cross-level-move', ...args)
|
||||
"
|
||||
@select-child-layer="
|
||||
(...args) => forwardEvent('select-child-layer', ...args)
|
||||
"
|
||||
@@ -296,18 +474,81 @@ const canDeleteComputed = computed(() => {
|
||||
border-top: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
// 拖拽模式样式
|
||||
.drag-mode {
|
||||
.layer-item {
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:not(.chosen):not(.ghost) {
|
||||
opacity: 0.7;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 拖拽状态样式
|
||||
.ghost {
|
||||
opacity: 0.5;
|
||||
background: #f0f0f0;
|
||||
opacity: 0.4;
|
||||
background: linear-gradient(90deg, #e6f7ff 0%, #bae7ff 100%);
|
||||
border: 2px dashed #1890ff;
|
||||
transform: rotate(2deg);
|
||||
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.chosen {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.02);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
z-index: 999;
|
||||
background: linear-gradient(90deg, #fff2e8 0%, #ffd8bf 100%);
|
||||
border: 2px solid #fa8c16;
|
||||
}
|
||||
|
||||
.drag {
|
||||
opacity: 0.6;
|
||||
transform: rotate(-1deg);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
// 跨层级拖拽目标区域高亮
|
||||
.sortable-layers {
|
||||
position: relative;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease;
|
||||
border-radius: 4px;
|
||||
min-height: 40px; // 确保空组也有足够的拖拽区域
|
||||
|
||||
&.drop-target {
|
||||
background-color: rgba(82, 196, 26, 0.1);
|
||||
border: 2px dashed #52c41a;
|
||||
|
||||
&::before {
|
||||
content: "拖拽到此处";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #52c41a;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.drop-invalid {
|
||||
background-color: rgba(255, 77, 79, 0.1);
|
||||
border: 2px dashed #ff4d4f;
|
||||
|
||||
&::before {
|
||||
content: "无法拖拽到此处";
|
||||
color: #ff4d4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { findLayerRecursively, isGroupLayer } from "../../utils/layerHelper";
|
||||
import ContextMenu from "./ContextMenu.vue";
|
||||
import LayerItem from "./LayerItem.vue";
|
||||
import LayersList from "./LayersList.vue"; // 引入 LayersList 组件
|
||||
import { createCrossLevelMoveCommand } from "../../commands/CrossLevelMoveCommands";
|
||||
// // 导入命令类
|
||||
// import {
|
||||
// ReorderLayersCommand,
|
||||
@@ -605,6 +606,7 @@ function handleLayerClick(layer, event) {
|
||||
} else {
|
||||
// 否则直接设置当前图层为活动图层
|
||||
setActiveLayer(layer.id);
|
||||
layerManager?.updateLayersObjectsInteractivity();
|
||||
}
|
||||
}
|
||||
lastSelectedIndex.value = sortableRootLayers.value.findIndex(
|
||||
@@ -1215,6 +1217,316 @@ function moveLayerToBottom(layerId) {
|
||||
const forwardEvent = (eventName, ...args) => {
|
||||
emit(eventName, ...args);
|
||||
};
|
||||
|
||||
// 处理跨层级移动
|
||||
async function handleCrossLevelMove(moveData) {
|
||||
console.log("🔀 处理跨层级移动:", moveData);
|
||||
|
||||
const {
|
||||
layerId,
|
||||
fromContainerType,
|
||||
toContainerType,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex,
|
||||
oldIndex,
|
||||
} = moveData;
|
||||
|
||||
// 基本验证
|
||||
if (!layerId) {
|
||||
console.error("❌ 缺少图层ID");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 如果有命令管理器,使用命令模式
|
||||
if (commandManager) {
|
||||
console.log("📝 使用命令模式执行跨层级移动");
|
||||
|
||||
const command = createCrossLevelMoveCommand({
|
||||
layers,
|
||||
layerManager,
|
||||
canvas: layerManager?.canvas,
|
||||
layerId,
|
||||
fromContainerType,
|
||||
toContainerType,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex,
|
||||
oldIndex,
|
||||
});
|
||||
|
||||
// 执行命令
|
||||
const result = await commandManager.executeCommand(command);
|
||||
|
||||
if (result) {
|
||||
console.log("✅ 跨层级移动命令执行成功");
|
||||
// 清除选择状态
|
||||
clearSelection();
|
||||
} else {
|
||||
console.warn("⚠️ 跨层级移动命令执行失败");
|
||||
}
|
||||
|
||||
return result;
|
||||
} else {
|
||||
// 回退方案:直接执行移动逻辑
|
||||
console.log("📝 使用回退方案执行跨层级移动");
|
||||
return await executeDirectMove(moveData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ 跨层级移动失败:", error);
|
||||
|
||||
// 可以在这里添加用户友好的错误提示
|
||||
const errorMessages = {
|
||||
找不到要移动的图层: "无法找到要移动的图层,请刷新页面后重试",
|
||||
背景层和固定层不能移动: "背景层和固定层无法移动",
|
||||
不能将图层移动到自己的子层级中: "无法将图层移动到自己的子层级中",
|
||||
目标图层不是组图层: "只能将图层移动到组图层中",
|
||||
};
|
||||
|
||||
const userMessage =
|
||||
errorMessages[error.message] || `移动失败: ${error.message}`;
|
||||
|
||||
// 这里可以触发一个全局的错误提示组件
|
||||
// 暂时使用console.warn,实际项目中应该替换为适当的提示方式
|
||||
console.warn("用户提示:", userMessage);
|
||||
}
|
||||
}
|
||||
|
||||
// 直接执行移动的回退方案(保持原有逻辑)
|
||||
async function executeDirectMove(moveData) {
|
||||
const {
|
||||
layerId,
|
||||
fromContainerType,
|
||||
toContainerType,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex,
|
||||
oldIndex,
|
||||
} = moveData;
|
||||
|
||||
// 查找被拖拽的图层
|
||||
let draggedLayer = null;
|
||||
let sourceParent = null;
|
||||
|
||||
// 根据源容器类型查找图层
|
||||
if (fromContainerType === "root") {
|
||||
draggedLayer = layers.value.find((layer) => layer.id === layerId);
|
||||
} else if (fromContainerType === "child" && fromParentId) {
|
||||
sourceParent = layers.value.find((layer) => layer.id === fromParentId);
|
||||
if (sourceParent && sourceParent.children) {
|
||||
draggedLayer = sourceParent.children.find(
|
||||
(child) => child.id === layerId
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!draggedLayer) {
|
||||
throw new Error("找不到要移动的图层");
|
||||
}
|
||||
|
||||
// 检查是否允许移动(背景层和固定层不能移动)
|
||||
if (draggedLayer.isBackground || draggedLayer.isFixed) {
|
||||
throw new Error("背景层和固定层不能移动");
|
||||
}
|
||||
|
||||
// 情况1: 从顶级图层移动到组图层内
|
||||
if (fromContainerType === "root" && toContainerType === "child") {
|
||||
await moveRootToGroup(draggedLayer, toParentId, newIndex);
|
||||
}
|
||||
// 情况2: 从组图层内移动到顶级图层
|
||||
else if (fromContainerType === "child" && toContainerType === "root") {
|
||||
await moveGroupToRoot(draggedLayer, fromParentId, newIndex);
|
||||
}
|
||||
// 情况3: 在不同组之间移动
|
||||
else if (
|
||||
fromContainerType === "child" &&
|
||||
toContainerType === "child" &&
|
||||
fromParentId !== toParentId
|
||||
) {
|
||||
await moveGroupToGroup(draggedLayer, fromParentId, toParentId, newIndex);
|
||||
}
|
||||
|
||||
// 刷新画布渲染
|
||||
if (layerManager?.canvas) {
|
||||
layerManager.canvas.renderAll();
|
||||
}
|
||||
|
||||
// 清除选择状态
|
||||
clearSelection();
|
||||
|
||||
console.log("✅ 跨层级移动完成");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 从顶级图层移动到组图层内
|
||||
async function moveRootToGroup(draggedLayer, toParentId, newIndex) {
|
||||
console.log("📥 顶级图层移动到组内:", {
|
||||
layerId: draggedLayer.id,
|
||||
toParentId,
|
||||
newIndex,
|
||||
});
|
||||
|
||||
// 找到目标父图层
|
||||
const targetParent = layers.value.find((layer) => layer.id === toParentId);
|
||||
if (!targetParent) {
|
||||
throw new Error(`找不到目标父图层: ${toParentId}`);
|
||||
}
|
||||
|
||||
// 检查目标父图层是否为组
|
||||
if (!isGroupLayerType(targetParent)) {
|
||||
throw new Error("目标图层不是组图层");
|
||||
}
|
||||
|
||||
// 确保父图层有children数组
|
||||
if (!targetParent.children) {
|
||||
targetParent.children = [];
|
||||
}
|
||||
|
||||
// 从顶级图层数组中移除
|
||||
const rootIndex = layers.value.findIndex(
|
||||
(layer) => layer.id === draggedLayer.id
|
||||
);
|
||||
if (rootIndex !== -1) {
|
||||
layers.value.splice(rootIndex, 1);
|
||||
}
|
||||
|
||||
// 使用 layerManager 的方法移动图层到组内
|
||||
if (layerManager?.moveLayerToGroup) {
|
||||
await layerManager.moveLayerToGroup(draggedLayer.id, toParentId, newIndex);
|
||||
} else {
|
||||
// 回退方案:手动更新图层关系
|
||||
draggedLayer.parentId = toParentId;
|
||||
targetParent.children.splice(newIndex, 0, draggedLayer);
|
||||
|
||||
// 处理 fabricObject 的层级关系
|
||||
if (draggedLayer.fabricObject && targetParent.fabricObject) {
|
||||
if (layerManager?.canvas) {
|
||||
layerManager.canvas.remove(draggedLayer.fabricObject);
|
||||
}
|
||||
targetParent.fabricObject.add(draggedLayer.fabricObject);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("✅ 成功将图层移动到组内");
|
||||
}
|
||||
|
||||
// 从组图层内移动到顶级图层
|
||||
async function moveGroupToRoot(draggedLayer, fromParentId, newIndex) {
|
||||
console.log("📤 组内图层移动到顶级:", {
|
||||
layerId: draggedLayer.id,
|
||||
fromParentId,
|
||||
newIndex,
|
||||
});
|
||||
|
||||
// 找到源父图层
|
||||
const sourceParent = layers.value.find((layer) => layer.id === fromParentId);
|
||||
if (!sourceParent || !sourceParent.children) {
|
||||
throw new Error(`找不到源父图层或其children数组: ${fromParentId}`);
|
||||
}
|
||||
|
||||
// 使用 layerManager 的方法移动图层到顶级
|
||||
if (layerManager?.moveLayerToRoot) {
|
||||
await layerManager.moveLayerToRoot(draggedLayer.id, newIndex);
|
||||
} else {
|
||||
// 回退方案:手动更新图层关系
|
||||
// 从源父图层的children中移除
|
||||
const childIndex = sourceParent.children.findIndex(
|
||||
(child) => child.id === draggedLayer.id
|
||||
);
|
||||
if (childIndex !== -1) {
|
||||
sourceParent.children.splice(childIndex, 1);
|
||||
}
|
||||
|
||||
// 处理 fabricObject 的层级关系
|
||||
if (draggedLayer.fabricObject && sourceParent.fabricObject) {
|
||||
sourceParent.fabricObject.remove(draggedLayer.fabricObject);
|
||||
if (layerManager?.canvas) {
|
||||
layerManager.canvas.add(draggedLayer.fabricObject);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除图层的parentId
|
||||
delete draggedLayer.parentId;
|
||||
|
||||
// 计算在顶级图层中的插入位置
|
||||
const targetIndex = Math.min(newIndex, layers.value.length);
|
||||
|
||||
// 将图层添加到顶级图层的指定位置
|
||||
layers.value.splice(targetIndex, 0, draggedLayer);
|
||||
}
|
||||
|
||||
console.log("✅ 成功将图层移动到顶级");
|
||||
}
|
||||
|
||||
// 在不同组之间移动
|
||||
async function moveGroupToGroup(
|
||||
draggedLayer,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex
|
||||
) {
|
||||
console.log("🔄 在不同组间移动:", {
|
||||
layerId: draggedLayer.id,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex,
|
||||
});
|
||||
|
||||
// 找到源父图层和目标父图层
|
||||
const sourceParent = layers.value.find((layer) => layer.id === fromParentId);
|
||||
const targetParent = layers.value.find((layer) => layer.id === toParentId);
|
||||
|
||||
if (!sourceParent || !targetParent) {
|
||||
throw new Error("找不到源父图层或目标父图层");
|
||||
}
|
||||
|
||||
if (!isGroupLayerType(targetParent)) {
|
||||
throw new Error("目标图层不是组图层");
|
||||
}
|
||||
|
||||
// 使用 layerManager 的方法在组间移动
|
||||
if (layerManager?.moveLayerBetweenGroups) {
|
||||
await layerManager.moveLayerBetweenGroups(
|
||||
draggedLayer.id,
|
||||
fromParentId,
|
||||
toParentId,
|
||||
newIndex
|
||||
);
|
||||
} else {
|
||||
// 回退方案:手动更新图层关系
|
||||
// 从源父图层中移除
|
||||
const childIndex = sourceParent.children.findIndex(
|
||||
(child) => child.id === draggedLayer.id
|
||||
);
|
||||
if (childIndex !== -1) {
|
||||
sourceParent.children.splice(childIndex, 1);
|
||||
|
||||
// 从源父组的fabricObject中移除
|
||||
if (draggedLayer.fabricObject && sourceParent.fabricObject) {
|
||||
sourceParent.fabricObject.remove(draggedLayer.fabricObject);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新图层的parentId
|
||||
draggedLayer.parentId = toParentId;
|
||||
|
||||
// 确保目标父图层有children数组
|
||||
if (!targetParent.children) {
|
||||
targetParent.children = [];
|
||||
}
|
||||
|
||||
// 将图层添加到目标组
|
||||
targetParent.children.splice(newIndex, 0, draggedLayer);
|
||||
|
||||
// 将图层的fabricObject添加到目标父组中
|
||||
if (draggedLayer.fabricObject && targetParent.fabricObject) {
|
||||
targetParent.fabricObject.add(draggedLayer.fabricObject);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("✅ 成功在不同组间移动图层");
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -1327,6 +1639,7 @@ const forwardEvent = (eventName, ...args) => {
|
||||
@update:editing-name="editingLayerName = $event"
|
||||
@root-layers-sort="handleRootLayersSort"
|
||||
@child-layers-sort="handleChildLayersSort"
|
||||
@cross-level-move="handleCrossLevelMove"
|
||||
@select-child-layer="selectChildLayer"
|
||||
@start-child-layer-edit="startChildLayerEdit"
|
||||
@child-context-menu="showChildLayerContextMenu"
|
||||
|
||||
Reference in New Issue
Block a user