From fab957d1423654339278ec625360715f5dd763d4 Mon Sep 17 00:00:00 2001 From: soojy <70171585+soojy@users.noreply.github.com> Date: Fri, 11 Sep 2026 18:17:11 +0300 Subject: [PATCH] Fix HALO border continuity at rounded corners --- MANIFEST.json | 34 +++++++++---------- ...influencer_resolution.bc3ad563c6f25c80.js} | 2 +- ...encer_resolution_2k4k.ea179b0b1378b742.js} | 2 +- ...2f9bb.js => easy_crop.c762cd2c08bdd021.js} | 2 +- ...e57f7.mjs => gallery.e3606d29cf52db7a.mjs} | 2 +- ...43393cf3.mjs => halo.84c0c1fe41e5e23f.mjs} | 23 +++++++++++-- ....js => halo_execution.61efa407f380b6aa.js} | 2 +- ...s => halo_resolution.a80ef8d6675f57d8.mjs} | 2 +- ...s => image_collection.b0499872483ab4a6.js} | 4 +-- ...js => prompt_director.142e8c2b440b899f.js} | 2 +- ...solution_control_deck.65456abfe9733be0.js} | 2 +- 11 files changed, 47 insertions(+), 30 deletions(-) rename web/{ai_influencer_resolution.1a837209ce36c3ee.js => ai_influencer_resolution.bc3ad563c6f25c80.js} (99%) rename web/{ai_influencer_resolution_2k4k.fc69d433ef01a504.js => ai_influencer_resolution_2k4k.ea179b0b1378b742.js} (99%) rename web/{easy_crop.b8510f8ee542f9bb.js => easy_crop.c762cd2c08bdd021.js} (99%) rename web/{gallery.af177ab78d3e57f7.mjs => gallery.e3606d29cf52db7a.mjs} (99%) rename web/{halo.b73e64ce43393cf3.mjs => halo.84c0c1fe41e5e23f.mjs} (98%) rename web/{halo_execution.09d34f450026959a.js => halo_execution.61efa407f380b6aa.js} (89%) rename web/{halo_resolution.59e0855f43e3060a.mjs => halo_resolution.a80ef8d6675f57d8.mjs} (99%) rename web/{image_collection.115703a311f28a75.js => image_collection.b0499872483ab4a6.js} (98%) rename web/{prompt_director.c5c84298ff159d35.js => prompt_director.142e8c2b440b899f.js} (99%) rename web/{resolution_control_deck.b30eddd3c7057a66.js => resolution_control_deck.65456abfe9733be0.js} (99%) diff --git a/MANIFEST.json b/MANIFEST.json index b252115..172656d 100644 --- a/MANIFEST.json +++ b/MANIFEST.json @@ -157,13 +157,13 @@ }, "display_name": "MATRIX LAB NODES", "frontend_entrypoints": [ - "web/ai_influencer_resolution.1a837209ce36c3ee.js", - "web/ai_influencer_resolution_2k4k.fc69d433ef01a504.js", - "web/easy_crop.b8510f8ee542f9bb.js", - "web/halo_execution.09d34f450026959a.js", - "web/image_collection.115703a311f28a75.js", - "web/prompt_director.c5c84298ff159d35.js", - "web/resolution_control_deck.b30eddd3c7057a66.js" + "web/ai_influencer_resolution.bc3ad563c6f25c80.js", + "web/ai_influencer_resolution_2k4k.ea179b0b1378b742.js", + "web/easy_crop.c762cd2c08bdd021.js", + "web/halo_execution.61efa407f380b6aa.js", + "web/image_collection.b0499872483ab4a6.js", + "web/prompt_director.142e8c2b440b899f.js", + "web/resolution_control_deck.65456abfe9733be0.js" ], "nodes": [ "MATRIXLAB_AIInfluencerResolution2K4K", @@ -234,19 +234,19 @@ "builder_sha256": "d39e689b06be7b2491809b464536c3f5f95c4a619ea2c93287b96525bd225305", "backend_policy": "Baseline runtime is preserved except for removal of Camera Look and Renoise implementations and registrations.", "frontend_assets": { - "web/ai_influencer_resolution.1a837209ce36c3ee.js": "1a837209ce36c3eeae2422e5dba9a0ac557b619c5f8421e69b26a9a7af68ae23", - "web/ai_influencer_resolution_2k4k.fc69d433ef01a504.js": "fc69d433ef01a5049691ba24528964270ad94f7e67b423aeeff9520faf0e96bb", + "web/ai_influencer_resolution.bc3ad563c6f25c80.js": "bc3ad563c6f25c80321e237c6125eb186054056b3a97f167f6085ee9fabaaa56", + "web/ai_influencer_resolution_2k4k.ea179b0b1378b742.js": "ea179b0b1378b742898942a800cc75d950f86aa6b3010e107939a9fc70424c64", "web/assets/CascadiaMono-LICENSE.txt": "51882cd3cdba4e16f220f44ddb08a635c38c44ea6e0975db2574f4be6f958238", "web/assets/CascadiaMono.woff2": "7d4986a68fbbd674c90cdd8cd5d4a28c698640d3472572b006d2978006049799", "web/assets/font-manifest.json": "60aa2ed87cce68373e4087805493dedafdfeb8715670cc4c64f594ab28401810", - "web/easy_crop.b8510f8ee542f9bb.js": "b8510f8ee542f9bb0b6b577fdd8a06399ac01196cded98d48f8c070d943302a2", - "web/gallery.af177ab78d3e57f7.mjs": "af177ab78d3e57f79fc3e35187f551c2a8c14fca923329a98ab41e7aa86a3b42", - "web/halo.b73e64ce43393cf3.mjs": "b73e64ce43393cf357acd90c1daf91b43f28c9f7d324b430354fb64ec9b857b7", - "web/halo_execution.09d34f450026959a.js": "09d34f450026959a212c12734d50b4dea5515a3044b168a537f4f4d19d885ec7", - "web/halo_resolution.59e0855f43e3060a.mjs": "59e0855f43e3060a8ae410857841b0586f7ba7a2f421046a82606d56d5e418c4", - "web/image_collection.115703a311f28a75.js": "115703a311f28a75586e8e6ba0e8d36686bd6d965e9f27c390c7023a3fea7971", - "web/prompt_director.c5c84298ff159d35.js": "c5c84298ff159d35be6d8e7a6885886358ebafe8a3e769a328f676419b4505a6", - "web/resolution_control_deck.b30eddd3c7057a66.js": "b30eddd3c7057a664996656e09dad90ca76dd8d24330e28af78485e2e2916b32", + "web/easy_crop.c762cd2c08bdd021.js": "c762cd2c08bdd02110f69b6c3ebedd06e7c59cde31e945a158abfe4eda5d3531", + "web/gallery.e3606d29cf52db7a.mjs": "e3606d29cf52db7aef836d339c2b2a6c1ec39555f4137a5f1e62954e89604121", + "web/halo.84c0c1fe41e5e23f.mjs": "84c0c1fe41e5e23ffc7009c5cc1ae8797c218d3d4a51b0ae88dec51937197599", + "web/halo_execution.61efa407f380b6aa.js": "61efa407f380b6aaff4c8b471bbb3a4273f7fc53920a0882ebf0b6e33c92f096", + "web/halo_resolution.a80ef8d6675f57d8.mjs": "a80ef8d6675f57d8b400eda213392ea4beb2246aacfbd7362fc01f1acb85b37e", + "web/image_collection.b0499872483ab4a6.js": "b0499872483ab4a6b67f24dee1447862e37f0ff4e0a8bf5cdfd31e46266a5b6a", + "web/prompt_director.142e8c2b440b899f.js": "142e8c2b440b899f58e85b656a11b09c5af02f3f8cf24d58a4007f097845119b", + "web/resolution_control_deck.65456abfe9733be0.js": "65456abfe9733be077fe9a7bd578d5201acc1da21e024f73b79daa20c4c6c8cf", "web/resolution_geometry.7c84089742df0120.mjs": "7c84089742df01204445ae3e811d88e7d74f3ba6282f788e44331e3ef3e5f82d" } } diff --git a/web/ai_influencer_resolution.1a837209ce36c3ee.js b/web/ai_influencer_resolution.bc3ad563c6f25c80.js similarity index 99% rename from web/ai_influencer_resolution.1a837209ce36c3ee.js rename to web/ai_influencer_resolution.bc3ad563c6f25c80.js index 9bce834..cd7dc53 100644 --- a/web/ai_influencer_resolution.1a837209ce36c3ee.js +++ b/web/ai_influencer_resolution.bc3ad563c6f25c80.js @@ -1,5 +1,5 @@ import { app } from "../../scripts/app.js"; -import { createHaloResolutionDeck, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, setHaloNodeSize, calculateTierResolution, migrateResolutionGraph } from "./halo_resolution.59e0855f43e3060a.mjs"; +import { createHaloResolutionDeck, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, setHaloNodeSize, calculateTierResolution, migrateResolutionGraph } from "./halo_resolution.a80ef8d6675f57d8.mjs"; const ASPECT_RATIOS = ["1:1", "9:16", "3:4"]; const RESOLUTION_TIERS = ["1K", "2K", "4K"]; export function calculateResolution(state) { diff --git a/web/ai_influencer_resolution_2k4k.fc69d433ef01a504.js b/web/ai_influencer_resolution_2k4k.ea179b0b1378b742.js similarity index 99% rename from web/ai_influencer_resolution_2k4k.fc69d433ef01a504.js rename to web/ai_influencer_resolution_2k4k.ea179b0b1378b742.js index 3df1c72..045b2f4 100644 --- a/web/ai_influencer_resolution_2k4k.fc69d433ef01a504.js +++ b/web/ai_influencer_resolution_2k4k.ea179b0b1378b742.js @@ -1,5 +1,5 @@ import { app } from "../../scripts/app.js"; -import { createHaloResolutionDeck, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, setHaloNodeSize, calculateTierResolution } from "./halo_resolution.59e0855f43e3060a.mjs"; +import { createHaloResolutionDeck, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, setHaloNodeSize, calculateTierResolution } from "./halo_resolution.a80ef8d6675f57d8.mjs"; const ASPECT_RATIOS = ["1:1", "9:16", "3:4"]; const RESOLUTION_TIERS = ["2K", "4K"]; export function calculateResolution(state) { diff --git a/web/easy_crop.b8510f8ee542f9bb.js b/web/easy_crop.c762cd2c08bdd021.js similarity index 99% rename from web/easy_crop.b8510f8ee542f9bb.js rename to web/easy_crop.c762cd2c08bdd021.js index d32bfa5..2f232c9 100644 --- a/web/easy_crop.b8510f8ee542f9bb.js +++ b/web/easy_crop.c762cd2c08bdd021.js @@ -1,6 +1,6 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; -import { createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, mountHaloSurface, setHaloNodeSize } from "./halo.b73e64ce43393cf3.mjs"; +import { createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, mountHaloSurface, setHaloNodeSize } from "./halo.84c0c1fe41e5e23f.mjs"; const NODE_IDS = new Set(["MATRIX_EasyCrop"]); export const CONTROL = Symbol.for("matrixlab.easy-crop.control"); diff --git a/web/gallery.af177ab78d3e57f7.mjs b/web/gallery.e3606d29cf52db7a.mjs similarity index 99% rename from web/gallery.af177ab78d3e57f7.mjs rename to web/gallery.e3606d29cf52db7a.mjs index bf619d7..5cf35bc 100644 --- a/web/gallery.af177ab78d3e57f7.mjs +++ b/web/gallery.e3606d29cf52db7a.mjs @@ -1,4 +1,4 @@ -import { haloMinimumNodeHeight, measureHaloContentHeight, mountHaloSurface, setHaloNodeSize } from "./halo.b73e64ce43393cf3.mjs"; +import { haloMinimumNodeHeight, measureHaloContentHeight, mountHaloSurface, setHaloNodeSize } from "./halo.84c0c1fe41e5e23f.mjs"; export const GALLERY_STATE_VERSION = 1; export const MAX_GALLERY_IMAGES = 10; diff --git a/web/halo.b73e64ce43393cf3.mjs b/web/halo.84c0c1fe41e5e23f.mjs similarity index 98% rename from web/halo.b73e64ce43393cf3.mjs rename to web/halo.84c0c1fe41e5e23f.mjs index 08f175c..84b0bb6 100644 --- a/web/halo.b73e64ce43393cf3.mjs +++ b/web/halo.84c0c1fe41e5e23f.mjs @@ -858,6 +858,10 @@ export function mountHaloSurface(root, node, options = {}) { let destroyed = false; let inViewport = true; let drops = []; + let dashWidth = -1; + let dashHeight = -1; + let dashCycle = HALO_TOKENS.edgeDashCycle; + const edgeDash = [...HALO_TOKENS.edgeDash]; let unregister = null; let resizeObserver = null; let intersectionObserver = null; @@ -933,13 +937,26 @@ export function mountHaloSurface(root, node, options = {}) { edge.translate(HALO_TOKENS.canvasOverscan, HALO_TOKENS.canvasOverscan); edge.beginPath(); const halfEdge = HALO_TOKENS.edgeWidth / 2; - roundedRect(edge, halfEdge, halfEdge, Math.max(0, frame.width - HALO_TOKENS.edgeWidth), Math.max(0, frame.height - HALO_TOKENS.edgeWidth), HALO_TOKENS.outerRadius); + const edgeWidth = Math.max(0, frame.width - HALO_TOKENS.edgeWidth); + const edgeHeight = Math.max(0, frame.height - HALO_TOKENS.edgeWidth); + roundedRect(edge, halfEdge, halfEdge, edgeWidth, edgeHeight, HALO_TOKENS.outerRadius); edge.strokeStyle = HALO_TOKENS.green; edge.shadowColor = HALO_TOKENS.green; edge.shadowBlur = HALO_TOKENS.edgeShadowBlur; edge.lineWidth = HALO_TOKENS.edgeWidth; - edge.setLineDash(HALO_TOKENS.edgeDash); - edge.lineDashOffset = -((timeSeconds * HALO_TOKENS.edgeSpeed) % HALO_TOKENS.edgeDashCycle); + if (edgeWidth !== dashWidth || edgeHeight !== dashHeight) { + const radius = Math.min(HALO_TOKENS.outerRadius, edgeWidth / 2, edgeHeight / 2); + const perimeter = 2 * (edgeWidth + edgeHeight) + (2 * Math.PI - 8) * radius; + // Fit whole dash cycles around the closed path so its seam stays continuous. + dashCycle = perimeter / Math.max(1, Math.round(perimeter / HALO_TOKENS.edgeDashCycle)); + const scale = dashCycle / HALO_TOKENS.edgeDashCycle; + edgeDash[0] = HALO_TOKENS.edgeDash[0] * scale; + edgeDash[1] = HALO_TOKENS.edgeDash[1] * scale; + dashWidth = edgeWidth; + dashHeight = edgeHeight; + } + edge.setLineDash(edgeDash); + edge.lineDashOffset = -((timeSeconds * HALO_TOKENS.edgeSpeed) % dashCycle); edge.stroke(); edge.restore(); if (classicHousing) node.setDirtyCanvas?.(true, false); diff --git a/web/halo_execution.09d34f450026959a.js b/web/halo_execution.61efa407f380b6aa.js similarity index 89% rename from web/halo_execution.09d34f450026959a.js rename to web/halo_execution.61efa407f380b6aa.js index c826a17..8b58ce5 100644 --- a/web/halo_execution.09d34f450026959a.js +++ b/web/halo_execution.61efa407f380b6aa.js @@ -1,5 +1,5 @@ import { app } from "../../scripts/app.js"; -import { mountHaloExecutionNode } from "./halo.b73e64ce43393cf3.mjs"; +import { mountHaloExecutionNode } from "./halo.84c0c1fe41e5e23f.mjs"; const ids = new Set(["MATRIX_CropTailPaste", "MATRIX_EyeMask", "MATRIX_LatentTail", "MATRIX_MetadataKiller", "MATRIX_OutputStage", "MATRIX_PhotoFinisher", "MATRIX_SkinMask", "MATRIX_SpectralSampler", "MATRIXSpectralSampler"]); const attach = (node) => { if (ids.has(node.comfyClass || node.type)) mountHaloExecutionNode(node, {app}); diff --git a/web/halo_resolution.59e0855f43e3060a.mjs b/web/halo_resolution.a80ef8d6675f57d8.mjs similarity index 99% rename from web/halo_resolution.59e0855f43e3060a.mjs rename to web/halo_resolution.a80ef8d6675f57d8.mjs index 7538071..3dfdc84 100644 --- a/web/halo_resolution.59e0855f43e3060a.mjs +++ b/web/halo_resolution.a80ef8d6675f57d8.mjs @@ -1,4 +1,4 @@ -import { HALO_TOKENS, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, measureHaloVerticalChrome, mountHaloSurface, setHaloNodeSize } from "./halo.b73e64ce43393cf3.mjs"; +import { HALO_TOKENS, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, measureHaloVerticalChrome, mountHaloSurface, setHaloNodeSize } from "./halo.84c0c1fe41e5e23f.mjs"; export { createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, measureHaloHorizontalChrome, measureHaloVerticalChrome, setHaloNodeSize }; diff --git a/web/image_collection.115703a311f28a75.js b/web/image_collection.b0499872483ab4a6.js similarity index 98% rename from web/image_collection.115703a311f28a75.js rename to web/image_collection.b0499872483ab4a6.js index 48955fa..5e06a66 100644 --- a/web/image_collection.115703a311f28a75.js +++ b/web/image_collection.b0499872483ab4a6.js @@ -1,5 +1,5 @@ -import { mountImageGallery } from "./gallery.af177ab78d3e57f7.mjs"; -import { createHaloWidgetHost, haloWidgetLayoutHeight, measureHaloContentHeight, setHaloNodeSize } from "./halo.b73e64ce43393cf3.mjs"; +import { mountImageGallery } from "./gallery.e3606d29cf52db7a.mjs"; +import { createHaloWidgetHost, haloWidgetLayoutHeight, measureHaloContentHeight, setHaloNodeSize } from "./halo.84c0c1fe41e5e23f.mjs"; const { app } = globalThis.comfyAPI?.app || {}; const { api } = globalThis.comfyAPI?.api || {}; diff --git a/web/prompt_director.c5c84298ff159d35.js b/web/prompt_director.142e8c2b440b899f.js similarity index 99% rename from web/prompt_director.c5c84298ff159d35.js rename to web/prompt_director.142e8c2b440b899f.js index 1f900de..4289176 100644 --- a/web/prompt_director.c5c84298ff159d35.js +++ b/web/prompt_director.142e8c2b440b899f.js @@ -6,7 +6,7 @@ import { measureHaloContentHeight, mountHaloSurface, setHaloNodeSize, -} from "./halo.b73e64ce43393cf3.mjs"; +} from "./halo.84c0c1fe41e5e23f.mjs"; const { app } = globalThis.comfyAPI?.app || {}; const { api } = globalThis.comfyAPI?.api || {}; diff --git a/web/resolution_control_deck.b30eddd3c7057a66.js b/web/resolution_control_deck.65456abfe9733be0.js similarity index 99% rename from web/resolution_control_deck.b30eddd3c7057a66.js rename to web/resolution_control_deck.65456abfe9733be0.js index d6509ce..fdaf1d7 100644 --- a/web/resolution_control_deck.b30eddd3c7057a66.js +++ b/web/resolution_control_deck.65456abfe9733be0.js @@ -1,5 +1,5 @@ import { app } from "../../scripts/app.js"; -import { createHaloResolutionDeck, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, setHaloNodeSize, calculateTierResolution, migrateResolutionGraph } from "./halo_resolution.59e0855f43e3060a.mjs"; +import { createHaloResolutionDeck, createHaloWidgetHost, haloMinimumNodeHeight, haloWidgetLayoutHeight, measureHaloContentHeight, setHaloNodeSize, calculateTierResolution, migrateResolutionGraph } from "./halo_resolution.a80ef8d6675f57d8.mjs"; const NODE_IDS = new Set("MATRIX_Resolution".split(",").filter(Boolean)); const RATIOS = {