From 7eda3319de61525743bc47d56d5b9f43b24017d9 Mon Sep 17 00:00:00 2001 From: Danil Boldyrev Date: Thu, 1 Feb 2024 15:43:01 +0300 Subject: [PATCH] Remove unused code and lint --- .../canvas-zoom-and-pan/javascript/zoom.js | 386 +++++------------- .../scripts/hotkey_config.py | 1 - 2 files changed, 105 insertions(+), 282 deletions(-) diff --git a/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js b/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js index 3e2875e98..6ce599659 100644 --- a/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js +++ b/extensions-builtin/canvas-zoom-and-pan/javascript/zoom.js @@ -18,13 +18,13 @@ onUiLoaded(async() => { function debounce(func, wait) { let timeout; - + return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; - + clearTimeout(timeout); timeout = setTimeout(later, wait); }; @@ -179,48 +179,6 @@ onUiLoaded(async() => { return config; } - /** - * The restoreImgRedMask function displays a red mask around an image to indicate the aspect ratio. - * If the image display property is set to 'none', the mask breaks. To fix this, the function - * temporarily sets the display property to 'block' and then hides the mask again after 300 milliseconds - * to avoid breaking the canvas. Additionally, the function adjusts the mask to work correctly on - * very long images. - */ - function restoreImgRedMask(elements) { - const mainTabId = getTabId(elements); - - if (!mainTabId) return; - - const mainTab = gradioApp().querySelector(mainTabId); - const img = mainTab.querySelector("img"); - const imageARPreview = gradioApp().querySelector("#imageARPreview"); - - if (!img || !imageARPreview) return; - - imageARPreview.style.transform = ""; - if (parseFloat(mainTab.style.width) > 865) { - const transformString = mainTab.style.transform; - const scaleMatch = transformString.match( - /scale\(([-+]?[0-9]*\.?[0-9]+)\)/ - ); - let zoom = 1; // default zoom - - if (scaleMatch && scaleMatch[1]) { - zoom = Number(scaleMatch[1]); - } - - imageARPreview.style.transformOrigin = "0 0"; - imageARPreview.style.transform = `scale(${zoom})`; - } - - if (img.style.display !== "none") return; - - img.style.display = "block"; - - setTimeout(() => { - img.style.display = "none"; - }, 400); - } const hotkeysConfigOpts = await waitForOpts(); @@ -236,7 +194,6 @@ onUiLoaded(async() => { canvas_hotkey_grow_brush: "KeyW", canvas_disabled_functions: [], canvas_show_tooltip: true, - canvas_auto_expand: true, canvas_blur_prompt: false, }; @@ -275,18 +232,6 @@ onUiLoaded(async() => { ); const elemData = {}; - // Apply functionality to the range inputs. Restore redmask and correct for long images. - const rangeInputs = elements.rangeGroup ? - Array.from(elements.rangeGroup.querySelectorAll("input")) : - [ - gradioApp().querySelector("#img2img_width input[type='range']"), - gradioApp().querySelector("#img2img_height input[type='range']") - ]; - - for (const input of rangeInputs) { - input?.addEventListener("input", () => restoreImgRedMask(elements)); - } - function applyZoomAndPan(elemId, isExtension = true) { const targetElement = gradioApp().querySelector(elemId); @@ -306,13 +251,12 @@ onUiLoaded(async() => { // Remove border, cause bags - const canvasBorder = targetElement.querySelector(".border") - canvasBorder.style.display = "none" + const canvasBorder = targetElement.querySelector(".border"); + canvasBorder.style.display = "none"; // Create tooltip function createTooltip() { - const toolTipElemnt = - targetElement.querySelector(".image-container"); + const toolTipElemnt = targetElement.querySelector(".image-container"); const tooltip = document.createElement("div"); tooltip.className = "canvas-tooltip"; @@ -375,25 +319,15 @@ onUiLoaded(async() => { // Add a hint element to the target element toolTipElemnt.appendChild(tooltip); + + return tooltip; } //Show tool tip if setting enable - if (hotkeysConfig.canvas_show_tooltip) { - createTooltip(); - } + const canvasTooltip = createTooltip(); - // 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"; - } - } + if (!hotkeysConfig.canvas_show_tooltip) { + canvasTooltip.style.display = "none"; } // Reset the zoom level and pan position of the target element to their initial values @@ -410,7 +344,6 @@ onUiLoaded(async() => { targetElement.isZoomed = false; - fixCanvas(); targetElement.style.transform = `scale(${elemData[elemId].zoomLevel}) translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px)`; const canvas = gradioApp().querySelector( @@ -425,29 +358,6 @@ onUiLoaded(async() => { closeBtn.addEventListener("click", resetZoom); } - if (canvas && isExtension) { - const parentElement = targetElement.closest('[id^="component-"]'); - if ( - canvas && - parseFloat(canvas.style.width) > parentElement.offsetWidth && - parseFloat(targetElement.style.width) > parentElement.offsetWidth - ) { - fitToElement(); - return; - } - - } - - if ( - canvas && - !isExtension && - parseFloat(canvas.style.width) > 865 && - parseFloat(targetElement.style.width) > 865 - ) { - fitToElement(); - return; - } - targetElement.style.width = ""; } @@ -501,7 +411,7 @@ onUiLoaded(async() => { `${elemId} .upload-container input[type="file"][accept="image/*"]` ); 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 function updateZoom(newZoomLevel, mouseX, mouseY) { @@ -551,67 +461,6 @@ onUiLoaded(async() => { } } - /** - * 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})`; - - let parentElement; - - if (isExtension) { - parentElement = targetElement.closest('[id^="component-"]'); - } else { - parentElement = targetElement.parentElement; - } - - - // Get element and screen dimensions - const elementWidth = targetElement.offsetWidth; - const elementHeight = targetElement.offsetHeight; - - 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 - elemData[elemId].zoomLevel = scale; - elemData[elemId].panX = offsetX; - elemData[elemId].panY = offsetY; - - fullScreenMode = false; - toggleOverlap("off"); - } - /** * This function fits the target element to the screen by calculating * the required scale and offsets. It also updates the global variables @@ -759,26 +608,6 @@ onUiLoaded(async() => { targetElement.addEventListener("mousemove", getMousePosition); - //observers - // Creating an observer with a callback function to handle DOM changes - const observer = new MutationObserver((mutationsList, observer) => { - for (let mutation of mutationsList) { - // If the style attribute of the canvas has changed, by observation it happens only when the picture changes - if (mutation.type === 'attributes' && mutation.attributeName === 'style' && - mutation.target.tagName.toLowerCase() === 'canvas') { - targetElement.isExpanded = false; - setTimeout(resetZoom, 10); - } - } - }); - - // Apply auto expand if enabled - if (hotkeysConfig.canvas_auto_expand) { - targetElement.addEventListener("mousemove", autoExpand); - // Set up an observer to track attribute changes - observer.observe(targetElement, {attributes: true, childList: true, subtree: true}); - } - // Handle events only inside the targetElement let isKeyDownHandlerAttached = false; @@ -806,12 +635,6 @@ onUiLoaded(async() => { // 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 @@ -873,7 +696,7 @@ onUiLoaded(async() => { elemData[elemId].panY += movementY * panSpeed; // Delayed redraw of an element - const canvas = targetElement.querySelector("canvas") + const canvas = targetElement.querySelector("canvas"); requestAnimationFrame(() => { targetElement.style.transform = `translate(${elemData[elemId].panX}px, ${elemData[elemId].panY}px) scale(${elemData[elemId].zoomLevel})`; toggleOverlap("on"); @@ -932,105 +755,105 @@ onUiLoaded(async() => { gradioApp().addEventListener("mousemove", handleMoveByKey); - - // Cursor manipulation script for a painting application. - // The purpose of this code is to create custom cursors (for painting and erasing) - // that can change depending on which button the user presses. - // When the mouse moves over the canvas, the appropriate custom cursor also moves, - // replicating its appearance dynamically based on various CSS properties. - // This is done because the original cursor is tied to the size of the kanvas, it can not be changed, so I came up with a hack that creates an exact copy that works properly + // Cursor manipulation script for a painting application. + // The purpose of this code is to create custom cursors (for painting and erasing) + // that can change depending on which button the user presses. + // When the mouse moves over the canvas, the appropriate custom cursor also moves, + // replicating its appearance dynamically based on various CSS properties. - function copySpecificStyles(sourceElement, targetElement) { + // This is done because the original cursor is tied to the size of the kanvas, it can not be changed, so I came up with a hack that creates an exact copy that works properly + + function copySpecificStyles(sourceElement, targetElement) { // List of CSS property names that we want to clone. - const stylesToCopy = ['top', 'left', 'width', 'height',"opacity"]; + const stylesToCopy = ['top', 'left', 'width', 'height', "opacity"]; - // For each style in our list, copy it from sourceElement to targetElement. - stylesToCopy.forEach(styleName => { - if (sourceElement.style[styleName]) { - targetElement.style[styleName] = sourceElement.style[styleName]; - } + // For each style in our list, copy it from sourceElement to targetElement. + stylesToCopy.forEach(styleName => { + if (sourceElement.style[styleName]) { + targetElement.style[styleName] = sourceElement.style[styleName]; + } + }); + } + + const eraseButton = targetElement.querySelector(`button[aria-label='Erase button']`); + const paintButton = targetElement.querySelector(`button[aria-label='Draw button']`); + + const canvasCursors = targetElement.querySelectorAll("span.svelte-btgkrd"); + const paintCursorCopy = canvasCursors[0].cloneNode(true); + const eraserCursorCopy = canvasCursors[1].cloneNode(true); + + canvasCursors.forEach(cursor => cursor.style.display = "none"); + + targetElement.appendChild(paintCursorCopy); + paintCursorCopy.style.display = "none"; + + targetElement.appendChild(eraserCursorCopy); + eraserCursorCopy.style.display = "none"; + + let activeCursor; + + paintButton.addEventListener('click', () => { + activateTool(paintButton, eraseButton, paintCursorCopy); }); - } - const eraseButton = targetElement.querySelector(`button[aria-label='Erase button']`); - const paintButton = targetElement.querySelector(`button[aria-label='Draw button']`); + eraseButton.addEventListener('click', () => { + activateTool(eraseButton, paintButton, eraserCursorCopy); + }); - const canvasCursors = targetElement.querySelectorAll("span.svelte-btgkrd"); - const paintCursorCopy = canvasCursors[0].cloneNode(true); - const eraserCursorCopy = canvasCursors[1].cloneNode(true); + function activateTool(activeButton, inactiveButton, activeCursorCopy) { + activeButton.classList.add("active"); + inactiveButton.classList.remove("active"); - canvasCursors.forEach(cursor => cursor.style.display = "none"); + if (activeCursor) { + activeCursor.style.display = "none"; + } - targetElement.appendChild(paintCursorCopy); - paintCursorCopy.style.display = "none"; - - targetElement.appendChild(eraserCursorCopy); - eraserCursorCopy.style.display = "none"; - - let activeCursor; - - paintButton.addEventListener('click', () => { - activateTool(paintButton, eraseButton, paintCursorCopy); - }); - - eraseButton.addEventListener('click', () => { - activateTool(eraseButton, paintButton, eraserCursorCopy); - }); - - function activateTool(activeButton, inactiveButton, activeCursorCopy) { - activeButton.classList.add("active"); - inactiveButton.classList.remove("active"); - - if (activeCursor){ - activeCursor.style.display = "none"; - } - - activeCursor = activeCursorCopy; - activeCursor.style.display = "block"; - } - - const canvasAreaEventsHandler = e => { - if (!activeCursor) return; - - const cursorNum = eraseButton.classList.contains("active") ? 1 : 0; - - // Update the styles of the currently active cursor - copySpecificStyles(canvasCursors[cursorNum], activeCursor); - - let offsetXAdjusted = e.offsetX; - let offsetYAdjusted = e.offsetY; - - // Position the cursor based on the current mouse coordinates within target element. - activeCursor.style.transform = - `translate(${offsetXAdjusted}px, ${offsetYAdjusted}px)`; - }; - - const canvasAreaLeaveHandler = () => { - if (activeCursor) { - activeCursor.style.display = "none"; - // Hide the cursor when mouse leaves. - activeCursor.style.opacity = 0; - } - } - - const canvasAreaEnterHandler= () => { - if (activeCursor) { + activeCursor = activeCursorCopy; activeCursor.style.display = "block"; - // Show the cursor when mouse enters. - activeCursor.style.opacity = 1; } - } - const canvasArea = targetElement.querySelector("canvas"); + const canvasAreaEventsHandler = e => { + if (!activeCursor) return; - // Attach event listeners to the target element and canvas area - targetElement.addEventListener("mousemove", canvasAreaEventsHandler); - canvasArea.addEventListener("mouseout", canvasAreaLeaveHandler); - canvasArea.addEventListener("mouseenter", canvasAreaEnterHandler); + const cursorNum = eraseButton.classList.contains("active") ? 1 : 0; - // Additional listener for handling zoom or other transformations which might affect visual representation - targetElement.addEventListener("wheel", canvasAreaEventsHandler); + // Update the styles of the currently active cursor + copySpecificStyles(canvasCursors[cursorNum], activeCursor); + + let offsetXAdjusted = e.offsetX; + let offsetYAdjusted = e.offsetY; + + // Position the cursor based on the current mouse coordinates within target element. + activeCursor.style.transform = + `translate(${offsetXAdjusted}px, ${offsetYAdjusted}px)`; + }; + + const canvasAreaLeaveHandler = () => { + if (activeCursor) { + activeCursor.style.display = "none"; + // Hide the cursor when mouse leaves. + activeCursor.style.opacity = 0; + } + }; + + const canvasAreaEnterHandler = () => { + if (activeCursor) { + activeCursor.style.display = "block"; + // Show the cursor when mouse enters. + activeCursor.style.opacity = 1; + } + }; + + const canvasArea = targetElement.querySelector("canvas"); + + // Attach event listeners to the target element and canvas area + targetElement.addEventListener("mousemove", canvasAreaEventsHandler); + canvasArea.addEventListener("mouseout", canvasAreaLeaveHandler); + canvasArea.addEventListener("mouseenter", canvasAreaEnterHandler); + + // Additional listener for handling zoom or other transformations which might affect visual representation + targetElement.addEventListener("wheel", canvasAreaEventsHandler); } @@ -1065,23 +888,24 @@ onUiLoaded(async() => { window.applyZoomAndPanIntegration = applyZoomAndPanIntegration; // for any extension - const img2imgArea = document.querySelector("#img2img_settings") + // Return zoom functionality when send img via buttons + const img2imgArea = document.querySelector("#img2img_settings"); const checkForTooltip = (e) => { const tabId = getTabId(elements); // Make sure that the item is passed correctly to determine the tabId - + if (tabId === "#img2img_sketch" || tabId === "#inpaint_sketch" || tabId === "#img2maskimg") { const zoomTooltip = document.querySelector(`${tabId} .canvas-tooltip`); - + if (!zoomTooltip) { - applyZoomAndPan(tabId,false); + applyZoomAndPan(tabId, false); // resetZoom() - } + } } }; - + // Wrapping your function through debounce to reduce the number of calls const debouncedCheckForTooltip = debounce(checkForTooltip, 20); - + // Assigning an event handler img2imgArea.addEventListener("mousemove", debouncedCheckForTooltip); diff --git a/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py b/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py index 89b7c31f2..3cef1df24 100644 --- a/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py +++ b/extensions-builtin/canvas-zoom-and-pan/scripts/hotkey_config.py @@ -11,7 +11,6 @@ shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas "canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas positon"), "canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, neededs for testing"), "canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"), - "canvas_auto_expand": shared.OptionInfo(True, "Automatically expands an image that does not fit completely in the canvas area, similar to manually pressing the S and R buttons"), "canvas_blur_prompt": shared.OptionInfo(False, "Take the focus off the prompt when working with a canvas"), "canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size","Hotkey enlarge brush","Hotkey shrink brush","Moving canvas","Fullscreen","Reset Zoom","Overlap"]}), }))