Skip to content

Commit 4962e05

Browse files
committed
stricter logic for snapping of nodes with grids
1 parent 3130fad commit 4962e05

1 file changed

Lines changed: 58 additions & 10 deletions

File tree

src/graph-builder/graph-core/1-core.js

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,50 @@ class CoreGraph {
8181
this.cy.nodeEditing({
8282
resizeToContentCueEnabled: () => false,
8383
setWidth: (node, width) => {
84-
// Allow smooth resizing - don't snap during drag
85-
node.data('style', { ...node.data('style'), width });
84+
// HARD ENFORCEMENT: Snap width every frame during resize
85+
const snappedWidth = this.snapDimensionToGrid(width);
86+
node.data('style', { ...node.data('style'), width: snappedWidth });
87+
88+
// Adjust position to maintain edge alignment based on resize handle
89+
const resizeType = node.scratch('resizeType');
90+
if (resizeType && (resizeType.includes('left') || resizeType.includes('right'))) {
91+
const currentPos = node.position();
92+
const initialPos = node.scratch('resizeInitialPos');
93+
const initialWidth = node.scratch('width');
94+
const widthDelta = snappedWidth - initialWidth;
95+
96+
let newX = currentPos.x;
97+
if (resizeType.includes('left')) {
98+
newX = initialPos.x - widthDelta / 2;
99+
} else if (resizeType.includes('right')) {
100+
newX = initialPos.x + widthDelta / 2;
101+
}
102+
node.position({ x: this.snapToGrid(newX), y: currentPos.y });
103+
}
104+
return snappedWidth;
86105
},
87106
setHeight: (node, height) => {
88-
// Allow smooth resizing - don't snap during drag
89-
node.data('style', { ...node.data('style'), height });
107+
// HARD ENFORCEMENT: Snap height every frame during resize
108+
const snappedHeight = this.snapDimensionToGrid(height);
109+
node.data('style', { ...node.data('style'), height: snappedHeight });
110+
111+
// Adjust position to maintain edge alignment based on resize handle
112+
const resizeType = node.scratch('resizeType');
113+
if (resizeType && (resizeType.includes('top') || resizeType.includes('bottom'))) {
114+
const currentPos = node.position();
115+
const initialPos = node.scratch('resizeInitialPos');
116+
const initialHeight = node.scratch('height');
117+
const heightDelta = snappedHeight - initialHeight;
118+
119+
let newY = currentPos.y;
120+
if (resizeType.includes('top')) {
121+
newY = initialPos.y - heightDelta / 2;
122+
} else if (resizeType.includes('bottom')) {
123+
newY = initialPos.y + heightDelta / 2;
124+
}
125+
node.position({ x: currentPos.x, y: this.snapToGrid(newY) });
126+
}
127+
return snappedHeight;
90128
},
91129
isNoResizeMode(node) { return node.data('type') !== 'ordin'; },
92130
isNoControlsMode(node) { return node.data('type') !== 'ordin'; },
@@ -199,26 +237,36 @@ class CoreGraph {
199237

200238
this.cy.on('free', 'node[type = "ordin"]', (e) => {
201239
e.target.forEach((node) => {
240+
const initialPos = node.scratch('position');
202241
const currentPos = node.position();
203-
const snappedPos = this.snapPositionToGrid(currentPos);
204-
node.position(snappedPos);
242+
// Only snap if the node actually moved
243+
const moved = !initialPos || initialPos.x !== currentPos.x || initialPos.y !== currentPos.y;
244+
if (moved) {
245+
const snappedPos = this.snapPositionToGrid(currentPos);
246+
node.position(snappedPos);
247+
}
205248
});
206249
});
207250

208251
this.cy.on('nodeediting.resizestart', (e, type, node) => {
252+
// Store initial state for resize operation
209253
node.scratch('height', node.data('style').height);
210254
node.scratch('width', node.data('style').width);
211-
node.scratch('position', { ...node.position() });
255+
node.scratch('resizeInitialPos', { ...node.position() });
256+
node.scratch('resizeType', type);
212257
});
213258

214259
this.cy.on('nodeediting.resizeend', (e, type, node) => {
215-
// Snap dimensions to grid multiples
260+
// Clean up scratch data
261+
node.removeScratch('resizeType');
262+
node.removeScratch('resizeInitialPos');
263+
264+
// Final enforcement: ensure position and dimensions are grid-aligned
216265
const style = node.data('style') || {};
217266
const snappedWidth = this.snapDimensionToGrid(style.width || 100);
218267
const snappedHeight = this.snapDimensionToGrid(style.height || 50);
219268
node.data('style', { ...style, width: snappedWidth, height: snappedHeight });
220-
221-
// Snap position to ensure all corners align to grid
269+
222270
const snappedPos = this.snapPositionToGrid(node.position());
223271
node.position(snappedPos);
224272
});

0 commit comments

Comments
 (0)