Files
IxMxAMAR-ComfyUI-Utility-Me…/web/cache.js
T
IxMxAMAR 5afe8e7eb1 release(v0.2.0): wires + 4 themes + category accents + group/grid sync + cache
Wire theming:
- per-theme wirePalette mutates app.canvas.default_connection_color_byType
- wire render-mode dropdown (straight/linear/bezier/manhattan)
- wire thickness + opacity settings via one-time renderLink wrap
- preserves ComfyUI's native execution-flow dots

4 new themes (15 total):
- Blueprint (cyanotype schematic, cached grid)
- Nord (frosted arctic)
- Synthwave (80s retro-futurism)
- E-Ink (monochrome with cached noise overlay)

Per-node-category accent stripes:
- themes declare categoryAccents map keyed by node.constructor.category
- 4-px colored bar on left edge of each node, matched by first path segment

Group colors + canvas bg sync:
- themes declare groupColors + bgGridColor; engine applies and restores

Performance:
- OffscreenCanvas pattern cache for static expensive draws (retro scanlines,
  blueprint grid, e-ink noise). O(area) -> O(1) per frame after first render.
- wire-engine fast path: zero overhead when thickness=1.0 and opacity=1.0

Theme schema bumped to v2; v1 themes still load (new fields just unused).

Tests: 340 Python + 33 JS (was 26).
2026-05-13 22:21:20 +05:30

60 lines
2.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* OffscreenCanvas cache for expensive static draws.
*
* Use case: a theme draws the same complex pattern (scanlines, hatch, grid,
* dither) inside every node's onDrawForeground every frame. Each individual
* draw is fast, but at 60 FPS × 20 nodes × N strokes, the cost compounds.
* Render once to an OffscreenCanvas keyed by (theme-id, width, height), then
* blit with a single drawImage call on subsequent frames.
*
* Cache is attached to the node (`node._mp_pattern_cache`) so it dies with
* the node and doesn't leak across graph reloads.
*/
const HAS_OFFSCREEN = typeof OffscreenCanvas !== "undefined";
/**
* Get-or-render a cached pattern for this node.
*
* @param {Object} node The LiteGraph node.
* @param {String} themeId Used as the cache key namespace.
* @param {Number} width Pattern width (typically node.size[0]).
* @param {Number} height Pattern height (typically node.size[1]).
* @param {Function} render Callback `(ctx, width, height) => void` that draws
* the pattern onto the provided context.
* @returns The OffscreenCanvas (or HTMLCanvasElement fallback) ready to blit.
* Pass it to your main ctx via `ctx.drawImage(canvas, 0, 0)`.
*/
export function cachedPattern(node, themeId, width, height, render) {
if (width <= 0 || height <= 0) return null;
const key = `${themeId}:${width}x${height}`;
if (!node._mp_pattern_cache) node._mp_pattern_cache = {};
let entry = node._mp_pattern_cache[key];
if (entry) return entry;
const w = Math.ceil(width);
const h = Math.ceil(height);
const canvas = HAS_OFFSCREEN ? new OffscreenCanvas(w, h) : Object.assign(document.createElement("canvas"), { width: w, height: h });
const ctx = canvas.getContext("2d");
render(ctx, w, h);
// Cap cache size per node to avoid unbounded growth when nodes resize a lot.
const entries = Object.keys(node._mp_pattern_cache);
if (entries.length > 4) {
// Drop the oldest (first inserted) entry. Map insertion order is fine.
delete node._mp_pattern_cache[entries[0]];
}
node._mp_pattern_cache[key] = canvas;
return canvas;
}
/**
* Invalidate a node's pattern cache. Call when a theme changes or when the
* node is going to be re-themed.
*/
export function invalidateCache(node) {
if (node) delete node._mp_pattern_cache;
}