|
159 | 159 | return { nodeOutput, nodeInput }; |
160 | 160 | } |
161 | 161 |
|
162 | | - function createWirePath(outputPort: SVGSVGElement, inputPort: SVGSVGElement, verticalOut: boolean, verticalIn: boolean, dashed: boolean): WirePath { |
| 162 | + function createWirePath(outputPort: SVGSVGElement, inputPort: SVGSVGElement, verticalOut: boolean, verticalIn: boolean, dashed: boolean, curvedNotStraight: boolean): WirePath { |
163 | 163 | const inputPortRect = inputPort.getBoundingClientRect(); |
164 | 164 | const outputPortRect = outputPort.getBoundingClientRect(); |
165 | 165 |
|
166 | | - const pathString = buildWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); |
| 166 | + const pathString = curvedNotStraight |
| 167 | + ? buildCurvedWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn) |
| 168 | + : buildStraightWirePathString(outputPortRect, inputPortRect, verticalOut, verticalIn); |
167 | 169 | const dataType = (outputPort.getAttribute("data-datatype") as FrontendGraphDataType) || "General"; |
168 | 170 | const thick = verticalIn && verticalOut; |
169 | 171 |
|
|
184 | 186 | const wireEndNode = wire.wireEnd.nodeId !== undefined ? $nodeGraph.nodes.get(wire.wireEnd.nodeId) : undefined; |
185 | 187 | const wireEnd = (wireEndNode?.isLayer && Number(wire.wireEnd.index) === 0) || false; |
186 | 188 |
|
187 | | - return [createWirePath(nodeOutput, nodeInput, wireStart, wireEnd, wire.dashed)]; |
| 189 | + return [createWirePath(nodeOutput, nodeInput, wireStart, wireEnd, wire.dashed, $nodeGraph.wiresCurvedNotStraight)]; |
188 | 190 | }); |
189 | 191 | } |
190 | 192 |
|
|
198 | 200 | return iconMap[icon] || "NodeNodes"; |
199 | 201 | } |
200 | 202 |
|
201 | | - function buildWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { |
| 203 | + function buildStraightWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { |
202 | 204 | if (!nodesContainer) return []; |
203 | 205 |
|
204 | 206 | const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; |
|
426 | 428 | return construct([x1, y1], [x20, y1], [x20, y3], [x4, y3]); |
427 | 429 | } |
428 | 430 |
|
429 | | - function buildWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { |
430 | | - const locations = buildWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); |
| 431 | + function buildStraightWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { |
| 432 | + const locations = buildStraightWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); |
431 | 433 | if (locations.length === 0) return "[error]"; |
432 | 434 | if (locations.length === 2) return `M${locations[0].x},${locations[0].y} L${locations[1].x},${locations[1].y}`; |
433 | 435 |
|
|
461 | 463 | return path; |
462 | 464 | } |
463 | 465 |
|
| 466 | + function buildCurvedWirePathLocations(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): { x: number; y: number }[] { |
| 467 | + if (!nodesContainer) return []; |
| 468 | +
|
| 469 | + const VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP = 1; |
| 470 | +
|
| 471 | + const containerBounds = nodesContainer.getBoundingClientRect(); |
| 472 | +
|
| 473 | + const outX = verticalOut ? outputBounds.x + outputBounds.width / 2 : outputBounds.x + outputBounds.width - 1; |
| 474 | + const outY = verticalOut ? outputBounds.y + VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : outputBounds.y + outputBounds.height / 2; |
| 475 | + const outConnectorX = (outX - containerBounds.x) / $nodeGraph.transform.scale; |
| 476 | + const outConnectorY = (outY - containerBounds.y) / $nodeGraph.transform.scale; |
| 477 | +
|
| 478 | + const inX = verticalIn ? inputBounds.x + inputBounds.width / 2 : inputBounds.x + 1; |
| 479 | + const inY = verticalIn ? inputBounds.y + inputBounds.height - VERTICAL_WIRE_OVERLAP_ON_SHAPED_CAP : inputBounds.y + inputBounds.height / 2; |
| 480 | + const inConnectorX = (inX - containerBounds.x) / $nodeGraph.transform.scale; |
| 481 | + const inConnectorY = (inY - containerBounds.y) / $nodeGraph.transform.scale; |
| 482 | + const horizontalGap = Math.abs(outConnectorX - inConnectorX); |
| 483 | + const verticalGap = Math.abs(outConnectorY - inConnectorY); |
| 484 | +
|
| 485 | + const curveLength = 24; |
| 486 | + const curveFalloffRate = curveLength * Math.PI * 2; |
| 487 | +
|
| 488 | + const horizontalCurveAmount = -(2 ** ((-10 * horizontalGap) / curveFalloffRate)) + 1; |
| 489 | + const verticalCurveAmount = -(2 ** ((-10 * verticalGap) / curveFalloffRate)) + 1; |
| 490 | + const horizontalCurve = horizontalCurveAmount * curveLength; |
| 491 | + const verticalCurve = verticalCurveAmount * curveLength; |
| 492 | +
|
| 493 | + return [ |
| 494 | + { x: outConnectorX, y: outConnectorY }, |
| 495 | + { x: verticalOut ? outConnectorX : outConnectorX + horizontalCurve, y: verticalOut ? outConnectorY - verticalCurve : outConnectorY }, |
| 496 | + { x: verticalIn ? inConnectorX : inConnectorX - horizontalCurve, y: verticalIn ? inConnectorY + verticalCurve : inConnectorY }, |
| 497 | + { x: inConnectorX, y: inConnectorY }, |
| 498 | + ]; |
| 499 | + } |
| 500 | +
|
| 501 | + function buildCurvedWirePathString(outputBounds: DOMRect, inputBounds: DOMRect, verticalOut: boolean, verticalIn: boolean): string { |
| 502 | + const locations = buildCurvedWirePathLocations(outputBounds, inputBounds, verticalOut, verticalIn); |
| 503 | + if (locations.length === 0) return "[error]"; |
| 504 | +
|
| 505 | + const SMOOTHING = 0.5; |
| 506 | + const delta01 = { x: (locations[1].x - locations[0].x) * SMOOTHING, y: (locations[1].y - locations[0].y) * SMOOTHING }; |
| 507 | + const delta23 = { x: (locations[3].x - locations[2].x) * SMOOTHING, y: (locations[3].y - locations[2].y) * SMOOTHING }; |
| 508 | +
|
| 509 | + return ` |
| 510 | + M${locations[0].x},${locations[0].y} |
| 511 | + L${locations[1].x},${locations[1].y} |
| 512 | + C${locations[1].x + delta01.x},${locations[1].y + delta01.y} |
| 513 | + ${locations[2].x - delta23.x},${locations[2].y - delta23.y} |
| 514 | + ${locations[2].x},${locations[2].y} |
| 515 | + L${locations[3].x},${locations[3].y} |
| 516 | + ` |
| 517 | + .split("\n") |
| 518 | + .map((line) => line.trim()) |
| 519 | + .join(" "); |
| 520 | + } |
| 521 | +
|
464 | 522 | function toggleLayerDisplay(displayAsLayer: boolean, toggleId: bigint) { |
465 | 523 | let node = $nodeGraph.nodes.get(toggleId); |
466 | 524 | if (node) editor.handle.setToNodeOrLayer(node.id, displayAsLayer); |
|
0 commit comments