Skip to content

Commit d76c59c

Browse files
christian-byrnegithub-actions
andauthored
[refactor] Simplify Vue node resize to bottom-right corner only (#7063)
## Summary Temporarily simplifies the resize logic to only work on bottom right corner and eliminates edge cases where corner resizing caused position drift issues. - Remove multi-corner resize handles in favor of bottom-right only - Delete resizeMath.ts and its tests (no longer needed) - Simplify useNodeResize to only handle bottom-right resize - Remove position tracking from resize callback --------- Co-authored-by: github-actions <[email protected]>
1 parent c298d8a commit d76c59c

File tree

6 files changed

+35
-301
lines changed

6 files changed

+35
-301
lines changed
-752 Bytes
Loading
-904 Bytes
Loading

src/renderer/extensions/vueNodes/components/LGraphNode.vue

Lines changed: 12 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,14 @@
117117
</div>
118118
</template>
119119

120-
<!-- Resize handles -->
121-
<template v-if="!isCollapsed">
122-
<div
123-
v-for="handle in cornerResizeHandles"
124-
:key="handle.id"
125-
role="button"
126-
:aria-label="handle.ariaLabel"
127-
:class="cn(baseResizeHandleClasses, handle.classes)"
128-
@pointerdown.stop="handleResizePointerDown(handle.direction)($event)"
129-
/>
130-
</template>
120+
<!-- Resize handle (bottom-right only) -->
121+
<div
122+
v-if="!isCollapsed"
123+
role="button"
124+
:aria-label="t('g.resizeFromBottomRight')"
125+
:class="cn(baseResizeHandleClasses, 'right-0 bottom-0 cursor-se-resize')"
126+
@pointerdown.stop="handleResizePointerDown"
127+
/>
131128
</div>
132129
</template>
133130

@@ -171,7 +168,6 @@ import {
171168
} from '@/utils/graphTraversalUtil'
172169
import { cn } from '@/utils/tailwindUtil'
173170
174-
import type { ResizeHandleDirection } from '../interactions/resize/resizeMath'
175171
import { useNodeResize } from '../interactions/resize/useNodeResize'
176172
import LivePreview from './LivePreview.vue'
177173
import NodeContent from './NodeContent.vue'
@@ -263,7 +259,7 @@ onErrorCaptured((error) => {
263259
return false // Prevent error propagation
264260
})
265261
266-
const { position, size, zIndex, moveNodeTo } = useNodeLayout(() => nodeData.id)
262+
const { position, size, zIndex } = useNodeLayout(() => nodeData.id)
267263
const { pointerHandlers } = useNodePointerInteractions(() => nodeData.id)
268264
const { onPointerdown, ...remainingPointerHandlers } = pointerHandlers
269265
const { startDrag } = useNodeDrag()
@@ -314,41 +310,6 @@ onMounted(() => {
314310
315311
const baseResizeHandleClasses =
316312
'absolute h-3 w-3 opacity-0 pointer-events-auto focus-visible:outline focus-visible:outline-2 focus-visible:outline-white/40'
317-
const POSITION_EPSILON = 0.01
318-
319-
type CornerResizeHandle = {
320-
id: string
321-
direction: ResizeHandleDirection
322-
classes: string
323-
ariaLabel: string
324-
}
325-
326-
const cornerResizeHandles: CornerResizeHandle[] = [
327-
{
328-
id: 'se',
329-
direction: { horizontal: 'right', vertical: 'bottom' },
330-
classes: 'right-0 bottom-0 cursor-se-resize',
331-
ariaLabel: t('g.resizeFromBottomRight')
332-
},
333-
{
334-
id: 'ne',
335-
direction: { horizontal: 'right', vertical: 'top' },
336-
classes: 'right-0 top-0 cursor-ne-resize',
337-
ariaLabel: t('g.resizeFromTopRight')
338-
},
339-
{
340-
id: 'sw',
341-
direction: { horizontal: 'left', vertical: 'bottom' },
342-
classes: 'left-0 bottom-0 cursor-sw-resize',
343-
ariaLabel: t('g.resizeFromBottomLeft')
344-
},
345-
{
346-
id: 'nw',
347-
direction: { horizontal: 'left', vertical: 'top' },
348-
classes: 'left-0 top-0 cursor-nw-resize',
349-
ariaLabel: t('g.resizeFromTopLeft')
350-
}
351-
]
352313
353314
const MIN_NODE_WIDTH = 225
354315
@@ -361,22 +322,11 @@ const { startResize } = useNodeResize((result, element) => {
361322
// Apply size directly to DOM element - ResizeObserver will pick this up
362323
element.style.setProperty('--node-width', `${clampedWidth}px`)
363324
element.style.setProperty('--node-height', `${result.size.height}px`)
364-
365-
const currentPosition = position.value
366-
const deltaX = Math.abs(result.position.x - currentPosition.x)
367-
const deltaY = Math.abs(result.position.y - currentPosition.y)
368-
369-
if (deltaX > POSITION_EPSILON || deltaY > POSITION_EPSILON) {
370-
moveNodeTo(result.position)
371-
}
372325
})
373326
374-
const handleResizePointerDown = (direction: ResizeHandleDirection) => {
375-
return (event: PointerEvent) => {
376-
if (nodeData.flags?.pinned) return
377-
378-
startResize(event, direction, { ...position.value })
379-
}
327+
const handleResizePointerDown = (event: PointerEvent) => {
328+
if (nodeData.flags?.pinned) return
329+
startResize(event)
380330
}
381331
382332
watch(isCollapsed, (collapsed) => {

src/renderer/extensions/vueNodes/interactions/resize/resizeMath.ts

Lines changed: 0 additions & 104 deletions
This file was deleted.

src/renderer/extensions/vueNodes/interactions/resize/useNodeResize.ts

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,14 @@ import { ref } from 'vue'
44
import type { Point, Size } from '@/renderer/core/layout/types'
55
import { useNodeSnap } from '@/renderer/extensions/vueNodes/composables/useNodeSnap'
66
import { useShiftKeySync } from '@/renderer/extensions/vueNodes/composables/useShiftKeySync'
7-
8-
import type { ResizeHandleDirection } from './resizeMath'
9-
import { createResizeSession, toCanvasDelta } from './resizeMath'
107
import { useTransformState } from '@/renderer/core/layout/transform/useTransformState'
118

129
interface ResizeCallbackPayload {
1310
size: Size
14-
position: Point
1511
}
1612

1713
/**
18-
* Composable for node resizing functionality
14+
* Composable for node resizing functionality (bottom-right corner only)
1915
*
2016
* Provides resize handle interaction that integrates with the layout system.
2117
* Handles pointer capture, coordinate calculations, and size constraints.
@@ -27,28 +23,15 @@ export function useNodeResize(
2723

2824
const isResizing = ref(false)
2925
const resizeStartPointer = ref<Point | null>(null)
30-
const resizeSession = ref<
31-
| ((
32-
delta: Point,
33-
snapFn?: (size: Size) => Size
34-
) => {
35-
size: Size
36-
position: Point
37-
})
38-
| null
39-
>(null)
26+
const resizeStartSize = ref<Size | null>(null)
4027

4128
// Snap-to-grid functionality
4229
const { shouldSnap, applySnapToSize } = useNodeSnap()
4330

4431
// Shift key sync for LiteGraph canvas preview
4532
const { trackShiftKey } = useShiftKeySync()
4633

47-
const startResize = (
48-
event: PointerEvent,
49-
handle: ResizeHandleDirection,
50-
startPosition: Point
51-
) => {
34+
const startResize = (event: PointerEvent) => {
5235
event.preventDefault()
5336
event.stopPropagation()
5437

@@ -74,45 +57,44 @@ export function useNodeResize(
7457

7558
isResizing.value = true
7659
resizeStartPointer.value = { x: event.clientX, y: event.clientY }
77-
resizeSession.value = createResizeSession({
78-
startSize,
79-
startPosition: { ...startPosition },
80-
handle
81-
})
60+
resizeStartSize.value = startSize
8261

8362
const handlePointerMove = (moveEvent: PointerEvent) => {
8463
if (
8564
!isResizing.value ||
8665
!resizeStartPointer.value ||
87-
!resizeSession.value
88-
)
66+
!resizeStartSize.value
67+
) {
8968
return
69+
}
70+
71+
const scale = transformState.camera.z
72+
const deltaX =
73+
(moveEvent.clientX - resizeStartPointer.value.x) / (scale || 1)
74+
const deltaY =
75+
(moveEvent.clientY - resizeStartPointer.value.y) / (scale || 1)
9076

91-
const startPointer = resizeStartPointer.value
92-
const session = resizeSession.value
77+
let newSize: Size = {
78+
width: resizeStartSize.value.width + deltaX,
79+
height: resizeStartSize.value.height + deltaY
80+
}
9381

94-
const delta = toCanvasDelta(
95-
startPointer,
96-
{ x: moveEvent.clientX, y: moveEvent.clientY },
97-
transformState.camera.z
98-
)
82+
// Apply snap if shift is held
83+
if (shouldSnap(moveEvent)) {
84+
newSize = applySnapToSize(newSize)
85+
}
9986

10087
const nodeElement = target.closest('[data-node-id]')
10188
if (nodeElement instanceof HTMLElement) {
102-
const outcome = session(
103-
delta,
104-
shouldSnap(moveEvent) ? applySnapToSize : undefined
105-
)
106-
107-
resizeCallback(outcome, nodeElement)
89+
resizeCallback({ size: newSize }, nodeElement)
10890
}
10991
}
11092

11193
const handlePointerUp = (upEvent: PointerEvent) => {
11294
if (isResizing.value) {
11395
isResizing.value = false
11496
resizeStartPointer.value = null
115-
resizeSession.value = null
97+
resizeStartSize.value = null
11698

11799
// Stop tracking shift key state
118100
stopShiftSync()

0 commit comments

Comments
 (0)