diff --git a/webshit/index.html b/webshit/index.html
index 4f55215..c98f1c0 100644
--- a/webshit/index.html
+++ b/webshit/index.html
@@ -271,12 +271,20 @@ function onObjectInfo(json) {
this.addInput(x, type);
}
- MyNode.prototype.getExtraMenuOptions = function(graph, options) {
- if(this.img) {
- options.unshift({
- content: "Open Image",
- callback: () => window.open(this.img.src, "_blank")
- });
+ MyNode.prototype.getExtraMenuOptions = function(canvas, options) {
+ if(this.imgs) {
+ let img;
+ if(this.imageIndex != null) {
+ img = this.imgs[this.imageIndex];
+ } else if(this.overIndex != null) {
+ img = this.imgs[this.overIndex];
+ }
+ if(img) {
+ options.unshift({
+ content: "Open Image",
+ callback: () => window.open(img.src, "_blank")
+ });
+ }
}
}
@@ -284,45 +292,167 @@ function onObjectInfo(json) {
if(!this.flags.collapsed) {
const output = nodeOutputs[this.id + ""];
if(output && output.images) {
- const src = output.images[0];
- if(this.src !== src) {
- this.img = null;
- this.src = src;
- const img = new Image();
- img.src = "/view/" + src;
- img.onload = () => {
- graph.setDirtyCanvas(true);
- this.img = img;
- if(this.size[1] < 100) {
- this.size[1] = 250;
+ if(this.images !== output.images) {
+ this.images = output.images;
+ this.imgs = null;
+ this.imageIndex = null;
+ Promise.all(output.images.map(src => {
+ return new Promise(r => {
+ const img = new Image();
+ img.onload = () => r(img);
+ img.onerror = () => r(null);
+ img.src = "/view/" + src;
+ });
+ })).then(imgs => {
+ if(this.images === output.images) {
+ this.imgs = imgs.filter(Boolean);
+ if(this.size[1] < 100) {
+ this.size[1] = 250;
+ }
+ graph.setDirtyCanvas(true);
}
- }
+ });
}
- if(this.img) {
- let w = this.img.naturalWidth;
- let h = this.img.naturalHeight;
- let dw = this.size[0];
- let dh = this.size[1];
-
- if(this.type === "SaveImage") {
- dh -= 55;
+
+ if(this.imgs) {
+ const canvas = graph.list_of_graphcanvas[0];
+ const mouse = canvas.graph_mouse;
+ if(!canvas.pointer_is_down && this.pointerDown) {
+ if(mouse[0] === this.pointerDown.pos[0] && mouse[1] === this.pointerDown.pos[1]) {
+ this.imageIndex = this.pointerDown.index;
+ }
+ this.pointerDown = null;
}
- const scaleX = dw / w;
- const scaleY = dh / h;
- const scale = Math.min(scaleX, scaleY, 1);
+ let w = this.imgs[0].naturalWidth;
+ let h = this.imgs[0].naturalHeight;
+ let imageIndex = this.imageIndex;
+ const numImages = this.imgs.length;
+ if(numImages === 1 && !imageIndex) {
+ this.imageIndex = imageIndex = 0;
+ }
+ let shiftY = this.type === "SaveImage" ? 55 : 0;
+ let dw = this.size[0];
+ let dh = this.size[1];
+ dh -= shiftY;
+
+ if(imageIndex == null) {
+ let best = 0;
+ let cellWidth;
+ let cellHeight;
+ let cols = 0;
+ let shiftX = 0;
+ for (let c = 1; c <= numImages; c++) {
+ const rows = Math.ceil(numImages / c);
+ const cW = dw / c;
+ const cH = dh / rows;
+ const scaleX = cW / w;
+ const scaleY = cH / h;
+
+ const scale = Math.min(scaleX, scaleY, 1);
+ const imageW = w * scale;
+ const imageH = h * scale;
+ const area = imageW * imageH * numImages;
+
+ if(area > best) {
+ best = area;
+ cellWidth = imageW;
+ cellHeight = imageH;
+ cols = c;
+ shiftX = c * ((cW - imageW) / 2);
+ }
+ }
- w *= scale;
- h *= scale;
+ let anyHovered = false;
+ this.imageRects = [];
+ for (let i = 0; i < numImages; i++) {
+ const img = this.imgs[i];
+ const row = Math.floor(i / cols);
+ const col = i % cols;
+ const x = col * cellWidth + shiftX;
+ const y = row * cellHeight + shiftY;
+ if(!anyHovered) {
+ anyHovered = LiteGraph.isInsideRectangle(mouse[0], mouse[1], x + this.pos[0], y + this.pos[1], cellWidth, cellHeight);
+ if(anyHovered) {
+ this.overIndex = i;
+ let value = 110;
+ if(canvas.pointer_is_down) {
+ if(!this.pointerDown || this.pointerDown.index !== i) {
+ this.pointerDown = {index: i, pos: [...mouse]};
+ }
+ value = 125;
+ }
+ ctx.filter = `contrast(${value}%) brightness(${value}%)`;
+ canvas.canvas.style.cursor = "pointer";
+ }
+ }
+ this.imageRects.push([x, y, cellWidth, cellHeight]);
+ ctx.drawImage(img, x, y, cellWidth, cellHeight);
+ ctx.filter = "none";
+ }
- let x = (dw - w) / 2;
- let y = (dh - h) / 2;
+ if(!anyHovered) {
+ this.pointerDown = null;
+ this.overIndex = null;
+ }
+ } else {
+ // Draw individual
+ const scaleX = dw / w;
+ const scaleY = dh / h;
+ const scale = Math.min(scaleX, scaleY, 1);
+
+ w *= scale;
+ h *= scale;
+
+ let x = (dw - w) / 2;
+ let y = (dh - h) / 2 + shiftY;
+ ctx.drawImage(this.imgs[imageIndex], x, y, w, h);
+
+ const drawButton = (x, y, sz, text) => {
+ const hovered = LiteGraph.isInsideRectangle(mouse[0], mouse[1], x + this.pos[0], y + this.pos[1], sz, sz);
+ let fill = "#333";
+ let textFill = "#fff";
+ let isClicking = false;
+ if(hovered) {
+ canvas.canvas.style.cursor = "pointer";
+ if(canvas.pointer_is_down) {
+ fill = "#1e90ff";
+ isClicking = true;
+ } else {
+ fill = "#eee";
+ textFill = "#000";
+ }
+ } else {
+ this.pointerWasDown = null;
+ }
+
+ ctx.fillStyle = fill;
+ ctx.beginPath();
+ ctx.roundRect(x, y, sz, sz, [4]);
+ ctx.fill();
+ ctx.fillStyle = textFill;
+ ctx.font = "12px Arial";
+ ctx.textAlign = "center";
+ ctx.fillText(text, x + 15, y + 20);
+
+ return isClicking;
+ }
- if(this.type === "SaveImage") {
- y += 55;
+ if(numImages > 1) {
+ if(drawButton(x + w - 35, y + h - 35, 30, `${this.imageIndex+1}/${numImages}`)) {
+ let i = this.imageIndex + 1 >= numImages ? 0 : this.imageIndex + 1;
+ if(!this.pointerDown || !this.pointerDown.index === i) {
+ this.pointerDown = {index: i, pos: [...mouse]};
+ }
+ }
+
+ if(drawButton(x + w - 35, y + 5, 30, `x`)) {
+ if(!this.pointerDown || !this.pointerDown.index === null) {
+ this.pointerDown = {index: null, pos: [...mouse]};
+ }
+ }
+ }
}
-
- ctx.drawImage(this.img, x, y, w, h);
}
}
}