diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts index 86c3c14c2..cbb644cbf 100644 --- a/src/lib/litegraph/src/LGraphCanvas.ts +++ b/src/lib/litegraph/src/LGraphCanvas.ts @@ -8,7 +8,6 @@ import { LGraphGroup } from './LGraphGroup' import { LGraphNode, type NodeId, type NodeProperty } from './LGraphNode' import { LLink, type LinkId } from './LLink' import { Reroute, type RerouteId } from './Reroute' -import { RenderedLinkSegment } from './canvas/RenderedLinkSegment' import { isOverNodeInput, isOverNodeOutput } from './canvas/measureSlots' import { strokeShape } from './draw' import type { @@ -5471,6 +5470,7 @@ export class LGraphCanvas const endPos = node.getInputPos(link.target_slot) const endDirection = node.inputs[link.target_slot]?.dir + firstReroute._dragging = true this.#renderAllLinkSegments( ctx, link, @@ -5490,6 +5490,7 @@ export class LGraphCanvas const endPos = reroute.pos const startDirection = node.outputs[link.origin_slot]?.dir + link._dragging = true this.#renderAllLinkSegments( ctx, link, @@ -5549,10 +5550,6 @@ export class LGraphCanvas // Has reroutes if (reroutes.length) { - const lastReroute = reroutes[reroutes.length - 1] - const floatingType = lastReroute?.floating?.slotType - const skipFirstSegment = floatingType === 'input' - const skipLastSegment = floatingType === 'output' let startControl: Point | undefined const l = reroutes.length @@ -5561,6 +5558,7 @@ export class LGraphCanvas // Only render once if (!renderedPaths.has(reroute)) { + renderedPaths.add(reroute) visibleReroutes.push(reroute) reroute._colour = link.color || @@ -5569,16 +5567,10 @@ export class LGraphCanvas const prevReroute = graph.getReroute(reroute.parentId) const rerouteStartPos = prevReroute?.pos ?? startPos - const params = reroute.computeRenderParams(graph, rerouteStartPos) + reroute.calculateAngle(this.last_draw_time, graph, rerouteStartPos) // Skip the first segment if it is being dragged - if (!(skipFirstSegment && j === 0)) { - const rendered = new RenderedLinkSegment({ - id: reroute.id, - origin_id: link.origin_id, - origin_slot: link.origin_slot, - parentId: reroute.parentId - }) + if (!reroute._dragging) { this.renderLink( ctx, rerouteStartPos, @@ -5591,45 +5583,35 @@ export class LGraphCanvas LinkDirection.CENTER, { startControl, - endControl: params.controlPoint, - disabled, - renderTarget: rendered + endControl: reroute.controlPoint, + reroute, + disabled } ) - renderedPaths.add(rendered) } } - if (!startControl && skipFirstSegment) { + if (!startControl && reroutes.at(-1)?.floating?.slotType === 'input') { // Floating link connected to an input startControl = [0, 0] } else { // Calculate start control for the next iter control point const nextPos = reroutes[j + 1]?.pos ?? endPos - const prevR = graph.getReroute(reroute.parentId) - const startPosForParams = prevR?.pos ?? startPos - const params = reroute.computeRenderParams(graph, startPosForParams) const dist = Math.min( Reroute.maxSplineOffset, distance(reroute.pos, nextPos) * 0.25 ) - startControl = [dist * params.cos, dist * params.sin] + startControl = [dist * reroute.cos, dist * reroute.sin] } } - // For floating links from output, skip the last segment - if (skipLastSegment) return + // Skip the last segment if it is being dragged + if (link._dragging) return // Use runtime fallback; TypeScript cannot evaluate this correctly. const segmentStartPos = points.at(-2) ?? startPos // Render final link segment - const rendered = new RenderedLinkSegment({ - id: link.id, - origin_id: link.origin_id, - origin_slot: link.origin_slot, - parentId: link.parentId - }) this.renderLink( ctx, segmentStartPos, @@ -5640,17 +5622,10 @@ export class LGraphCanvas null, LinkDirection.CENTER, end_dir, - { startControl, disabled, renderTarget: rendered } + { startControl, disabled } ) - renderedPaths.add(rendered) // Skip normal render when link is being dragged } else if (!link._dragging) { - const rendered = new RenderedLinkSegment({ - id: link.id, - origin_id: link.origin_id, - origin_slot: link.origin_slot, - parentId: link.parentId - }) this.renderLink( ctx, startPos, @@ -5660,11 +5635,10 @@ export class LGraphCanvas 0, null, start_dir, - end_dir, - { renderTarget: rendered } + end_dir ) - renderedPaths.add(rendered) } + renderedPaths.add(link) // event triggered rendered on top if (link?._last_time && now - link._last_time < 1000) { @@ -5713,8 +5687,7 @@ export class LGraphCanvas endControl, reroute, num_sublines = 1, - disabled = false, - renderTarget + disabled = false }: { /** When defined, render data will be saved to this reroute instead of the {@link link}. */ reroute?: Reroute @@ -5726,8 +5699,6 @@ export class LGraphCanvas num_sublines?: number /** Whether this is a floating link segment */ disabled?: boolean - /** Where to store the drawn path for hit testing if not using a reroute */ - renderTarget?: RenderedLinkSegment } = {} ): void { const linkColour = @@ -5758,13 +5729,13 @@ export class LGraphCanvas const path = new Path2D() /** The link or reroute we're currently rendering */ - const linkSegment = reroute ?? renderTarget + const linkSegment = reroute ?? link if (linkSegment) linkSegment.path = path const innerA = LGraphCanvas.#lTempA const innerB = LGraphCanvas.#lTempB - /** Reference to render-time centre point of this segment. */ + /** Reference to {@link reroute._pos} if present, or {@link link._pos} if present. Caches the centre point of the link. */ const pos: Point = linkSegment?._pos ?? [0, 0] for (let i = 0; i < num_sublines; i++) { diff --git a/src/lib/litegraph/src/Reroute.ts b/src/lib/litegraph/src/Reroute.ts index d462e620f..886930227 100644 --- a/src/lib/litegraph/src/Reroute.ts +++ b/src/lib/litegraph/src/Reroute.ts @@ -537,66 +537,6 @@ export class Reroute } } - /** - * Computes render-time parameters for this reroute without mutating the model. - * Returns the bezier end control-point offset and the direction cos/sin. - */ - computeRenderParams( - network: ReadonlyLinkNetwork, - linkStart: Point - ): { cos: number; sin: number; controlPoint: Point } { - const thisPos = this.#pos - const angles: number[] = [] - let sum = 0 - - // Collect angles of all links passing through this reroute - addAngles(this.linkIds, network.links) - addAngles(this.floatingLinkIds, network.floatingLinks) - - // Default values when invalid - if (!angles.length) { - return { cos: 0, sin: 0, controlPoint: [0, 0] } - } - - sum /= angles.length - - const originToReroute = Math.atan2( - thisPos[1] - linkStart[1], - thisPos[0] - linkStart[0] - ) - let diff = (originToReroute - sum) * 0.5 - if (Math.abs(diff) > Math.PI * 0.5) diff += Math.PI - const dist = Math.min( - Reroute.maxSplineOffset, - distance(linkStart, thisPos) * 0.25 - ) - - const originDiff = originToReroute - diff - const cos = Math.cos(originDiff) - const sin = Math.sin(originDiff) - const controlPoint: Point = [dist * -cos, dist * -sin] - - return { cos, sin, controlPoint } - - function addAngles( - linkIds: Iterable, - links: ReadonlyMap - ) { - for (const linkId of linkIds) { - const link = links.get(linkId) - const pos = getNextPos(network, link, thisObj.id) - if (!pos) continue - const angle = getDirection(thisPos, pos) - angles.push(angle) - sum += angle - } - } - - // Preserve lexical `this` values inside helper - // eslint-disable-next-line @typescript-eslint/no-this-alias - const thisObj = this - } - /** * Renders the reroute on the canvas. * @param ctx Canvas context to draw on diff --git a/src/lib/litegraph/src/canvas/RenderedLinkSegment.ts b/src/lib/litegraph/src/canvas/RenderedLinkSegment.ts deleted file mode 100644 index 753231488..000000000 --- a/src/lib/litegraph/src/canvas/RenderedLinkSegment.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { NodeId } from '@/lib/litegraph/src/LGraphNode' -import type { LinkId } from '@/lib/litegraph/src/LLink' -import type { RerouteId } from '@/lib/litegraph/src/Reroute' -import type { LinkSegment } from '@/lib/litegraph/src/interfaces' - -/** - * Lightweight, render-only representation of a link segment used for hit testing and tooltips. - * Decouples canvas state from the LLink data model. - */ -export class RenderedLinkSegment implements LinkSegment { - readonly id: LinkId | RerouteId - readonly origin_id: NodeId - readonly origin_slot: number - readonly parentId?: RerouteId - - path?: Path2D - readonly _pos: Float32Array = new Float32Array(2) - _centreAngle?: number - _dragging?: boolean - - constructor(args: { - id: LinkId | RerouteId - origin_id: NodeId - origin_slot: number - parentId?: RerouteId - }) { - this.id = args.id - this.origin_id = args.origin_id - this.origin_slot = args.origin_slot - this.parentId = args.parentId - } -}