diff --git a/src/info-panel/CanvasHighlighter.ts b/src/info-panel/CanvasHighlighter.ts index bd36671..6ab57e6 100644 --- a/src/info-panel/CanvasHighlighter.ts +++ b/src/info-panel/CanvasHighlighter.ts @@ -34,7 +34,6 @@ export class CanvasHighlighter { display: none; box-sizing: border-box; box-shadow: 0 0 10px rgba(0, 123, 255, 0.3); - transition: all 0.05s linear; `; document.body.appendChild(this.highlightEl); } diff --git a/web/info-panel/CanvasHighlighter.js b/web/info-panel/CanvasHighlighter.js index 6ad0bc4..f297650 100644 --- a/web/info-panel/CanvasHighlighter.js +++ b/web/info-panel/CanvasHighlighter.js @@ -30,7 +30,6 @@ class CanvasHighlighter { display: none; box-sizing: border-box; box-shadow: 0 0 10px rgba(0, 123, 255, 0.3); - transition: all 0.05s linear; `; document.body.appendChild(this.highlightEl); } diff --git a/web/info-panel/CanvasHighlighter.js.map b/web/info-panel/CanvasHighlighter.js.map index 98162f4..2e3399d 100644 --- a/web/info-panel/CanvasHighlighter.js.map +++ b/web/info-panel/CanvasHighlighter.js.map @@ -1 +1 @@ -{"version":3,"file":"CanvasHighlighter.js","sources":["../../src/info-panel/CanvasHighlighter.ts"],"sourcesContent":["/**\n * CanvasHighlighter.ts\n * \n * Handles drawing a visual highlight on the main canvas around the currently inspected node.\n * Hooks into LiteGraph's canvas drawing cycle.\n */\n\nimport { ComfyApp, ComfyNode } from '../types/comfyui';\n\ndeclare const app: ComfyApp;\n\nexport class CanvasHighlighter {\n private originalOnDrawForeground: ((ctx: CanvasRenderingContext2D, visible_nodes: any) => void) | null = null;\n private highlightedNodeId: number | null = null;\n\n private highlightEl: HTMLDivElement | null = null;\n // Cache for DOM updates to minimize thrashing\n private lastStyleState: string = '';\n\n constructor() {\n this.createHighlightElement();\n this.hookCanvas();\n }\n\n private createHighlightElement(): void {\n this.highlightEl = document.createElement(\"div\");\n this.highlightEl.id = \"magnify-glass-node-highlight\";\n this.highlightEl.style.cssText = `\n position: fixed;\n pointer-events: none;\n border: 2px solid #007bff;\n border-radius: 10px;\n z-index: 1000;\n display: none;\n box-sizing: border-box;\n box-shadow: 0 0 10px rgba(0, 123, 255, 0.3);\n transition: all 0.05s linear;\n `;\n document.body.appendChild(this.highlightEl);\n }\n\n /**\n * Hook into the main canvas onDrawForeground method.\n */\n private hookCanvas(): void {\n const app = (window as any).app;\n if (!app || !app.canvas) {\n console.warn('[MagnifyGlass] Canvas not found, cannot hook highlighter');\n return;\n }\n const canvas = app.canvas;\n\n // Save original method\n this.originalOnDrawForeground = canvas.onDrawForeground;\n\n // Override\n canvas.onDrawForeground = this.boundOnDrawForeground;\n }\n\n /**\n * Set the node ID to highlight.\n */\n setHighlightedNode(nodeId: number | null): void {\n this.ensureHook(); // Ensure we are still hooked\n\n if (this.highlightedNodeId === nodeId) return;\n this.highlightedNodeId = nodeId;\n\n // Force redraw effectively updates our position logic via the hook\n const app = (window as any).app;\n if (app && app.canvas) {\n app.canvas.setDirty(true, true);\n }\n\n // Immediate update attempt (in case canvas isn't dirty)\n if (nodeId === null && this.highlightEl) {\n this.highlightEl.style.display = 'none';\n }\n }\n\n /**\n * Ensure the canvas hook is active.\n */\n private ensureHook(): void {\n const app = (window as any).app;\n if (!app || !app.canvas) return;\n\n // If our hook was overwritten (e.g. by another extension), re-hook\n if (app.canvas.onDrawForeground !== this.boundOnDrawForeground) {\n this.originalOnDrawForeground = app.canvas.onDrawForeground;\n app.canvas.onDrawForeground = this.boundOnDrawForeground;\n }\n }\n\n // Bound method to preserve 'this' and allow equality check\n private boundOnDrawForeground = (ctx: CanvasRenderingContext2D, visible_nodes: any) => {\n // Call original first\n if (this.originalOnDrawForeground) {\n this.originalOnDrawForeground.call((window as any).app.canvas, ctx, visible_nodes);\n }\n\n // Update DOM Highlight Position\n this.updateHighlightPosition();\n };\n\n /**\n * Update the position of the DOM highlight element.\n */\n private updateHighlightPosition(): void {\n if (!this.highlightEl) return;\n const app = (window as any).app;\n if (!app || !app.canvas || !app.graph) return;\n\n // 1. Check Visibility Settings\n const highlightEnabled = app.ui?.settings?.getSettingValue('🔍MagnifyGlass.NodeHighlightEnabled') ?? true;\n if (!highlightEnabled || this.highlightedNodeId === null) {\n if (this.highlightEl.style.display !== 'none') {\n this.highlightEl.style.display = 'none';\n }\n return;\n }\n\n // 2. Get Node\n const node = app.graph.getNodeById(this.highlightedNodeId);\n if (!node) {\n if (this.highlightEl.style.display !== 'none') {\n this.highlightEl.style.display = 'none';\n }\n return;\n }\n\n // 3. Get Canvas Element's position on the page\n const canvasEl = app.canvas.canvas as HTMLCanvasElement;\n if (!canvasEl) return;\n const canvasRect = canvasEl.getBoundingClientRect();\n\n // 4. Coordinate Math\n const ds = app.canvas.ds;\n const scale = ds.scale;\n const offset = ds.offset;\n\n const LiteGraph = (window as any).LiteGraph;\n const titleHeight = LiteGraph?.NODE_TITLE_HEIGHT ?? 30;\n const padding = 6;\n\n // Graph coordinates\n // Assuming node.pos is top of body, we shift up by titleHeight to cover title\n // And use total height = title + body\n const graphX = node.pos[0];\n const graphY = node.pos[1] - titleHeight;\n const graphW = node.size[0];\n const graphH = titleHeight + node.size[1];\n\n // Canvas-relative screen coordinates (CSS pixels within the canvas element)\n // LiteGraph transform is: (Graph + Offset) * Scale\n const canvasX = (graphX + offset[0]) * scale;\n const canvasY = (graphY + offset[1]) * scale;\n const canvasW = graphW * scale;\n const canvasH = graphH * scale;\n\n // Page-absolute coordinates (add canvas position on the page)\n const pageX = canvasRect.left + canvasX - padding;\n const pageY = canvasRect.top + canvasY - padding; // Removed hardcoded offset\n const finalW = canvasW + (padding * 2);\n const finalH = canvasH + (padding * 2);\n\n // 5. Update DOM\n const styleState = `${pageX.toFixed(1)},${pageY.toFixed(1)},${finalW.toFixed(1)},${finalH.toFixed(1)}`;\n if (this.lastStyleState !== styleState || this.highlightEl.style.display === 'none') {\n this.highlightEl.style.display = 'block';\n this.highlightEl.style.left = `${pageX}px`;\n this.highlightEl.style.top = `${pageY}px`;\n this.highlightEl.style.width = `${finalW}px`;\n this.highlightEl.style.height = `${finalH}px`;\n\n // Border width scales with zoom (clamped 2-6px)\n const borderWidth = Math.max(2, Math.min(6, 3 * scale));\n this.highlightEl.style.borderWidth = `${borderWidth}px`;\n\n this.lastStyleState = styleState;\n }\n }\n\n /**\n * Clean up hooks.\n */\n cleanup(): void {\n const app = (window as any).app;\n if (app && app.canvas && this.originalOnDrawForeground) {\n if (app.canvas.onDrawForeground === this.boundOnDrawForeground) {\n app.canvas.onDrawForeground = this.originalOnDrawForeground;\n }\n }\n\n if (this.highlightEl) {\n this.highlightEl.remove();\n this.highlightEl = null;\n }\n }\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"CanvasHighlighter.js","sources":["../../src/info-panel/CanvasHighlighter.ts"],"sourcesContent":["/**\n * CanvasHighlighter.ts\n * \n * Handles drawing a visual highlight on the main canvas around the currently inspected node.\n * Hooks into LiteGraph's canvas drawing cycle.\n */\n\nimport { ComfyApp, ComfyNode } from '../types/comfyui';\n\ndeclare const app: ComfyApp;\n\nexport class CanvasHighlighter {\n private originalOnDrawForeground: ((ctx: CanvasRenderingContext2D, visible_nodes: any) => void) | null = null;\n private highlightedNodeId: number | null = null;\n\n private highlightEl: HTMLDivElement | null = null;\n // Cache for DOM updates to minimize thrashing\n private lastStyleState: string = '';\n\n constructor() {\n this.createHighlightElement();\n this.hookCanvas();\n }\n\n private createHighlightElement(): void {\n this.highlightEl = document.createElement(\"div\");\n this.highlightEl.id = \"magnify-glass-node-highlight\";\n this.highlightEl.style.cssText = `\n position: fixed;\n pointer-events: none;\n border: 2px solid #007bff;\n border-radius: 10px;\n z-index: 1000;\n display: none;\n box-sizing: border-box;\n box-shadow: 0 0 10px rgba(0, 123, 255, 0.3);\n `;\n document.body.appendChild(this.highlightEl);\n }\n\n /**\n * Hook into the main canvas onDrawForeground method.\n */\n private hookCanvas(): void {\n const app = (window as any).app;\n if (!app || !app.canvas) {\n console.warn('[MagnifyGlass] Canvas not found, cannot hook highlighter');\n return;\n }\n const canvas = app.canvas;\n\n // Save original method\n this.originalOnDrawForeground = canvas.onDrawForeground;\n\n // Override\n canvas.onDrawForeground = this.boundOnDrawForeground;\n }\n\n /**\n * Set the node ID to highlight.\n */\n setHighlightedNode(nodeId: number | null): void {\n this.ensureHook(); // Ensure we are still hooked\n\n if (this.highlightedNodeId === nodeId) return;\n this.highlightedNodeId = nodeId;\n\n // Force redraw effectively updates our position logic via the hook\n const app = (window as any).app;\n if (app && app.canvas) {\n app.canvas.setDirty(true, true);\n }\n\n // Immediate update attempt (in case canvas isn't dirty)\n if (nodeId === null && this.highlightEl) {\n this.highlightEl.style.display = 'none';\n }\n }\n\n /**\n * Ensure the canvas hook is active.\n */\n private ensureHook(): void {\n const app = (window as any).app;\n if (!app || !app.canvas) return;\n\n // If our hook was overwritten (e.g. by another extension), re-hook\n if (app.canvas.onDrawForeground !== this.boundOnDrawForeground) {\n this.originalOnDrawForeground = app.canvas.onDrawForeground;\n app.canvas.onDrawForeground = this.boundOnDrawForeground;\n }\n }\n\n // Bound method to preserve 'this' and allow equality check\n private boundOnDrawForeground = (ctx: CanvasRenderingContext2D, visible_nodes: any) => {\n // Call original first\n if (this.originalOnDrawForeground) {\n this.originalOnDrawForeground.call((window as any).app.canvas, ctx, visible_nodes);\n }\n\n // Update DOM Highlight Position\n this.updateHighlightPosition();\n };\n\n /**\n * Update the position of the DOM highlight element.\n */\n private updateHighlightPosition(): void {\n if (!this.highlightEl) return;\n const app = (window as any).app;\n if (!app || !app.canvas || !app.graph) return;\n\n // 1. Check Visibility Settings\n const highlightEnabled = app.ui?.settings?.getSettingValue('🔍MagnifyGlass.NodeHighlightEnabled') ?? true;\n if (!highlightEnabled || this.highlightedNodeId === null) {\n if (this.highlightEl.style.display !== 'none') {\n this.highlightEl.style.display = 'none';\n }\n return;\n }\n\n // 2. Get Node\n const node = app.graph.getNodeById(this.highlightedNodeId);\n if (!node) {\n if (this.highlightEl.style.display !== 'none') {\n this.highlightEl.style.display = 'none';\n }\n return;\n }\n\n // 3. Get Canvas Element's position on the page\n const canvasEl = app.canvas.canvas as HTMLCanvasElement;\n if (!canvasEl) return;\n const canvasRect = canvasEl.getBoundingClientRect();\n\n // 4. Coordinate Math\n const ds = app.canvas.ds;\n const scale = ds.scale;\n const offset = ds.offset;\n\n const LiteGraph = (window as any).LiteGraph;\n const titleHeight = LiteGraph?.NODE_TITLE_HEIGHT ?? 30;\n const padding = 6;\n\n // Graph coordinates\n // Assuming node.pos is top of body, we shift up by titleHeight to cover title\n // And use total height = title + body\n const graphX = node.pos[0];\n const graphY = node.pos[1] - titleHeight;\n const graphW = node.size[0];\n const graphH = titleHeight + node.size[1];\n\n // Canvas-relative screen coordinates (CSS pixels within the canvas element)\n // LiteGraph transform is: (Graph + Offset) * Scale\n const canvasX = (graphX + offset[0]) * scale;\n const canvasY = (graphY + offset[1]) * scale;\n const canvasW = graphW * scale;\n const canvasH = graphH * scale;\n\n // Page-absolute coordinates (add canvas position on the page)\n const pageX = canvasRect.left + canvasX - padding;\n const pageY = canvasRect.top + canvasY - padding; // Removed hardcoded offset\n const finalW = canvasW + (padding * 2);\n const finalH = canvasH + (padding * 2);\n\n // 5. Update DOM\n const styleState = `${pageX.toFixed(1)},${pageY.toFixed(1)},${finalW.toFixed(1)},${finalH.toFixed(1)}`;\n if (this.lastStyleState !== styleState || this.highlightEl.style.display === 'none') {\n this.highlightEl.style.display = 'block';\n this.highlightEl.style.left = `${pageX}px`;\n this.highlightEl.style.top = `${pageY}px`;\n this.highlightEl.style.width = `${finalW}px`;\n this.highlightEl.style.height = `${finalH}px`;\n\n // Border width scales with zoom (clamped 2-6px)\n const borderWidth = Math.max(2, Math.min(6, 3 * scale));\n this.highlightEl.style.borderWidth = `${borderWidth}px`;\n\n this.lastStyleState = styleState;\n }\n }\n\n /**\n * Clean up hooks.\n */\n cleanup(): void {\n const app = (window as any).app;\n if (app && app.canvas && this.originalOnDrawForeground) {\n if (app.canvas.onDrawForeground === this.boundOnDrawForeground) {\n app.canvas.onDrawForeground = this.originalOnDrawForeground;\n }\n }\n\n if (this.highlightEl) {\n this.highlightEl.remove();\n this.highlightEl = null;\n }\n }\n}\n"],"names":[],"mappings":";;;AAWO,MAAM,kBAAkB;AAAA,EAQ3B,cAAc;AAPN,oDAAiG;AACjG,6CAAmC;AAEnC,uCAAqC;AAErC;AAAA,0CAAyB;AA6EzB;AAAA,iDAAwB,CAAC,KAA+B,kBAAuB;AAEnF,UAAI,KAAK,0BAA0B;AAC/B,aAAK,yBAAyB,KAAM,OAAe,IAAI,QAAQ,KAAK,aAAa;AAAA,MACrF;AAGA,WAAK,wBAAA;AAAA,IACT;AAlFI,SAAK,uBAAA;AACL,SAAK,WAAA;AAAA,EACT;AAAA,EAEQ,yBAA+B;AACnC,SAAK,cAAc,SAAS,cAAc,KAAK;AAC/C,SAAK,YAAY,KAAK;AACtB,SAAK,YAAY,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUjC,aAAS,KAAK,YAAY,KAAK,WAAW;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAmB;AACvB,UAAM,MAAO,OAAe;AAC5B,QAAI,CAAC,OAAO,CAAC,IAAI,QAAQ;AACrB,cAAQ,KAAK,0DAA0D;AACvE;AAAA,IACJ;AACA,UAAM,SAAS,IAAI;AAGnB,SAAK,2BAA2B,OAAO;AAGvC,WAAO,mBAAmB,KAAK;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,QAA6B;AAC5C,SAAK,WAAA;AAEL,QAAI,KAAK,sBAAsB,OAAQ;AACvC,SAAK,oBAAoB;AAGzB,UAAM,MAAO,OAAe;AAC5B,QAAI,OAAO,IAAI,QAAQ;AACnB,UAAI,OAAO,SAAS,MAAM,IAAI;AAAA,IAClC;AAGA,QAAI,WAAW,QAAQ,KAAK,aAAa;AACrC,WAAK,YAAY,MAAM,UAAU;AAAA,IACrC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAmB;AACvB,UAAM,MAAO,OAAe;AAC5B,QAAI,CAAC,OAAO,CAAC,IAAI,OAAQ;AAGzB,QAAI,IAAI,OAAO,qBAAqB,KAAK,uBAAuB;AAC5D,WAAK,2BAA2B,IAAI,OAAO;AAC3C,UAAI,OAAO,mBAAmB,KAAK;AAAA,IACvC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAgBQ,0BAAgC;AAhGrC;AAiGC,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,MAAO,OAAe;AAC5B,QAAI,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,IAAI,MAAO;AAGvC,UAAM,qBAAmB,eAAI,OAAJ,mBAAQ,aAAR,mBAAkB,gBAAgB,2CAA0C;AACrG,QAAI,CAAC,oBAAoB,KAAK,sBAAsB,MAAM;AACtD,UAAI,KAAK,YAAY,MAAM,YAAY,QAAQ;AAC3C,aAAK,YAAY,MAAM,UAAU;AAAA,MACrC;AACA;AAAA,IACJ;AAGA,UAAM,OAAO,IAAI,MAAM,YAAY,KAAK,iBAAiB;AACzD,QAAI,CAAC,MAAM;AACP,UAAI,KAAK,YAAY,MAAM,YAAY,QAAQ;AAC3C,aAAK,YAAY,MAAM,UAAU;AAAA,MACrC;AACA;AAAA,IACJ;AAGA,UAAM,WAAW,IAAI,OAAO;AAC5B,QAAI,CAAC,SAAU;AACf,UAAM,aAAa,SAAS,sBAAA;AAG5B,UAAM,KAAK,IAAI,OAAO;AACtB,UAAM,QAAQ,GAAG;AACjB,UAAM,SAAS,GAAG;AAElB,UAAM,YAAa,OAAe;AAClC,UAAM,eAAc,uCAAW,sBAAqB;AACpD,UAAM,UAAU;AAKhB,UAAM,SAAS,KAAK,IAAI,CAAC;AACzB,UAAM,SAAS,KAAK,IAAI,CAAC,IAAI;AAC7B,UAAM,SAAS,KAAK,KAAK,CAAC;AAC1B,UAAM,SAAS,cAAc,KAAK,KAAK,CAAC;AAIxC,UAAM,WAAW,SAAS,OAAO,CAAC,KAAK;AACvC,UAAM,WAAW,SAAS,OAAO,CAAC,KAAK;AACvC,UAAM,UAAU,SAAS;AACzB,UAAM,UAAU,SAAS;AAGzB,UAAM,QAAQ,WAAW,OAAO,UAAU;AAC1C,UAAM,QAAQ,WAAW,MAAM,UAAU;AACzC,UAAM,SAAS,UAAW,UAAU;AACpC,UAAM,SAAS,UAAW,UAAU;AAGpC,UAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC,IAAI,OAAO,QAAQ,CAAC,CAAC,IAAI,OAAO,QAAQ,CAAC,CAAC;AACpG,QAAI,KAAK,mBAAmB,cAAc,KAAK,YAAY,MAAM,YAAY,QAAQ;AACjF,WAAK,YAAY,MAAM,UAAU;AACjC,WAAK,YAAY,MAAM,OAAO,GAAG,KAAK;AACtC,WAAK,YAAY,MAAM,MAAM,GAAG,KAAK;AACrC,WAAK,YAAY,MAAM,QAAQ,GAAG,MAAM;AACxC,WAAK,YAAY,MAAM,SAAS,GAAG,MAAM;AAGzC,YAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC;AACtD,WAAK,YAAY,MAAM,cAAc,GAAG,WAAW;AAEnD,WAAK,iBAAiB;AAAA,IAC1B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACZ,UAAM,MAAO,OAAe;AAC5B,QAAI,OAAO,IAAI,UAAU,KAAK,0BAA0B;AACpD,UAAI,IAAI,OAAO,qBAAqB,KAAK,uBAAuB;AAC5D,YAAI,OAAO,mBAAmB,KAAK;AAAA,MACvC;AAAA,IACJ;AAEA,QAAI,KAAK,aAAa;AAClB,WAAK,YAAY,OAAA;AACjB,WAAK,cAAc;AAAA,IACvB;AAAA,EACJ;AACJ;"} \ No newline at end of file