diff --git a/.bumpversion.toml b/.bumpversion.toml index d40e925..b0820d0 100644 --- a/.bumpversion.toml +++ b/.bumpversion.toml @@ -1,5 +1,5 @@ [tool.bumpversion] -current_version = "0.0.2" +current_version = "1.0.0" parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)" serialize = ["{major}.{minor}.{patch}"] search = "{current_version}" diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml index 4cf3b6e..e00e20d 100644 --- a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml @@ -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: diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..482ec81 --- /dev/null +++ b/CHANGELOG.md @@ -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. + +--- diff --git a/README.md b/README.md index 7b12ce7..588993c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@
-
- +
+![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.
+ +------------------------------------------------------------------ + +## 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 diff --git a/__init__.py b/__init__.py index df2057b..484ccd3 100644 --- a/__init__.py +++ b/__init__.py @@ -8,7 +8,7 @@ __author__ = 'Edoardo Carmignani' __email__ = 'edoardo.carmignani@gmail.com' -__version__ = '0.0.2' +__version__ = '1.0.0' WEB_DIRECTORY = './web' diff --git a/pyproject.toml b/pyproject.toml index b65220b..559ffe5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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"} diff --git a/web/js/ExtraLinks.js b/web/js/ExtraLinks.js index e323cef..76543ac 100644 --- a/web/js/ExtraLinks.js +++ b/web/js/ExtraLinks.js @@ -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]} + } } } -}; - - +}; \ No newline at end of file diff --git a/web/js/extralinks_register.js b/web/js/extralinks_register.js index d5447a8..1a43320 100644 --- a/web/js/extralinks_register.js +++ b/web/js/extralinks_register.js @@ -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");