diff --git a/browser_tests/tests/viewport.spec.ts-snapshots/viewport-fits-when-saved-offscreen-chromium-linux.png b/browser_tests/tests/viewport.spec.ts-snapshots/viewport-fits-when-saved-offscreen-chromium-linux.png
index f6ac2afd0..cbbdab631 100644
Binary files a/browser_tests/tests/viewport.spec.ts-snapshots/viewport-fits-when-saved-offscreen-chromium-linux.png and b/browser_tests/tests/viewport.spec.ts-snapshots/viewport-fits-when-saved-offscreen-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png
index 6f9da202b..63a7665fe 100644
Binary files a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png and b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png
index 503618abd..31502cf37 100644
Binary files a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png and b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png b/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png
index 6a98eafc4..f965a5bbf 100644
Binary files a/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png and b/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png
index 47dfca47b..584e0c3b3 100644
Binary files a/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png
index 3374a86a4..483251f59 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png
index 2cf7fe9de..21afb2c03 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png
index 3cde4d5a8..6b236bd60 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png
index 0cccea1b4..eb05d40fc 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png
index d70462889..4dfd064c9 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png
index 51e805054..9c5874347 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png
index e0f85f133..47282cee6 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png
index 4981d113c..d3ad77b7b 100644
Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png
index bbf212657..d7508564c 100644
Binary files a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png and b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png differ
diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png
index ec5c0a6a3..62c59f12c 100644
Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png differ
diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png
index 514d42eec..cf9fbba14 100644
Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png differ
diff --git a/src/components/graph/GraphCanvas.vue b/src/components/graph/GraphCanvas.vue
index 27c038076..aad7d6f24 100644
--- a/src/components/graph/GraphCanvas.vue
+++ b/src/components/graph/GraphCanvas.vue
@@ -76,6 +76,13 @@
/>
+
+
@@ -111,6 +118,7 @@ import BottomPanel from '@/components/bottomPanel/BottomPanel.vue'
import ExtensionSlot from '@/components/common/ExtensionSlot.vue'
import DomWidgets from '@/components/graph/DomWidgets.vue'
import GraphCanvasMenu from '@/components/graph/GraphCanvasMenu.vue'
+import LinkOverlayCanvas from '@/components/graph/LinkOverlayCanvas.vue'
import NodeTooltip from '@/components/graph/NodeTooltip.vue'
import SelectionToolbox from '@/components/graph/SelectionToolbox.vue'
import TitleEditor from '@/components/graph/TitleEditor.vue'
@@ -241,6 +249,18 @@ const allNodes = computed((): VueNodeData[] =>
Array.from(vueNodeLifecycle.nodeManager.value?.vueNodeData?.values() ?? [])
)
+function onLinkOverlayReady(el: HTMLCanvasElement) {
+ if (!canvasStore.canvas) return
+ canvasStore.canvas.overlayCanvas = el
+ canvasStore.canvas.overlayCtx = el.getContext('2d')
+}
+
+function onLinkOverlayDispose() {
+ if (!canvasStore.canvas) return
+ canvasStore.canvas.overlayCanvas = null
+ canvasStore.canvas.overlayCtx = null
+}
+
watchEffect(() => {
LiteGraph.nodeOpacity = settingStore.get('Comfy.Node.Opacity')
})
diff --git a/src/components/graph/LinkOverlayCanvas.vue b/src/components/graph/LinkOverlayCanvas.vue
new file mode 100644
index 000000000..a29726b25
--- /dev/null
+++ b/src/components/graph/LinkOverlayCanvas.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts
index e131d877b..130a27809 100644
--- a/src/lib/litegraph/src/LGraphCanvas.ts
+++ b/src/lib/litegraph/src/LGraphCanvas.ts
@@ -688,6 +688,8 @@ export class LGraphCanvas implements CustomEventDispatcher
canvas: HTMLCanvasElement & ICustomEventTarget
bgcanvas: HTMLCanvasElement
+ overlayCanvas: HTMLCanvasElement | null = null
+ overlayCtx: CanvasRenderingContext2D | null = null
ctx: CanvasRenderingContext2D
_events_binded?: boolean
_mousedown_callback?(e: PointerEvent): void
@@ -4849,7 +4851,7 @@ export class LGraphCanvas implements CustomEventDispatcher
drawFrontCanvas(): void {
this.dirty_canvas = false
- const { ctx, canvas, graph, linkConnector } = this
+ const { ctx, canvas, graph } = this
// @ts-expect-error start2D method not in standard CanvasRenderingContext2D
if (ctx.start2D && !this.viewport) {
@@ -4949,78 +4951,14 @@ export class LGraphCanvas implements CustomEventDispatcher
this.drawConnections(ctx)
}
- if (linkConnector.isConnecting) {
- // current connection (the one being dragged by the mouse)
- const { renderLinks } = linkConnector
- const highlightPos = this._getHighlightPosition()
- ctx.lineWidth = this.connections_width
-
- for (const renderLink of renderLinks) {
- const {
- fromSlot,
- fromPos: pos,
- fromDirection,
- dragDirection
- } = renderLink
- const connShape = fromSlot.shape
- const connType = fromSlot.type
-
- const colour = resolveConnectingLinkColor(connType)
-
- // the connection being dragged by the mouse
- if (this.linkRenderer) {
- this.linkRenderer.renderDraggingLink(
- ctx,
- pos,
- highlightPos,
- colour,
- fromDirection,
- dragDirection,
- {
- ...this.buildLinkRenderContext(),
- linkMarkerShape: LinkMarkerShape.None
- }
- )
- }
-
- ctx.fillStyle = colour
- ctx.beginPath()
- if (connType === LiteGraph.EVENT || connShape === RenderShape.BOX) {
- ctx.rect(pos[0] - 6 + 0.5, pos[1] - 5 + 0.5, 14, 10)
- ctx.rect(
- highlightPos[0] - 6 + 0.5,
- highlightPos[1] - 5 + 0.5,
- 14,
- 10
- )
- } else if (connShape === RenderShape.ARROW) {
- ctx.moveTo(pos[0] + 8, pos[1] + 0.5)
- ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5)
- ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5)
- ctx.closePath()
- } else {
- ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2)
- ctx.arc(highlightPos[0], highlightPos[1], 4, 0, Math.PI * 2)
- }
- ctx.fill()
- }
-
- // Gradient half-border over target node
- this._renderSnapHighlight(ctx, highlightPos)
- }
-
- // on top of link center
- if (
- !this.isDragging &&
- this.over_link_center &&
- this.render_link_tooltip
- ) {
- this.drawLinkTooltip(ctx, this.over_link_center)
+ if (!LiteGraph.vueNodesMode || !this.overlayCtx) {
+ this._drawConnectingLinks(ctx)
} else {
- this.onDrawLinkTooltip?.(ctx, null)
+ this._drawOverlayLinks()
}
- // custom info
+ this._drawLinkTooltip(ctx)
+
this.onDrawForeground?.(ctx, this.visible_area)
ctx.restore()
@@ -5031,9 +4969,7 @@ export class LGraphCanvas implements CustomEventDispatcher
if (area) ctx.restore()
}
- /** @returns If the pointer is over a link centre marker, the link segment it belongs to. Otherwise, `undefined`. */
private _getLinkCentreOnPos(e: CanvasPointerEvent): LinkSegment | undefined {
- // Skip hit detection if center markers are disabled
if (this.linkMarkerShape === LinkMarkerShape.None) {
return undefined
}
@@ -5050,6 +4986,90 @@ export class LGraphCanvas implements CustomEventDispatcher
}
}
+ private _drawConnectingLinks(ctx: CanvasRenderingContext2D): void {
+ const { linkConnector } = this
+ if (!linkConnector.isConnecting) return
+
+ const { renderLinks } = linkConnector
+ const highlightPos = this._getHighlightPosition()
+ ctx.lineWidth = this.connections_width
+
+ for (const renderLink of renderLinks) {
+ const {
+ fromSlot,
+ fromPos: pos,
+ fromDirection,
+ dragDirection
+ } = renderLink
+ const connShape = fromSlot.shape
+ const connType = fromSlot.type
+
+ const colour = resolveConnectingLinkColor(connType)
+
+ if (this.linkRenderer) {
+ this.linkRenderer.renderDraggingLink(
+ ctx,
+ pos,
+ highlightPos,
+ colour,
+ fromDirection,
+ dragDirection,
+ {
+ ...this.buildLinkRenderContext(),
+ linkMarkerShape: LinkMarkerShape.None
+ }
+ )
+ }
+
+ ctx.fillStyle = colour
+ ctx.beginPath()
+ if (connType === LiteGraph.EVENT || connShape === RenderShape.BOX) {
+ ctx.rect(pos[0] - 6 + 0.5, pos[1] - 5 + 0.5, 14, 10)
+ ctx.rect(highlightPos[0] - 6 + 0.5, highlightPos[1] - 5 + 0.5, 14, 10)
+ } else if (connShape === RenderShape.ARROW) {
+ ctx.moveTo(pos[0] + 8, pos[1] + 0.5)
+ ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5)
+ ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5)
+ ctx.closePath()
+ } else {
+ ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2)
+ ctx.arc(highlightPos[0], highlightPos[1], 4, 0, Math.PI * 2)
+ }
+ ctx.fill()
+ }
+
+ this._renderSnapHighlight(ctx, highlightPos)
+ }
+
+ private _drawLinkTooltip(ctx: CanvasRenderingContext2D): void {
+ if (!this.isDragging && this.over_link_center && this.render_link_tooltip) {
+ this.drawLinkTooltip(ctx, this.over_link_center)
+ } else {
+ this.onDrawLinkTooltip?.(ctx, null)
+ }
+ }
+
+ private _drawOverlayLinks(): void {
+ const octx = this.overlayCtx
+ const overlayCanvas = this.overlayCanvas
+ if (!octx || !overlayCanvas) return
+
+ octx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height)
+
+ if (!this.linkConnector.isConnecting) return
+
+ octx.save()
+
+ const scale = window.devicePixelRatio
+ octx.setTransform(scale, 0, 0, scale, 0, 0)
+
+ this.ds.toCanvasContext(octx)
+
+ this._drawConnectingLinks(octx)
+
+ octx.restore()
+ }
+
/** Get the target snap / highlight point in graph space */
private _getHighlightPosition(): Readonly {
return LiteGraph.snaps_for_comfy