diff --git a/node_info.js b/node_info.js
index 76b40a7..ac51184 100644
--- a/node_info.js
+++ b/node_info.js
@@ -9,8 +9,6 @@ const verticalDistributionSvg = ``
const equalHeightSvg = ``
-const current_node_list = []; // 存储已选中的节点
-
const ButtonManager = {
isInitialized: false, // 检查是否已经初始化
buttonContainer: null, // 保存按钮容器
@@ -330,94 +328,172 @@ const ButtonManager = {
return selectedNodesObj ? Object.values(selectedNodesObj) : [];
},
- // 执行对齐操作的通用方法
- alignNodesByProperty(prop, value) {
- const nodes = this.getSelectedNodes();
- if (nodes.length > 0) {
- nodes.forEach(node => {
- node.pos[prop] = value;
- });
- LGraphCanvas.active_canvas.setDirty(true, true); // 重新渲染 canvas
- }
+ // 辅助函数:按照 X 或 Y 坐标分组
+ groupNodesByCoordinate(nodes, axis, tolerance = 100) {
+ const groups = [];
+
+ nodes.forEach(node => {
+ let foundGroup = null;
+
+ for (let group of groups) {
+ const groupCoord = group[0].pos[axis];
+
+ if (Math.abs(groupCoord - node.pos[axis]) <= tolerance) {
+ foundGroup = group;
+ break;
+ }
+ }
+
+ if (foundGroup) {
+ foundGroup.push(node);
+ } else {
+ groups.push([node]);
+ }
+ });
+
+ return groups;
},
// 左对齐
alignLeft() {
const selectedNodes = this.getSelectedNodes();
if (selectedNodes.length === 0) {
- // 如果没有选中任何节点,重置视图位置和缩放比例
const canvas = LGraphCanvas.active_canvas;
if (canvas) {
canvas.ds.offset = [80, 140]; // 重置视图位置
canvas.ds.scale = 1; // 重置缩放比例
canvas.setDirty(true, true);
}
- } else if (selectedNodes.length === 1) {
- selectedNodes[0].pos[0] = 0;
- } else if (selectedNodes.length > 1) {
- const leftMost = Math.min(...selectedNodes.map(node => node.pos[0]));
- this.alignNodesByProperty(0, leftMost);
+ } else {
+ // 按 X 轴进行分组
+ const groups = this.groupNodesByCoordinate(selectedNodes, 0); // 分组基于X轴坐标
+ groups.forEach(group => {
+ const leftMost = Math.min(...group.map(node => node.pos[0]));
+ group.forEach(node => {
+ node.pos[0] = leftMost; // 左对齐
+ });
+ });
}
LGraphCanvas.active_canvas.setDirty(true, true);
},
+
// 右对齐
alignRight() {
- const rightMost = Math.max(...this.getSelectedNodes().map(node => node.pos[0] + node.size[0]));
- this.getSelectedNodes().forEach(node => {
- node.pos[0] = rightMost - node.size[0];
- });
+ const selectedNodes = this.getSelectedNodes();
+ if (selectedNodes.length > 0) {
+ // 按 X 轴进行分组
+ const groups = this.groupNodesByCoordinate(selectedNodes, 0); // 分组基于X轴坐标
+ groups.forEach(group => {
+ const rightMost = Math.max(...group.map(node => node.pos[0] + node.size[0]));
+ group.forEach(node => {
+ node.pos[0] = rightMost - node.size[0]; // 右对齐
+ });
+ });
+ }
LGraphCanvas.active_canvas.setDirty(true, true);
},
+
// 顶部对齐
alignTop() {
const selectedNodes = this.getSelectedNodes();
- if (selectedNodes.length === 1) {
- selectedNodes[0].pos[1] = 0;
- } else if (selectedNodes.length > 1) {
- const topMost = Math.min(...selectedNodes.map(node => node.pos[1]));
- this.alignNodesByProperty(1, topMost);
+ if (selectedNodes.length > 0) {
+ // 按 Y 轴进行分组
+ const groups = this.groupNodesByCoordinate(selectedNodes, 1); // 分组基于Y轴坐标
+ groups.forEach(group => {
+ const topMost = Math.min(...group.map(node => node.pos[1]));
+ group.forEach(node => {
+ node.pos[1] = topMost; // 顶部对齐
+ });
+ });
}
LGraphCanvas.active_canvas.setDirty(true, true);
},
// 底部对齐
alignBottom() {
- const bottomMost = Math.max(...this.getSelectedNodes().map(node => node.pos[1] + node.size[1]));
- this.getSelectedNodes().forEach(node => {
- node.pos[1] = bottomMost - node.size[1];
- });
+ const selectedNodes = this.getSelectedNodes();
+ if (selectedNodes.length > 0) {
+ // 按 Y 轴进行分组
+ const groups = this.groupNodesByCoordinate(selectedNodes, 1); // 分组基于Y轴坐标
+ groups.forEach(group => {
+ const bottomMost = Math.max(...group.map(node => node.pos[1] + node.size[1]));
+ group.forEach(node => {
+ node.pos[1] = bottomMost - node.size[1]; // 底部对齐
+ });
+ });
+ }
LGraphCanvas.active_canvas.setDirty(true, true);
},
// 水平居中对齐
alignCenterHorizontally() {
- const centerY = this.calculateCenter(1);
- this.getSelectedNodes().forEach(node => {
- node.pos[1] = centerY - node.size[1] / 2;
- });
+ const selectedNodes = this.getSelectedNodes();
+ if (selectedNodes.length > 0) {
+ // 按 Y 轴进行分组
+ const groups = this.groupNodesByCoordinate(selectedNodes, 1); // 分组基于Y轴坐标
+ groups.forEach(group => {
+ const centerY = this.calculateCenterInGroup(group, 1); // 计算 Y 轴中心
+ group.forEach(node => {
+ node.pos[1] = centerY - node.size[1] / 2; // 垂直居中
+ });
+ });
+ }
LGraphCanvas.active_canvas.setDirty(true, true);
},
// 垂直居中对齐
alignCenterVertically() {
- const centerX = this.calculateCenter(0);
- this.getSelectedNodes().forEach(node => {
- node.pos[0] = centerX - node.size[0] / 2;
- });
+ const selectedNodes = this.getSelectedNodes();
+ if (selectedNodes.length > 0) {
+ // 按 X 轴进行分组
+ const groups = this.groupNodesByCoordinate(selectedNodes, 0); // 分组基于X轴坐标
+ groups.forEach(group => {
+ const centerX = this.calculateCenterInGroup(group, 0); // 计算 X 轴中心
+ group.forEach(node => {
+ node.pos[0] = centerX - node.size[0] / 2; // 水平居中
+ });
+ });
+ }
LGraphCanvas.active_canvas.setDirty(true, true);
},
- // 计算节点的中心坐标
- calculateCenter(axis) {
- const nodes = this.getSelectedNodes();
- const min = Math.min(...nodes.map(node => node.pos[axis]));
- const max = Math.max(...nodes.map(node => node.pos[axis] + node.size[axis]));
- return (min + max) / 2;
+ // 计算组内节点的中心坐标
+ calculateCenterInGroup(group, axis) {
+ const minCoord = Math.min(...group.map(node => node.pos[axis]));
+ const maxCoord = Math.max(...group.map(node => node.pos[axis] + node.size[axis]));
+ return (minCoord + maxCoord) / 2;
},
// 横向分布
horizontalDistribution() {
- this.distributeNodes(0);
+ const nodes = this.getSelectedNodes();
+ const axis = 0;
+ if (nodes.length > 1) {
+ // 按照节点在 axis 轴上的位置(高低)进行排序
+ nodes.sort((a, b) => a.pos[axis] - b.pos[axis]);
+
+ // 获取最小和最大的位置范围
+ const min = Math.min(...nodes.map(node => node.pos[axis]));
+ const max = Math.max(...nodes.map(node => node.pos[axis] + node.size[axis]));
+
+ // 计算节点的总尺寸
+ const totalSize = nodes.reduce((sum, node) => sum + node.size[axis], 0);
+
+ // 计算间距
+ const spacing = (max - min - totalSize) / (nodes.length - 1);
+
+ // 初始化当前分布位置
+ let current = min;
+
+ // 遍历排序后的节点,按顺序分布
+ nodes.forEach(node => {
+ node.pos[axis] = current; // 设置当前节点位置
+ current += node.size[axis] + spacing; // 更新下一个节点位置
+ });
+
+ // 重新渲染画布
+ LGraphCanvas.active_canvas.setDirty(true, true);
+ }
},
// 纵向分布
@@ -427,7 +503,7 @@ const ButtonManager = {
if (nodes.length > 1) {
const axis = 1; // Y轴
const otherAxis = 0; // X轴
- const tolerance = 20; // 用于将节点分组的容差
+ const tolerance = 100; // 用于将节点分组的容差
const minSpacing = 20; // 最小间距,保证节点之间至少有 20 像素的间隔
// 用于存储列的数组
@@ -463,10 +539,10 @@ const ButtonManager = {
// 找到最高列的高度
const maxColumnHeight = Math.max(...columnHeights);
- // 找到所有列中第一个节点的最小 Y 值,用于对齐第一排
+ // 找到当前所有列中第一个节点的最小 Y 值,用于对齐第一排
const minFirstNodeY = Math.min(...columns.map(column => column[0].pos[axis]));
- // 对每列进行处理,类似 distributeNodes 方法
+ // 对每列进行处理
columns.forEach((column, columnIndex) => {
if (column.length > 1) {
// 按照节点在 Y 轴上的位置(高低)进行排序
@@ -503,10 +579,7 @@ const ButtonManager = {
// 重新渲染画布
LGraphCanvas.active_canvas.setDirty(true, true);
}
- }
-
- ,
-
+ },
// 等宽
equalWidth() {
this.equalSize(0);
@@ -528,38 +601,6 @@ const ButtonManager = {
});
LGraphCanvas.active_canvas.setDirty(true, true);
}
- },
-
- // 通用的节点分布方法
- distributeNodes(axis) {
- const nodes = this.getSelectedNodes();
-
- if (nodes.length > 1) {
- // 按照节点在 axis 轴上的位置(高低)进行排序
- nodes.sort((a, b) => a.pos[axis] - b.pos[axis]);
-
- // 获取最小和最大的位置范围
- const min = Math.min(...nodes.map(node => node.pos[axis]));
- const max = Math.max(...nodes.map(node => node.pos[axis] + node.size[axis]));
-
- // 计算节点的总尺寸
- const totalSize = nodes.reduce((sum, node) => sum + node.size[axis], 0);
-
- // 计算间距
- const spacing = (max - min - totalSize) / (nodes.length - 1);
-
- // 初始化当前分布位置
- let current = min;
-
- // 遍历排序后的节点,按顺序分布
- nodes.forEach(node => {
- node.pos[axis] = current; // 设置当前节点位置
- current += node.size[axis] + spacing; // 更新下一个节点位置
- });
-
- // 重新渲染画布
- LGraphCanvas.active_canvas.setDirty(true, true);
- }
}
};