Merge pull request #2 from edoardocarmignani/develop
refractor: migrate to new ComfyUI link renderer
This commit is contained in:
+1
-1
@@ -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}"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
---
|
||||
@@ -1,8 +1,11 @@
|
||||
<div align="center">
|
||||
<img src="imgs/extralinks_logo.png">
|
||||
</div>
|
||||
|
||||
</div><br>
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
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
@@ -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
@@ -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
@@ -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]}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user