From f6b8ff6bd64bc2bd3e1967bf8a328844d83c0b07 Mon Sep 17 00:00:00 2001 From: wbccb Date: Sun, 29 Sep 2024 16:58:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(extension):=20=E3=80=90dynamic-group?= =?UTF-8?q?=E3=80=91=E5=AE=9E=E7=8E=B0autoResize=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E7=88=B6=E8=8A=82=E7=82=B9=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD(#1750)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/extension/src/dynamic-group/index.ts | 80 ++++++++++++++++++- packages/extension/src/dynamic-group/model.ts | 2 + 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/packages/extension/src/dynamic-group/index.ts b/packages/extension/src/dynamic-group/index.ts index 35bb0297b..63cff3598 100644 --- a/packages/extension/src/dynamic-group/index.ts +++ b/packages/extension/src/dynamic-group/index.ts @@ -339,6 +339,72 @@ export class DynamicGroup { } } + onNodeMove = ({ + deltaX, + deltaY, + data, + }: Omit, 'e' | 'position'>) => { + const { id, x, y, properties } = data + if (!properties) { + return + } + const { width, height } = properties + const groupId = this.nodeGroupMap.get(id) + if (!groupId) { + return + } + const groupModel = this.lf.getNodeModelById( + groupId, + ) as DynamicGroupNodeModel + + if (!groupModel || !groupModel.isRestrict || !groupModel.autoResize) { + return + } + // 当父节点isRestrict=true & autoResize=true + // 子节点在父节点中移动时,父节点会自动调整大小 + + // step1: 计算出当前child的bounds + const newX = x + deltaX / 2 + const newY = y + deltaY / 2 + const minX = newX - width! / 2 + const minY = newY - height! / 2 + const maxX = newX + width! / 2 + const maxY = newY + height! / 2 + // step2:比较当前child.bounds与parent.bounds的差异,比如child.minX newGroupBounds.maxX) { + newGroupBounds.maxX = maxX + hasChange = true + } + if (maxY > newGroupBounds.maxY) { + newGroupBounds.maxY = maxY + hasChange = true + } + if (!hasChange) { + return + } + // step3: 根据当前parent.bounds去计算出最新的x、y、width、height + const newGroupX = + newGroupBounds.minX + (newGroupBounds.maxX - newGroupBounds.minX) / 2 + const newGroupY = + newGroupBounds.minY + (newGroupBounds.maxY - newGroupBounds.minY) / 2 + const newGroupWidth = newGroupBounds.maxX - newGroupBounds.minX + const newGroupHeight = newGroupBounds.maxY - newGroupBounds.minY + groupModel.moveTo(newGroupX, newGroupY) + groupModel.width = newGroupWidth + groupModel.height = newGroupHeight + } + onGraphRendered = ({ data }: CallbackArgs<'graph:rendered'>) => { console.log('data', data) forEach(data.nodes, (node) => { @@ -537,9 +603,15 @@ export class DynamicGroup { ) as DynamicGroupNodeModel if (groupModel && groupModel.isRestrict) { - // 如果移动的节点存在于某个分组中,且这个分组禁止子节点移出去 - const groupBounds = groupModel.getBounds() - return isAllowMoveTo(groupBounds, model, deltaX, deltaY) + if (groupModel.autoResize) { + // 子节点在父节点中移动时,父节点会自动调整大小 + // 在node:mousemove中进行父节点的调整 + return true + } else { + // 如果移动的节点存在于某个分组中,且这个分组禁止子节点移出去 + const groupBounds = groupModel.getBounds() + return isAllowMoveTo(groupBounds, model, deltaX, deltaY) + } } return true @@ -569,6 +641,7 @@ export class DynamicGroup { lf.on('node:delete', this.removeNodeFromGroup) lf.on('node:drag,node:dnd-drag', this.setActiveGroup) lf.on('node:click', this.onNodeSelect) + lf.on('node:mousemove', this.onNodeMove) lf.on('graph:rendered', this.onGraphRendered) lf.on('graph:updated', ({ data }) => console.log('data', data)) @@ -637,6 +710,7 @@ export class DynamicGroup { this.lf.off('node:delete', this.removeNodeFromGroup) this.lf.off('node:drag,node:dnd-drag', this.setActiveGroup) this.lf.off('node:click', this.onNodeSelect) + this.lf.off('node:mousemove', this.onNodeMove) this.lf.off('graph:rendered', this.onGraphRendered) // 还原 lf.addElements 方法? diff --git a/packages/extension/src/dynamic-group/model.ts b/packages/extension/src/dynamic-group/model.ts index ab0661f0e..fa5d8422c 100644 --- a/packages/extension/src/dynamic-group/model.ts +++ b/packages/extension/src/dynamic-group/model.ts @@ -84,6 +84,8 @@ export class DynamicGroupNodeModel extends RectNodeModel { children!: Set // 是否限制组内节点的移动范围。默认不限制 TODO: 完善该功能 isRestrict: boolean = false + // isRestrict 模式启用时,如果同时设置 autoResize 为 true,那么子节点在父节点中移动时,父节点会自动调整大小 + autoResize: boolean = false // 分组节点是否可以折叠 collapsible: boolean = true