diff --git a/js/resize_dither.js b/js/resize_dither.js index 39ce061..a5c9b27 100644 --- a/js/resize_dither.js +++ b/js/resize_dither.js @@ -146,6 +146,7 @@ app.registerExtension({ controlLayout: null, vgaPalette: [...FALLBACK_PALETTE], binaryToPaletteLut: null, + bootstrapRevision: 0, findWidget: function (name) { return this.widgets?.find((w) => w.name === name); @@ -719,6 +720,9 @@ api.addEventListener("game_dev.resize_dither.initialise", ({ detail }) => { return; } + node.bootstrapRevision = (node.bootstrapRevision || 0) + 1; + const revision = node.bootstrapRevision; + if (Number.isFinite(detail.width)) { node.setWidgetValue("width", clamp(toInt(detail.width, 256), 1, MAX_DIMENSION)); } @@ -736,6 +740,10 @@ api.addEventListener("game_dev.resize_dither.initialise", ({ detail }) => { } const onBeforeLoad = () => { + if (revision !== node.bootstrapRevision) { + return; + } + if (!node.hasUserResizedNode && node.originalImage) { const aspectRatio = node.originalImage.naturalWidth / node.originalImage.naturalHeight; node.size[0] = NODE_BASE_WIDTH; @@ -759,14 +767,25 @@ api.addEventListener("game_dev.resize_dither.initialise", ({ detail }) => { const afterImg = new Image(); afterImg.src = "data:image/png;base64," + detail.preview_after; afterImg.onload = () => { - node.imagePreview = afterImg; - node.setDirtyCanvas(true, true); + if (revision !== node.bootstrapRevision) { + return; + } + + // Only use backend after-preview as a temporary fallback before source pixels are ready. + if (!node.sourcePixelData || !node.originalImage) { + node.imagePreview = afterImg; + node.setDirtyCanvas(true, true); + } }; } const beforeImg = new Image(); beforeImg.src = "data:image/png;base64," + detail.preview_before; beforeImg.onload = () => { + if (revision !== node.bootstrapRevision) { + return; + } + node.originalImage = beforeImg; onBeforeLoad(); };