Merge pull request #2 from edoardocarmignani/develop

refractor: migrate to new ComfyUI link renderer
This commit is contained in:
Edoardo Carmignani
2025-09-23 11:29:03 +02:00
committed by GitHub
8 changed files with 241 additions and 51 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
[tool.bumpversion]
current_version = "0.0.2"
current_version = "1.0.0"
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
serialize = ["{major}.{minor}.{patch}"]
search = "{current_version}"
+6
View File
@@ -23,6 +23,12 @@ body:
- Mac
validations:
required: true
- type: input
id: browser
attributes:
label: "Browser"
description: "Which browser are you using?"
placeholder: Chrome
- type: textarea
id: description
attributes:
+33
View File
@@ -0,0 +1,33 @@
# Changelog
All notable changes to this project will be documented in this file.
---
## [1.0.0] - 2025-09-20
### Changed
- Migrated from `renderLink` patch to new `drawLinkPath` patch (`ExtraLinks.js`), compatible with ComfyUI frontend ≥ 1.27.1.
- Updated link renderers to use `{x, y}` objects (`link.startPoint` / `link.endPoint`) instead of `[x, y]` arrays.
- Patched `calculateCenterPoint` to align markers with custom paths.
- Improved patching lifecycle: now waits for `app.canvas.linkRenderer.pathRenderer` before applying.
- Preserved all extension settings (Enable, Shape, Radius, Offset, Curvature).
### Breaking
- **Requires ComfyUI frontend ≥ 1.27.1.**
- ExtraLinks is no longer compatible with earlier frontend builds. Users on older ComfyUI must stay on **ExtraLinks v0.0.2**.
---
## [0.0.2] - 2025-07-15
### Added
- Initial implementation of custom link shapes (`Curved`, `Rounded`).
- Configurable Radius, Offset, and Curvature.
- Toggle Enable/Disable from settings panel.
- Basic marker rendering at link midpoints.
---
+126 -2
View File
@@ -1,8 +1,11 @@
<div align="center">
<img src="imgs/extralinks_logo.png">
</div>
</div><br>
![GitHub Tag](https://img.shields.io/github/v/tag/edoardocarmignani/extralinks?label=version)
![GitHub License](https://img.shields.io/github/license/edoardocarmignani/extralinks)
![Last Commit](https://img.shields.io/github/last-commit/edoardocarmignani/extralinks)
![Issues](https://img.shields.io/github/issues/edoardocarmignani/extralinks)
A one-click collection of alternate connection styles for ComfyUI.
@@ -16,3 +19,124 @@ A one-click collection of alternate connection styles for ComfyUI.
<div align="center">
<img width=800 src="imgs/extralinks_example.gif">
</div>
------------------------------------------------------------------
## Requirements
**ComfyUI frontend**: ≥ **1.27.1** (new link renderer API)
> On older ComfyUI versions, use ExtraLinks v0.0.2 (see Compatibility).
------------------------------------------------------------------
## Installation
### Git Clone
```powershell
cd ComfyUI\custom_nodes
git clone https://github.com/edoardocarmignani/extralinks.git
```
Restart ComfyUI (or just reload the browser tab if ComfyUI is already running).
### ComfyUI Manager
Go to **Custom Nodes Manager** and search for **Extra Links**.
------------------------------------------------------------------
## Usage
Open **Settings** → **Extra Links** and configure:
- **Enable**: toggle on/off
- **Shape**: `Curved` | `Rounded`
- **Radius**: corner smoothing
- **Offset**: horizontal separation for multi-outputs
- **Curvature**: strength of turn-in/out
Changes apply immediately to the canvas.
------------------------------------------------------------------
## Compatibility
| ExtraLinks version | ComfyUI frontend | Notes |
|--------------------|------------------|-------|
| **1.0.0+** | **≥ 1.27.1** | Uses new `drawLinkPath` API |
| 0.0.2 | < 1.27.1 | Legacy `renderLink` patch |
> Staying on an older ComfyUI? Keep using **v0.0.2** (see legacy tag/releases).
------------------------------------------------------------------
## Troubleshooting
- **Only the center dot appears**
Likely start/end were read as arrays. Ensure you’re on **v1.0.0+**; we read `{x,y}` points.
- **No lines drawn**
Check DevTools Console for warnings from ExtraLinks; verify ComfyUI is **≥ 1.27.1**.
- **After toggling Enable nothing changes**
Try reloading the page; ensure there’s no other extension overriding link rendering.
If issues persist, please open an issue with:
- ComfyUI frontend commit/date
- Browser + OS
- A screenshot / brief recording
- Console logs (copy/paste)
👉 [Open an issue](https://github.com/edoardocarmignani/extralinks/issues)
------------------------------------------------------------------
## Versioning & Releases
- **1.0.0** — Migration to new ComfyUI link renderer (**breaking**: drops < 1.27.1).
> See [`CHANGELOG`](CHANGELOG.md) for details.
Tags:
- `v1.x.y` → current series.
- `v0.0.2` → legacy (for older ComfyUI).
------------------------------------------------------------------
## Development
- Main code lives in `extralinks/web/ExtraLinks.js`
- Settings/registration live in `extralinks/web/extralinks_register.js`
- Python exposes `WEB_DIRECTORY` via `extralinks/__init__.py`
Typical flow:
```bash
# edit JS files
# reload ComfyUI browser tab
# watch console for "[Extra Links]" logs
```
Optional Runtime guard:
```javascript
const ok = app?.canvas?.linkRenderer?.pathRenderer?.drawLinkPath;
if (!ok) {
console.warn("[ExtraLinks] Requires ComfyUI frontend >= 1.27.1");
}
```
------------------------------------------------------------------
## License
MIT (see [`LICENSE`](LICENSE))
------------------------------------------------------------------
## Credits
- Built by [@edoardocarmignani](https://github.com/edoardocarmignani)
- Thanks to the ComfyUI community for the incredible work
+1 -1
View File
@@ -8,7 +8,7 @@
__author__ = 'Edoardo Carmignani'
__email__ = 'edoardo.carmignani@gmail.com'
__version__ = '0.0.2'
__version__ = '1.0.0'
WEB_DIRECTORY = './web'
+1 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "extralinks"
version = "0.0.2"
version = "1.0.0"
description = "More connection links."
authors = [
{name = "Edoardo Carmignani", email = "edoardo.carmignani@gmail.com"}
+72 -45
View File
@@ -3,10 +3,10 @@ import {app} from "../../../scripts/app.js"
const LinkRenderers = {
curved: {
draw: function(path, start, end, slot_id, outputs, radius, offset, curvature, pos) {
const x0 = start[0];
const y1 = start[1];
const x2 = end[0];
const y2 = end[1];
const x0 = start.x;
const y1 = start.y;
const x2 = end.x;
const y2 = end.y;
const dx = x2 - x0;
const dy = y2 - y1;
@@ -38,10 +38,10 @@ const LinkRenderers = {
},
rounded: {
draw: function(path, start, end, slot_id, outputs, radius, offset, curvature, pos) {
const x0 = start[0];
const y1 = start[1];
const x2 = end[0];
const y2 = end[1];
const x0 = start.x;
const y1 = start.y;
const x2 = end.x;
const y2 = end.y;
const dx = x2 - x0;
const dy = y2 - y1;
@@ -70,52 +70,79 @@ const LinkRenderers = {
};
export class ExtraLinks {
constructor() {
this.isPatched = false;
}
init() {
const RADIUS = app.extensionManager.setting.get("Extra Links.Shapes.Radius") ?? 10;
const OFFSET = app.extensionManager.setting.get("Extra Links.Shapes.Offset") ?? 25;
const CURVATURE = app.extensionManager.setting.get("Extra Links.Shapes.Curvature") ?? 5;
this.waitForCanvas().then(() => {
this.patchDrawLinkPath();
console.log("✅ Extra Links Loaded");
});
}
const _oldRenderLink = LGraphCanvas.prototype.renderLink;
async waitForCanvas() {
while (!app.canvas ||
!app.canvas.linkRenderer ||
!app.canvas.linkRenderer.pathRenderer ||
!app.canvas.linkRenderer.pathRenderer.drawLink) {
await new Promise(resolve => setTimeout(resolve, 100));
}
return true;
}
LGraphCanvas.prototype.renderLink = function renderLink(ctx, a2, b2, link2, skip_border, flow, color2, start_dir, end_dir, {
startControl,
endControl,
reroute,
num_sublines = 1,
disabled = false
} = {}) {
patchDrawLinkPath() {
const pathRenderer = app.canvas.linkRenderer.pathRenderer;
const _originalDrawLinkPath = pathRenderer.drawLinkPath;
const _originalCalculateCenterPoint = pathRenderer.calculateCenterPoint;
pathRenderer.drawLinkPath = function drawLinkPath(ctx, path, link2, context, lineWidth, color2) {
if (!app.extensionManager.setting.get("Extra Links.General.Enable")) {
LGraphCanvas.prototype.renderLink = _oldRenderLink;
pathRenderer.drawLinkPath = _originalDrawLinkPath;
pathRenderer.calculateCenterPoint = _originalCalculateCenterPoint;
return;
};
const linkColour = link2 != null && this.highlighted_links[link2.id] ? "#FFF" : color2 || link2?.color || link2?.type != null && LGraphCanvas.link_type_colors[link2.type] || this.default_link_color;
ctx.lineJoin = "round";
num_sublines ||= 1;
if (num_sublines > 1) ctx.lineWidth = 0.5;
const linkSegment = reroute ?? link2;
const path = new Path2D();
if (linkSegment) linkSegment.path = path;
const pos = linkSegment?._pos ?? [0, 0];
const outputId = link2?.origin_slot ?? 0;
const start_node = this.graph.getNodeById(link2?.origin_id);
const total_outputs = start_node?.outputs.length ?? 1;
for (let i2 = 0; i2 < num_sublines; i2++) {
LinkRenderers[app.extensionManager.setting.get("Extra Links.General.Shape")].draw(path, a2, b2, outputId, total_outputs, RADIUS, OFFSET, CURVATURE, pos);
}
ctx.lineWidth = this.connections_width;
ctx.fillStyle = ctx.strokeStyle = linkColour;
const RADIUS = app.extensionManager.setting.get("Extra Links.Shapes.Radius") ?? 10;
const OFFSET = app.extensionManager.setting.get("Extra Links.Shapes.Offset") ?? 25;
const CURVATURE = app.extensionManager.setting.get("Extra Links.Shapes.Curvature") ?? 5;
const SHAPE = app.extensionManager.setting.get("Extra Links.General.Shape") ?? "curved";
const outputId = link2?.origin_slot ?? 0;
const start_node = app.graph.getNodeById(link2?.origin_id);
const total_outputs = start_node?.outputs.length ?? 1;
const startPos = link2.startPoint;
const endPos = link2.endPoint;
ctx.lineJoin = "round";
ctx.lineWidth = lineWidth;
ctx.fillStyle = ctx.strokeStyle = color2;
const pos = [0, 0];
const renderer = LinkRenderers[SHAPE] || LinkRenderers.curved;
renderer.draw(
path,
startPos,
endPos,
outputId,
total_outputs,
RADIUS,
OFFSET,
CURVATURE,
pos
);
ctx.stroke(path);
ctx.beginPath()
ctx.arc(pos[0], pos[1], 5, 0, Math.PI * 2);
ctx.fill();
pathRenderer.calculateCenterPoint = (...args) => {
return link2.centerPos = {x: pos[0], y: pos[1]}
}
}
}
};
};
+1 -1
View File
@@ -47,7 +47,7 @@ app.registerExtension({
},
{
id: "Extra Links.ExtraLinks",
name: "Version 0.0.2",
name: "Version 1.0.0",
type: () => {
const container = document.createElement("span");
const btn = document.createElement("button");