diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ae75aa..9382114 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [未发布 Unreleased] +- GuLuLu 的像素点击判定增加图片加载保护:图片未就绪、加载失败或被替换成无法加载的文件时不再抛错,也不会把小人误判为「整只透明、点不到」(思路来自 EndoTheDev 的 PR #22) +- GuLuLu's pixel hit-testing now guards against the image not being ready, failing to load or being replaced with an unloadable file: no more exceptions, and the sprite no longer becomes unclickable (approach from EndoTheDev's PR #22) - 资源监视器面板改为独立合成层(`will-change: transform`),它每帧重绘时不再连带重绘被它盖住的那块主画布 - The resource monitor panel now gets its own compositor layer (`will-change: transform`), so its per-frame redraw no longer forces the main canvas region beneath it to repaint - 资源监视器的数据行和顶部的工作流进度条改为只创建一次:条形每帧用 transform 平滑跟随曲线(不触发布局),文字每 100ms 更新。此前每帧重写整块 innerHTML 并新建 canvas 量字宽,每秒数百次 DOM 重建,是拖动画布时掉帧的来源之一;现在单次开销降到 0.01ms 以下 diff --git a/README.md b/README.md index 1288030..e7ea6b5 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ This is a custom node utility package developed for ComfyUI. Initially created f ## 最新更新 / Last Update ### [未发布 Unreleased] +- GuLuLu 的像素点击判定增加图片加载保护:图片未就绪、加载失败或被替换成无法加载的文件时不再抛错,也不会把小人误判为「整只透明、点不到」(思路来自 EndoTheDev 的 PR #22) +- GuLuLu's pixel hit-testing now guards against the image not being ready, failing to load or being replaced with an unloadable file: no more exceptions, and the sprite no longer becomes unclickable (approach from EndoTheDev's PR #22) - 资源监视器面板改为独立合成层(`will-change: transform`),它每帧重绘时不再连带重绘被它盖住的那块主画布 - The resource monitor panel now gets its own compositor layer (`will-change: transform`), so its per-frame redraw no longer forces the main canvas region beneath it to repaint - 资源监视器的数据行和顶部的工作流进度条改为只创建一次:条形每帧用 transform 平滑跟随曲线(不触发布局),文字每 100ms 更新。此前每帧重写整块 innerHTML 并新建 canvas 量字宽,每秒数百次 DOM 重建,是拖动画布时掉帧的来源之一;现在单次开销降到 0.01ms 以下 diff --git a/web/gululu.js b/web/gululu.js index a561d9e..1979823 100644 --- a/web/gululu.js +++ b/web/gululu.js @@ -109,6 +109,11 @@ const KayGuLuLuManager = { this.container.id = "kay-gululu-container"; const img = document.createElement("img"); img.src = this.imgSrc; + // 图片缺失或被用户换成加载不了的文件时,不要让后面的像素判定抛错 + img.onerror = () => { + console.warn("[KayTool] GuLuLu image failed to load:", img.src); + this.pixelDataCache = null; + }; img.alt = "GuLuLu"; img.onload = () => { this.updatePixelDataCache(); @@ -251,13 +256,24 @@ const KayGuLuLuManager = { if (containerRect.width === 0 || containerRect.height === 0) { return; } + // 像素判定依赖图片已经解码好;没就绪时读到的是整张透明,会让小人「点不到」, + // 坏图则会让 drawImage 直接抛 InvalidStateError。没就绪就跳过,等下次再算。 + const img = this.container?.querySelector("img"); + if (!img || !img.complete || img.naturalWidth === 0) { + this.pixelDataCache = null; + return; + } this.pixelCanvas.width = containerRect.width; this.pixelCanvas.height = containerRect.height; this.pixelCtx.clearRect(0, 0, this.pixelCanvas.width, this.pixelCanvas.height); - this.pixelCtx.drawImage(this.container.querySelector("img"), 0, 0, containerRect.width, containerRect.height); - this.pixelDataCache = this.pixelCtx.getImageData(0, 0, this.pixelCanvas.width, this.pixelCanvas.height); - - this.calculateEffectiveBounds(); + try { + this.pixelCtx.drawImage(img, 0, 0, containerRect.width, containerRect.height); + this.pixelDataCache = this.pixelCtx.getImageData(0, 0, this.pixelCanvas.width, this.pixelCanvas.height); + this.calculateEffectiveBounds(); + } catch (e) { + console.warn("[KayTool] GuLuLu pixel cache update failed:", e); + this.pixelDataCache = null; + } }, calculateEffectiveBounds() {