feat: improve canvas highlight hook robustness and update node highlight style to a thicker blue border.
This commit is contained in:
@@ -37,21 +37,18 @@ export class CanvasHighlighter {
|
||||
this.originalOnDrawForeground = canvas.onDrawForeground;
|
||||
|
||||
// Override
|
||||
canvas.onDrawForeground = (ctx: CanvasRenderingContext2D, visible_nodes: any) => {
|
||||
// Call original first
|
||||
if (this.originalOnDrawForeground) {
|
||||
this.originalOnDrawForeground.call(canvas, ctx, visible_nodes);
|
||||
}
|
||||
|
||||
// Draw our highlight
|
||||
this.drawHighlight(ctx, canvas.ds.scale);
|
||||
};
|
||||
canvas.onDrawForeground = this.boundOnDrawForeground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the node ID to highlight.
|
||||
*/
|
||||
/**
|
||||
* Set the node ID to highlight.
|
||||
*/
|
||||
setHighlightedNode(nodeId: number | null): void {
|
||||
this.ensureHook(); // Ensure we are still hooked
|
||||
|
||||
if (this.highlightedNodeId === nodeId) return;
|
||||
this.highlightedNodeId = nodeId;
|
||||
// Force redraw to update highlight immediately
|
||||
@@ -61,6 +58,35 @@ export class CanvasHighlighter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the canvas hook is active.
|
||||
*/
|
||||
private ensureHook(): void {
|
||||
const app = (window as any).app;
|
||||
if (!app || !app.canvas) return;
|
||||
|
||||
// If our hook was overwritten (e.g. by another extension), re-hook
|
||||
if (app.canvas.onDrawForeground !== this.boundOnDrawForeground) {
|
||||
// console.log('[MagnifyGlass] Re-hooking CanvasHighlighter');
|
||||
this.originalOnDrawForeground = app.canvas.onDrawForeground;
|
||||
app.canvas.onDrawForeground = this.boundOnDrawForeground;
|
||||
}
|
||||
}
|
||||
|
||||
// Bound method to preserve 'this' and allow equality check
|
||||
private boundOnDrawForeground = (ctx: CanvasRenderingContext2D, visible_nodes: any) => {
|
||||
// Call original first
|
||||
if (this.originalOnDrawForeground) {
|
||||
this.originalOnDrawForeground.call((window as any).app.canvas, ctx, visible_nodes);
|
||||
}
|
||||
|
||||
// Draw our highlight
|
||||
const app = (window as any).app;
|
||||
if (app && app.canvas) {
|
||||
this.drawHighlight(ctx, app.canvas.ds.scale);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the highlight rectangle around the target node.
|
||||
*/
|
||||
@@ -78,23 +104,24 @@ export class CanvasHighlighter {
|
||||
// Note: ctx passed to onDrawForeground is already transformed by LiteGraph to graph coordinates
|
||||
// so we can draw using node.pos directly.
|
||||
|
||||
const x = node.pos[0] - this.HIGHLIGHT_PADDING;
|
||||
const y = node.pos[1] - this.HIGHLIGHT_PADDING;
|
||||
const w = node.size[0] + (this.HIGHLIGHT_PADDING * 2);
|
||||
const h = node.size[1] + (this.HIGHLIGHT_PADDING * 2);
|
||||
const padding = 10;
|
||||
const x = node.pos[0] - padding;
|
||||
const y = node.pos[1] - padding;
|
||||
const w = node.size[0] + (padding * 2);
|
||||
const h = node.size[1] + (padding * 2);
|
||||
|
||||
// Draw glow/outline
|
||||
ctx.lineWidth = this.HIGHLIGHT_WIDTH;
|
||||
ctx.strokeStyle = this.HIGHLIGHT_COLOR;
|
||||
ctx.shadowColor = this.HIGHLIGHT_COLOR;
|
||||
ctx.shadowBlur = 10 * scale; // Scale shadow with zoom
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
// Draw large blue bar/border
|
||||
ctx.lineWidth = 10; // Thicker border
|
||||
ctx.strokeStyle = '#007bff'; // Blue
|
||||
// ctx.shadowColor = '#007bff'; // Optional glow
|
||||
// ctx.shadowBlur = 0;
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.lineCap = 'round';
|
||||
|
||||
// Use roundRect if available (modern browsers), else rect
|
||||
ctx.beginPath();
|
||||
if (typeof ctx.roundRect === 'function') {
|
||||
const radius = 10; // LiteGraph nodes usually have round corners
|
||||
const radius = 10;
|
||||
ctx.roundRect(x, y, w, h, radius);
|
||||
} else {
|
||||
ctx.rect(x, y, w, h);
|
||||
@@ -111,7 +138,9 @@ export class CanvasHighlighter {
|
||||
cleanup(): void {
|
||||
const app = (window as any).app;
|
||||
if (app && app.canvas && this.originalOnDrawForeground) {
|
||||
app.canvas.onDrawForeground = this.originalOnDrawForeground;
|
||||
if (app.canvas.onDrawForeground === this.boundOnDrawForeground) {
|
||||
app.canvas.onDrawForeground = this.originalOnDrawForeground;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,16 @@ class CanvasHighlighter {
|
||||
__publicField(this, "HIGHLIGHT_WIDTH", 2);
|
||||
// px
|
||||
__publicField(this, "HIGHLIGHT_PADDING", 0);
|
||||
// Bound method to preserve 'this' and allow equality check
|
||||
__publicField(this, "boundOnDrawForeground", (ctx, visible_nodes) => {
|
||||
if (this.originalOnDrawForeground) {
|
||||
this.originalOnDrawForeground.call(window.app.canvas, ctx, visible_nodes);
|
||||
}
|
||||
const app = window.app;
|
||||
if (app && app.canvas) {
|
||||
this.drawHighlight(ctx, app.canvas.ds.scale);
|
||||
}
|
||||
});
|
||||
this.hookCanvas();
|
||||
}
|
||||
/**
|
||||
@@ -25,17 +35,16 @@ class CanvasHighlighter {
|
||||
}
|
||||
const canvas = app.canvas;
|
||||
this.originalOnDrawForeground = canvas.onDrawForeground;
|
||||
canvas.onDrawForeground = (ctx, visible_nodes) => {
|
||||
if (this.originalOnDrawForeground) {
|
||||
this.originalOnDrawForeground.call(canvas, ctx, visible_nodes);
|
||||
}
|
||||
this.drawHighlight(ctx, canvas.ds.scale);
|
||||
};
|
||||
canvas.onDrawForeground = this.boundOnDrawForeground;
|
||||
}
|
||||
/**
|
||||
* Set the node ID to highlight.
|
||||
*/
|
||||
/**
|
||||
* Set the node ID to highlight.
|
||||
*/
|
||||
setHighlightedNode(nodeId) {
|
||||
this.ensureHook();
|
||||
if (this.highlightedNodeId === nodeId) return;
|
||||
this.highlightedNodeId = nodeId;
|
||||
const app = window.app;
|
||||
@@ -43,6 +52,17 @@ class CanvasHighlighter {
|
||||
app.canvas.setDirty(true, true);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure the canvas hook is active.
|
||||
*/
|
||||
ensureHook() {
|
||||
const app = window.app;
|
||||
if (!app || !app.canvas) return;
|
||||
if (app.canvas.onDrawForeground !== this.boundOnDrawForeground) {
|
||||
this.originalOnDrawForeground = app.canvas.onDrawForeground;
|
||||
app.canvas.onDrawForeground = this.boundOnDrawForeground;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Draw the highlight rectangle around the target node.
|
||||
*/
|
||||
@@ -53,16 +73,15 @@ class CanvasHighlighter {
|
||||
const node = app.graph.getNodeById(this.highlightedNodeId);
|
||||
if (!node) return;
|
||||
ctx.save();
|
||||
const x = node.pos[0] - this.HIGHLIGHT_PADDING;
|
||||
const y = node.pos[1] - this.HIGHLIGHT_PADDING;
|
||||
const w = node.size[0] + this.HIGHLIGHT_PADDING * 2;
|
||||
const h = node.size[1] + this.HIGHLIGHT_PADDING * 2;
|
||||
ctx.lineWidth = this.HIGHLIGHT_WIDTH;
|
||||
ctx.strokeStyle = this.HIGHLIGHT_COLOR;
|
||||
ctx.shadowColor = this.HIGHLIGHT_COLOR;
|
||||
ctx.shadowBlur = 10 * scale;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
const padding = 10;
|
||||
const x = node.pos[0] - padding;
|
||||
const y = node.pos[1] - padding;
|
||||
const w = node.size[0] + padding * 2;
|
||||
const h = node.size[1] + padding * 2;
|
||||
ctx.lineWidth = 10;
|
||||
ctx.strokeStyle = "#007bff";
|
||||
ctx.lineJoin = "round";
|
||||
ctx.lineCap = "round";
|
||||
ctx.beginPath();
|
||||
if (typeof ctx.roundRect === "function") {
|
||||
const radius = 10;
|
||||
@@ -79,7 +98,9 @@ class CanvasHighlighter {
|
||||
cleanup() {
|
||||
const app = window.app;
|
||||
if (app && app.canvas && this.originalOnDrawForeground) {
|
||||
app.canvas.onDrawForeground = this.originalOnDrawForeground;
|
||||
if (app.canvas.onDrawForeground === this.boundOnDrawForeground) {
|
||||
app.canvas.onDrawForeground = this.originalOnDrawForeground;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user