Commit f48bce5f authored by Danil Boldyrev's avatar Danil Boldyrev

Corrected the code according to Code style

parent 9e69009d
...@@ -3,420 +3,426 @@ ...@@ -3,420 +3,426 @@
// Helper functions // Helper functions
// Get active tab // Get active tab
function getActiveTab(elements, all = false) { function getActiveTab(elements, all = false) {
const tabs = elements.img2imgTabs.querySelectorAll("button"); const tabs = elements.img2imgTabs.querySelectorAll("button");
if (all) return tabs; if (all) return tabs;
for (let tab of tabs) { for (let tab of tabs) {
if (tab.classList.contains("selected")) { if (tab.classList.contains("selected")) {
return tab; return tab;
}
} }
}
} }
onUiLoaded(async () => { onUiLoaded(async() => {
const hotkeysConfig = { const hotkeysConfig = {
resetZoom: "KeyR", resetZoom: "KeyR",
fitToScreen: "KeyS", fitToScreen: "KeyS",
moveKey: "KeyF", moveKey: "KeyF",
overlap: "KeyO", overlap: "KeyO"
}; };
let isMoving = false; let isMoving = false;
let mouseX, mouseY; let mouseX, mouseY;
const elementIDs = { const elementIDs = {
sketch: "#img2img_sketch", sketch: "#img2img_sketch",
inpaint: "#img2maskimg", inpaint: "#img2maskimg",
inpaintSketch: "#inpaint_sketch", inpaintSketch: "#inpaint_sketch",
img2imgTabs: "#mode_img2img .tab-nav", img2imgTabs: "#mode_img2img .tab-nav"
}; };
async function getElements() { async function getElements() {
const elements = await Promise.all( const elements = await Promise.all(
Object.values(elementIDs).map((id) => document.querySelector(id)) Object.values(elementIDs).map(id => document.querySelector(id))
); );
return Object.fromEntries( return Object.fromEntries(
Object.keys(elementIDs).map((key, index) => [key, elements[index]]) Object.keys(elementIDs).map((key, index) => [key, elements[index]])
); );
}
const elements = await getElements();
function applyZoomAndPan(targetElement, elemId) {
targetElement.style.transformOrigin = "0 0";
let [zoomLevel, panX, panY] = [1, 0, 0];
let fullScreenMode = false;
// In the course of research, it was found that the tag img is very harmful when zooming and creates white canvases. This hack allows you to almost never think about this problem, it has no effect on webui.
function fixCanvas() {
const activeTab = getActiveTab(elements).textContent.trim();
if (activeTab !== "img2img") {
const img = targetElement.querySelector(`${elemId} img`);
if (img && img.style.display !== "none") {
img.style.display = "none";
img.style.visibility = "hidden";
}
}
} }
// Reset the zoom level and pan position of the target element to their initial values const elements = await getElements();
function resetZoom() {
zoomLevel = 1;
panX = 0;
panY = 0;
fixCanvas();
targetElement.style.transform = `scale(${zoomLevel}) translate(${panX}px, ${panY}px)`;
const canvas = document.querySelector(
`${elemId} canvas[key="interface"]`
);
toggleOverlap("off");
fullScreenMode = false;
if (
canvas &&
parseFloat(canvas.style.width) > 865 &&
parseFloat(targetElement.style.width) > 865
) {
fitToElement();
return;
}
targetElement.style.width = "";
if (canvas) {
targetElement.style.height = canvas.style.height;
}
}
// Toggle the zIndex of the target element between two values, allowing it to overlap or be overlapped by other elements function applyZoomAndPan(targetElement, elemId) {
function toggleOverlap(forced = "") { targetElement.style.transformOrigin = "0 0";
const zIndex1 = "0"; let [zoomLevel, panX, panY] = [1, 0, 0];
const zIndex2 = "998"; let fullScreenMode = false;
targetElement.style.zIndex = // In the course of research, it was found that the tag img is very harmful when zooming and creates white canvases. This hack allows you to almost never think about this problem, it has no effect on webui.
targetElement.style.zIndex !== zIndex2 ? zIndex2 : zIndex1; function fixCanvas() {
const activeTab = getActiveTab(elements).textContent.trim();
if (forced === "off") { if (activeTab !== "img2img") {
targetElement.style.zIndex = zIndex1; const img = targetElement.querySelector(`${elemId} img`);
} else if (forced === "on") {
targetElement.style.zIndex = zIndex2;
}
}
// Adjust the brush size based on the deltaY value from a mouse wheel event if (img && img.style.display !== "none") {
function adjustBrushSize( img.style.display = "none";
elemId, img.style.visibility = "hidden";
deltaY, }
withoutValue = false, }
percentage = 5
) {
const input =
document.querySelector(`${elemId} input[aria-label='Brush radius']`) ||
document.querySelector(`${elemId} button[aria-label="Use brush"]`);
if (input) {
input.click();
if (!withoutValue) {
const maxValue = parseFloat(input.getAttribute("max")) || 100;
const changeAmount = maxValue * (percentage / 100);
const newValue =
parseFloat(input.value) +
(deltaY > 0 ? -changeAmount : changeAmount);
input.value = Math.min(Math.max(newValue, 0), maxValue);
input.dispatchEvent(new Event("change"));
} }
}
}
// Reset zoom when uploading a new image
fileInput = document.querySelector(
`${elemId} input[type="file"][accept="image/*"].svelte-116rqfv`
);
fileInput.addEventListener("click", resetZoom);
// Update the zoom level and pan position of the target element based on the values of the zoomLevel, panX and panY variables // Reset the zoom level and pan position of the target element to their initial values
function updateZoom(newZoomLevel, mouseX, mouseY) { function resetZoom() {
newZoomLevel = Math.max(0.5, Math.min(newZoomLevel, 15)); zoomLevel = 1;
panX += mouseX - (mouseX * newZoomLevel) / zoomLevel; panX = 0;
panY += mouseY - (mouseY * newZoomLevel) / zoomLevel; panY = 0;
fixCanvas();
targetElement.style.transform = `scale(${zoomLevel}) translate(${panX}px, ${panY}px)`;
const canvas = document.querySelector(
`${elemId} canvas[key="interface"]`
);
toggleOverlap("off");
fullScreenMode = false;
if (
canvas &&
parseFloat(canvas.style.width) > 865 &&
parseFloat(targetElement.style.width) > 865
) {
fitToElement();
return;
}
targetElement.style.width = "";
if (canvas) {
targetElement.style.height = canvas.style.height;
}
}
targetElement.style.transformOrigin = "0 0"; // Toggle the zIndex of the target element between two values, allowing it to overlap or be overlapped by other elements
targetElement.style.transform = `translate(${panX}px, ${panY}px) scale(${newZoomLevel})`; function toggleOverlap(forced = "") {
const zIndex1 = "0";
const zIndex2 = "998";
toggleOverlap("on"); targetElement.style.zIndex =
return newZoomLevel; targetElement.style.zIndex !== zIndex2 ? zIndex2 : zIndex1;
}
// Change the zoom level based on user interaction if (forced === "off") {
function changeZoomLevel(operation, e) { targetElement.style.zIndex = zIndex1;
if (e.shiftKey) { } else if (forced === "on") {
e.preventDefault(); targetElement.style.zIndex = zIndex2;
}
let zoomPosX, zoomPosY;
let delta = 0.2;
if (zoomLevel > 7) {
delta = 0.9;
} else if (zoomLevel > 2) {
delta = 0.6;
} }
zoomPosX = e.clientX; // Adjust the brush size based on the deltaY value from a mouse wheel event
zoomPosY = e.clientY; function adjustBrushSize(
elemId,
deltaY,
withoutValue = false,
percentage = 5
) {
const input =
document.querySelector(
`${elemId} input[aria-label='Brush radius']`
) ||
document.querySelector(
`${elemId} button[aria-label="Use brush"]`
);
if (input) {
input.click();
if (!withoutValue) {
const maxValue =
parseFloat(input.getAttribute("max")) || 100;
const changeAmount = maxValue * (percentage / 100);
const newValue =
parseFloat(input.value) +
(deltaY > 0 ? -changeAmount : changeAmount);
input.value = Math.min(Math.max(newValue, 0), maxValue);
input.dispatchEvent(new Event("change"));
}
}
}
fullScreenMode = false; // Reset zoom when uploading a new image
zoomLevel = updateZoom( const fileInput = document.querySelector(
zoomLevel + (operation === "+" ? delta : -delta), `${elemId} input[type="file"][accept="image/*"].svelte-116rqfv`
zoomPosX - targetElement.getBoundingClientRect().left,
zoomPosY - targetElement.getBoundingClientRect().top
); );
} fileInput.addEventListener("click", resetZoom);
}
/** // Update the zoom level and pan position of the target element based on the values of the zoomLevel, panX and panY variables
* This function fits the target element to the screen by calculating function updateZoom(newZoomLevel, mouseX, mouseY) {
* the required scale and offsets. It also updates the global variables newZoomLevel = Math.max(0.5, Math.min(newZoomLevel, 15));
* zoomLevel, panX, and panY to reflect the new state. panX += mouseX - (mouseX * newZoomLevel) / zoomLevel;
*/ panY += mouseY - (mouseY * newZoomLevel) / zoomLevel;
function fitToElement() {
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const parentElement = targetElement.parentElement;
const screenWidth = parentElement.clientWidth;
const screenHeight = parentElement.clientHeight;
// Get element's coordinates relative to the parent element
const elementRect = targetElement.getBoundingClientRect();
const parentRect = parentElement.getBoundingClientRect();
const elementX = elementRect.x - parentRect.x;
// Calculate scale and offsets
const scaleX = screenWidth / elementWidth;
const scaleY = screenHeight / elementHeight;
const scale = Math.min(scaleX, scaleY);
const transformOrigin =
window.getComputedStyle(targetElement).transformOrigin;
const [originX, originY] = transformOrigin.split(" ");
const originXValue = parseFloat(originX);
const originYValue = parseFloat(originY);
const offsetX =
(screenWidth - elementWidth * scale) / 2 - originXValue * (1 - scale);
const offsetY =
(screenHeight - elementHeight * scale) / 2.5 -
originYValue * (1 - scale);
// Apply scale and offsets to the element
targetElement.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// Update global variables
zoomLevel = scale;
panX = offsetX;
panY = offsetY;
fullScreenMode = false;
toggleOverlap("off");
}
/** targetElement.style.transformOrigin = "0 0";
* This function fits the target element to the screen by calculating targetElement.style.transform = `translate(${panX}px, ${panY}px) scale(${newZoomLevel})`;
* the required scale and offsets. It also updates the global variables
* zoomLevel, panX, and panY to reflect the new state.
*/
// Fullscreen mode
function fitToScreen() {
const canvas = document.querySelector(
`${elemId} canvas[key="interface"]`
);
if (!canvas) return;
if (canvas.offsetWidth > 862) {
targetElement.style.width = canvas.offsetWidth + "px";
}
if (fullScreenMode) {
resetZoom();
fullScreenMode = false;
return;
}
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
// Get element's coordinates relative to the page
const elementRect = targetElement.getBoundingClientRect();
const elementY = elementRect.y;
const elementX = elementRect.x;
// Calculate scale and offsets
const scaleX = screenWidth / elementWidth;
const scaleY = screenHeight / elementHeight;
const scale = Math.min(scaleX, scaleY);
// Get the current transformOrigin
const computedStyle = window.getComputedStyle(targetElement);
const transformOrigin = computedStyle.transformOrigin;
const [originX, originY] = transformOrigin.split(" ");
const originXValue = parseFloat(originX);
const originYValue = parseFloat(originY);
// Calculate offsets with respect to the transformOrigin
const offsetX =
(screenWidth - elementWidth * scale) / 2 -
elementX -
originXValue * (1 - scale);
const offsetY =
(screenHeight - elementHeight * scale) / 2 -
elementY -
originYValue * (1 - scale);
// Apply scale and offsets to the element
targetElement.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// Update global variables
zoomLevel = scale;
panX = offsetX;
panY = offsetY;
fullScreenMode = true;
toggleOverlap("on");
}
// Handle keydown events toggleOverlap("on");
function handleKeyDown(event) { return newZoomLevel;
const hotkeyActions = { }
[hotkeysConfig.resetZoom]: resetZoom,
[hotkeysConfig.overlap]: toggleOverlap,
[hotkeysConfig.fitToScreen]: fitToScreen,
// [hotkeysConfig.moveKey] : moveCanvas,
};
const action = hotkeyActions[event.code];
if (action) {
event.preventDefault();
action(event);
}
}
// Get Mouse position // Change the zoom level based on user interaction
function getMousePosition(e) { function changeZoomLevel(operation, e) {
mouseX = e.offsetX; if (e.shiftKey) {
mouseY = e.offsetY; e.preventDefault();
}
let zoomPosX, zoomPosY;
let delta = 0.2;
if (zoomLevel > 7) {
delta = 0.9;
} else if (zoomLevel > 2) {
delta = 0.6;
}
zoomPosX = e.clientX;
zoomPosY = e.clientY;
fullScreenMode = false;
zoomLevel = updateZoom(
zoomLevel + (operation === "+" ? delta : -delta),
zoomPosX - targetElement.getBoundingClientRect().left,
zoomPosY - targetElement.getBoundingClientRect().top
);
}
}
/**
* This function fits the target element to the screen by calculating
* the required scale and offsets. It also updates the global variables
* zoomLevel, panX, and panY to reflect the new state.
*/
function fitToElement() {
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const parentElement = targetElement.parentElement;
const screenWidth = parentElement.clientWidth;
const screenHeight = parentElement.clientHeight;
// Get element's coordinates relative to the parent element
const elementRect = targetElement.getBoundingClientRect();
const parentRect = parentElement.getBoundingClientRect();
const elementX = elementRect.x - parentRect.x;
// Calculate scale and offsets
const scaleX = screenWidth / elementWidth;
const scaleY = screenHeight / elementHeight;
const scale = Math.min(scaleX, scaleY);
const transformOrigin =
window.getComputedStyle(targetElement).transformOrigin;
const [originX, originY] = transformOrigin.split(" ");
const originXValue = parseFloat(originX);
const originYValue = parseFloat(originY);
const offsetX =
(screenWidth - elementWidth * scale) / 2 -
originXValue * (1 - scale);
const offsetY =
(screenHeight - elementHeight * scale) / 2.5 -
originYValue * (1 - scale);
// Apply scale and offsets to the element
targetElement.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// Update global variables
zoomLevel = scale;
panX = offsetX;
panY = offsetY;
fullScreenMode = false;
toggleOverlap("off");
}
targetElement.addEventListener("mousemove", getMousePosition); /**
* This function fits the target element to the screen by calculating
* the required scale and offsets. It also updates the global variables
* zoomLevel, panX, and panY to reflect the new state.
*/
// Fullscreen mode
function fitToScreen() {
const canvas = document.querySelector(
`${elemId} canvas[key="interface"]`
);
if (!canvas) return;
if (canvas.offsetWidth > 862) {
targetElement.style.width = canvas.offsetWidth + "px";
}
if (fullScreenMode) {
resetZoom();
fullScreenMode = false;
return;
}
//Reset Zoom
targetElement.style.transform = `translate(${0}px, ${0}px) scale(${1})`;
// Get element and screen dimensions
const elementWidth = targetElement.offsetWidth;
const elementHeight = targetElement.offsetHeight;
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
// Get element's coordinates relative to the page
const elementRect = targetElement.getBoundingClientRect();
const elementY = elementRect.y;
const elementX = elementRect.x;
// Calculate scale and offsets
const scaleX = screenWidth / elementWidth;
const scaleY = screenHeight / elementHeight;
const scale = Math.min(scaleX, scaleY);
// Get the current transformOrigin
const computedStyle = window.getComputedStyle(targetElement);
const transformOrigin = computedStyle.transformOrigin;
const [originX, originY] = transformOrigin.split(" ");
const originXValue = parseFloat(originX);
const originYValue = parseFloat(originY);
// Calculate offsets with respect to the transformOrigin
const offsetX =
(screenWidth - elementWidth * scale) / 2 -
elementX -
originXValue * (1 - scale);
const offsetY =
(screenHeight - elementHeight * scale) / 2 -
elementY -
originYValue * (1 - scale);
// Apply scale and offsets to the element
targetElement.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
// Update global variables
zoomLevel = scale;
panX = offsetX;
panY = offsetY;
fullScreenMode = true;
toggleOverlap("on");
}
// Handle events only inside the targetElement // Handle keydown events
let isKeyDownHandlerAttached = false; function handleKeyDown(event) {
const hotkeyActions = {
[hotkeysConfig.resetZoom]: resetZoom,
[hotkeysConfig.overlap]: toggleOverlap,
[hotkeysConfig.fitToScreen]: fitToScreen
// [hotkeysConfig.moveKey] : moveCanvas,
};
const action = hotkeyActions[event.code];
if (action) {
event.preventDefault();
action(event);
}
}
function handleMouseMove() { // Get Mouse position
if (!isKeyDownHandlerAttached) { function getMousePosition(e) {
document.addEventListener("keydown", handleKeyDown); mouseX = e.offsetX;
isKeyDownHandlerAttached = true; mouseY = e.offsetY;
} }
}
function handleMouseLeave() { targetElement.addEventListener("mousemove", getMousePosition);
if (isKeyDownHandlerAttached) {
document.removeEventListener("keydown", handleKeyDown); // Handle events only inside the targetElement
isKeyDownHandlerAttached = false; let isKeyDownHandlerAttached = false;
}
}
// Add mouse event handlers function handleMouseMove() {
targetElement.addEventListener("mousemove", handleMouseMove); if (!isKeyDownHandlerAttached) {
targetElement.addEventListener("mouseleave", handleMouseLeave); document.addEventListener("keydown", handleKeyDown);
isKeyDownHandlerAttached = true;
// Reset zoom when click on another tab }
elements.img2imgTabs.addEventListener("click", resetZoom);
elements.img2imgTabs.addEventListener("click", () => {
// targetElement.style.width = "";
if (parseInt(targetElement.style.width) > 865) {
setTimeout(fitToElement, 0);
}
});
targetElement.addEventListener("wheel", (e) => {
// change zoom level
const operation = e.deltaY > 0 ? "-" : "+";
changeZoomLevel(operation, e);
// Handle brush size adjustment with ctrl key pressed
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
// Increase or decrease brush size based on scroll direction
adjustBrushSize(elemId, e.deltaY);
}
});
/**
* Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element.
* @param {MouseEvent} e - The mouse event.
*/
function handleMoveKeyDown(e) {
if (e.code === hotkeysConfig.moveKey) {
if (!e.ctrlKey && !e.metaKey) {
isMoving = true;
} }
}
}
function handleMoveKeyUp(e) { function handleMouseLeave() {
if (e.code === hotkeysConfig.moveKey) { if (isKeyDownHandlerAttached) {
isMoving = false; document.removeEventListener("keydown", handleKeyDown);
} isKeyDownHandlerAttached = false;
} }
}
document.addEventListener("keydown", handleMoveKeyDown); // Add mouse event handlers
document.addEventListener("keyup", handleMoveKeyUp); targetElement.addEventListener("mousemove", handleMouseMove);
targetElement.addEventListener("mouseleave", handleMouseLeave);
// Reset zoom when click on another tab
elements.img2imgTabs.addEventListener("click", resetZoom);
elements.img2imgTabs.addEventListener("click", () => {
// targetElement.style.width = "";
if (parseInt(targetElement.style.width) > 865) {
setTimeout(fitToElement, 0);
}
});
targetElement.addEventListener("wheel", e => {
// change zoom level
const operation = e.deltaY > 0 ? "-" : "+";
changeZoomLevel(operation, e);
// Handle brush size adjustment with ctrl key pressed
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
// Increase or decrease brush size based on scroll direction
adjustBrushSize(elemId, e.deltaY);
}
});
/**
* Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element.
* @param {MouseEvent} e - The mouse event.
*/
function handleMoveKeyDown(e) {
if (e.code === hotkeysConfig.moveKey) {
if (!e.ctrlKey && !e.metaKey) {
isMoving = true;
}
}
}
// Detect zoom level and update the pan speed. function handleMoveKeyUp(e) {
function updatePanPosition(movementX, movementY) { if (e.code === hotkeysConfig.moveKey) {
let panSpeed = 1.5; isMoving = false;
}
}
if (zoomLevel > 8) { document.addEventListener("keydown", handleMoveKeyDown);
panSpeed = 2.5; document.addEventListener("keyup", handleMoveKeyUp);
}
panX = panX + movementX * panSpeed; // Detect zoom level and update the pan speed.
panY = panY + movementY * panSpeed; function updatePanPosition(movementX, movementY) {
let panSpeed = 1.5;
targetElement.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`; if (zoomLevel > 8) {
toggleOverlap("on"); panSpeed = 2.5;
} }
function handleMoveByKey(e) { panX = panX + movementX * panSpeed;
if (isMoving) { panY = panY + movementY * panSpeed;
updatePanPosition(e.movementX, e.movementY);
targetElement.style.pointerEvents = "none";
} else {
targetElement.style.pointerEvents = "auto";
}
}
document.addEventListener("mousemove", handleMoveByKey); targetElement.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`;
} toggleOverlap("on");
}
function handleMoveByKey(e) {
if (isMoving) {
updatePanPosition(e.movementX, e.movementY);
targetElement.style.pointerEvents = "none";
} else {
targetElement.style.pointerEvents = "auto";
}
}
document.addEventListener("mousemove", handleMoveByKey);
}
applyZoomAndPan(elements.sketch, elementIDs.sketch); applyZoomAndPan(elements.sketch, elementIDs.sketch);
applyZoomAndPan(elements.inpaint, elementIDs.inpaint); applyZoomAndPan(elements.inpaint, elementIDs.inpaint);
applyZoomAndPan(elements.inpaintSketch, elementIDs.inpaintSketch); applyZoomAndPan(elements.inpaintSketch, elementIDs.inpaintSketch);
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment