Files
2026-07-17 04:02:11 +08:00

287 lines
5.8 KiB
JavaScript
Raw Permalink 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.
import { app } from "../../scripts/app.js";
let panel;
let img;
let info;
let mini;
let executing = false;
let userClosed = false;
let scale = 1;
let offsetX = 0;
let offsetY = 0;
// Create the preview window
function createPreview() {
panel = document.createElement("div");
Object.assign(panel.style, {
position: "fixed",
left: "120px",
top: "120px",
width: "800px",
height: "700px",
background: "#111",
border: "1px solid #777",
zIndex: 99999,
resize: "both",
overflow: "hidden",
display: "none",
flexDirection: "column"
});
// Title bar
let header = document.createElement("div");
Object.assign(header.style, {
height: "35px",
background: "#222",
color: "white",
cursor: "move",
padding: "5px",
userSelect: "none"
});
header.innerHTML = "";
header.appendChild(document.createTextNode("HD Preview"));
let close = document.createElement("button");
close.innerText = "×";
Object.assign(close.style, {
float: "right",
width: "30px"
});
close.onclick = (e) => {
e.stopPropagation();
panel.style.display = "none";
mini.style.display = "block";
userClosed = true;
};
header.appendChild(close);
// Content area
let content = document.createElement("div");
Object.assign(content.style, {
flex: "1",
overflow: "hidden",
display: "flex",
justifyContent: "center",
alignItems: "center"
});
img = document.createElement("img");
Object.assign(img.style, {
maxWidth: "100%",
maxHeight: "100%",
cursor: "grab",
transformOrigin: "center"
});
content.appendChild(img);
info = document.createElement("div");
Object.assign(info.style, {
height: "25px",
color: "white"
});
panel.appendChild(header);
panel.appendChild(content);
panel.appendChild(info);
document.body.appendChild(panel);
// Window dragging
let moving = false;
let moveStartX = 0;
let moveStartY = 0;
let panelStartX = 0;
let panelStartY = 0;
header.addEventListener("pointerdown", (e) => {
if (e.target === close) return;
moving = true;
moveStartX = e.clientX;
moveStartY = e.clientY;
panelStartX = panel.offsetLeft;
panelStartY = panel.offsetTop;
header.setPointerCapture(e.pointerId);
header.style.cursor = "grabbing";
e.preventDefault();
e.stopPropagation();
});
header.addEventListener("pointermove", (e) => {
if (!moving) return;
let dx = e.clientX - moveStartX;
let dy = e.clientY - moveStartY;
panel.style.left = panelStartX + dx + "px";
panel.style.top = panelStartY + dy + "px";
});
header.addEventListener("pointerup", (e) => {
moving = false;
header.style.cursor = "move";
try {
header.releasePointerCapture(e.pointerId);
} catch (err) {}
});
// Image zoom
img.addEventListener("wheel", (e) => {
e.preventDefault();
scale *= e.deltaY < 0 ? 1.1 : 0.9;
scale = Math.max(0.2, Math.min(scale, 5));
updateImage();
});
// Image drag
let dragImg = false;
let lastX;
let lastY;
img.addEventListener("mousedown", (e) => {
dragImg = true;
lastX = e.clientX;
lastY = e.clientY;
img.style.cursor = "grabbing";
});
document.addEventListener("mousemove", (e) => {
if (!dragImg) return;
offsetX += e.clientX - lastX;
offsetY += e.clientY - lastY;
lastX = e.clientX;
lastY = e.clientY;
updateImage();
});
document.addEventListener("mouseup", () => {
dragImg = false;
if (img) img.style.cursor = "grab";
});
img.ondblclick = () => {
scale = 1;
offsetX = 0;
offsetY = 0;
updateImage();
};
// Mini floating button
mini = document.createElement("button");
mini.innerText = "HD";
Object.assign(mini.style, {
position: "fixed",
left: "30px",
top: "30px",
width: "60px",
height: "60px",
borderRadius: "50%",
zIndex: 100000
});
// Mini button interactions
let miniMoving = false;
let miniDragged = false;
let miniStartX = 0;
let miniStartY = 0;
let miniStartLeft = 0;
let miniStartTop = 0;
mini.addEventListener("click", () => {
if (miniDragged) {
miniDragged = false;
return;
}
panel.style.display = "flex";
mini.style.display = "none";
userClosed = false;
});
mini.addEventListener("mousedown", (e) => {
miniMoving = true;
miniDragged = false;
miniStartX = e.clientX;
miniStartY = e.clientY;
miniStartLeft = mini.offsetLeft;
miniStartTop = mini.offsetTop;
e.preventDefault();
});
document.addEventListener("mousemove", (e) => {
if (!miniMoving) return;
let dx = e.clientX - miniStartX;
let dy = e.clientY - miniStartY;
if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
miniDragged = true;
}
mini.style.left = miniStartLeft + dx + "px";
mini.style.top = miniStartTop + dy + "px";
});
document.addEventListener("mouseup", () => {
miniMoving = false;
});
document.body.appendChild(mini);
}
function updateImage() {
img.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
}
app.registerExtension({
name: "HighPreviewKSampler",
async setup() {
createPreview();
app.api.addEventListener("execution_start", () => {
executing = true;
// Do not reset userClosed here
panel.style.display = "flex";
mini.style.display = "none";
});
app.api.addEventListener("high_preview", (e) => {
let data = e.detail;
if (executing && !userClosed) {
panel.style.display = "flex";
mini.style.display = "none";
}
img.src = "data:image/png;base64," + data.image;
info.innerText = `Step ${data.step}/${data.total}`;
});
app.api.addEventListener("execution_success", () => {
executing = false;
if (panel.style.display === "none") {
mini.style.display = "block";
}
});
}
});