From aa9b7126c2d54edc6fc42e1f55f32b4de733e317 Mon Sep 17 00:00:00 2001 From: anapnoe <124302297+anapnoe@users.noreply.github.com> Date: Sat, 1 Apr 2023 12:14:18 +0300 Subject: [PATCH] zoom and pan fullscreen capabilities for image edit component used in extensions --- javascript/imageMaskFix.js | 374 +++++++++++++++---------------------- style.css | 1 + 2 files changed, 150 insertions(+), 225 deletions(-) diff --git a/javascript/imageMaskFix.js b/javascript/imageMaskFix.js index 7978d369..a3b38308 100644 --- a/javascript/imageMaskFix.js +++ b/javascript/imageMaskFix.js @@ -46,246 +46,170 @@ function imageMaskResize() { onUiUpdate(() => imageMaskResize()); */ - - -let img2img_tab_index = 0; -let img2img_tab_tool_buttons; - -let isPanning; -let parent_container_img; -let spotlight_sketch; -let spotlight_inpaint; -let spotlight_inpaint_sketch; -let spotlight; - -let curr_src = []; - -let intervalLastUIUpdate; - -let sketch_pan; -let inpaint_pan; -let inpaint_sketch_pan; -let curr_pan; - - -function common_undo_handler(e) { - img2img_tab_tool_buttons[0].click(); -} -function common_clear_handler(e){ - img2img_tab_tool_buttons[1].click(); -} - -function common_color_handler(e){ -} - -function common_brush_handler(e){ -} - -function preventDefault(e) { - e = e || window.event - if (e.preventDefault) { - e.preventDefault() - } - e.returnValue = false -} - -function pan_toggle(val, target){ - isPanning = val; - target.classList.toggle("on", isPanning); - spotlight.panzoom(val); - - if(isPanning){ - parent_container_img.classList.add("no-point-events"); - parent_container_img.parentElement.classList.add("move"); - document.addEventListener('wheel', preventDefault, {passive: false}); - }else{ - parent_container_img.classList.remove("no-point-events"); - parent_container_img.parentElement.classList.remove("move"); - document.removeEventListener('wheel', preventDefault, false); - } - -} - -function common_pan_handler(e){ - isPanning = !isPanning; - pan_toggle(isPanning, this); -} - -function update_color(listener){ - let input_color = parent_container_img.querySelector("input[type='color']"); - let spl = parent_container_img.parentElement.parentElement.parentElement.parentElement.parentElement; - let spl_color = spl.querySelector(".spl-color input[type='color']"); - spl_color.value = input_color.value; - - if(listener){ - spl_color.addEventListener("input", function(ev) { - input_color.value = ev.target.value; - updateInput(input_color); - pan_toggle(false, curr_pan); - }) - } -} - -function update_brush(listener){ - let input_range = parent_container_img.querySelector("input[type='range']"); - let spl = parent_container_img.parentElement.parentElement.parentElement.parentElement.parentElement; - let spl_brush = spl.querySelector(".spl-brush input[type='range']"); - spl_brush.value = input_range.value; - - if(listener){ - spl_brush.addEventListener("input", function(ev) { - input_range.value = ev.target.value; - updateInput(input_range); - }) - } -} - -function init_drawing_tools(){ - - let input_color = parent_container_img.querySelector("input[type='color']"); - if(!input_color){ - if(img2img_tab_tool_buttons[3]){ - img2img_tab_tool_buttons[3].click(); - setTimeout(function() { update_color(true); }, 100); - } - }else{ - setTimeout(function() { update_color(false);}, 100); - } - - let input_range = parent_container_img.querySelector("input[type='range']"); - if(!input_range){ - img2img_tab_tool_buttons[2].click(); - setTimeout(function() { update_brush(true); }, 100); - }else{ - setTimeout(function() { update_brush(false);}, 100); - } - -} - onUiLoaded(function(){ const color_box = ''; const brush_size = ''; - - spotlight_sketch = new Spotlight(); - const spotlight_sketch_parent = gradioApp().querySelector("#img2img_sketch"); - spotlight_sketch.init(spotlight_sketch_parent, "-sketch"); - spotlight_sketch.addControl("undo", common_undo_handler); - sketch_pan = spotlight_sketch.addControl("pan", common_pan_handler); - spotlight_sketch.addControl("brush", common_brush_handler, brush_size); - spotlight_sketch.addControl("color", common_color_handler, color_box); - spotlight_sketch.addControl("clear",common_clear_handler); - spotlight_inpaint = new Spotlight(); - const spotlight_inpaint_parent = gradioApp().querySelector("#img2maskimg"); - spotlight_inpaint.init(spotlight_inpaint_parent, "-inpaint"); - spotlight_inpaint.addControl("undo", common_undo_handler); - inpaint_pan = spotlight_inpaint.addControl("pan", common_pan_handler); - spotlight_inpaint.addControl("brush", common_brush_handler, brush_size); - spotlight_inpaint.addControl("clear",common_clear_handler); - - spotlight_inpaint_sketch = new Spotlight(); - const spotlight_inpaint_sketch_parent = gradioApp().querySelector("#inpaint_sketch"); - spotlight_inpaint_sketch.init(spotlight_inpaint_sketch_parent, "-inpaint-sketch"); - spotlight_inpaint_sketch.addControl("undo", common_undo_handler); - inpaint_sketch_pan = spotlight_inpaint_sketch.addControl("pan", common_pan_handler); - spotlight_inpaint_sketch.addControl("brush", common_brush_handler, brush_size); - spotlight_inpaint_sketch.addControl("color", common_color_handler, color_box); - spotlight_inpaint_sketch.addControl("clear",common_clear_handler); -}) + let img_src = []; + const container = gradioApp().querySelector(".gradio-container"); + const observer = new MutationObserver(() => + gradioApp().querySelectorAll('div[data-testid="image"]').forEach(function (elem, i){ + let img_parent = elem.parentElement.querySelector('div[data-testid="image"] > div'); + let img = img_parent.querySelector('img'); + if(img){ + if(img_src[i] != img.src){ + let tool_buttons = img_parent.querySelectorAll('button'); + if(tool_buttons.length > 2){ + img_src[i] = img.src; + //console.log("NEWIMAGE"); + let spl_parent = elem.parentElement; + let spl = new Spotlight(); + spl.init(spl_parent, "-"+spl_parent.id); + + spl.addControl("undo", spl_undo_handler); + let spl_pan = spl.addControl("pan", spl_pan_handler); + spl.addControl("brush", spl_brush_handler, brush_size); + if(tool_buttons.length == 4){ + spl.addControl("color", spl_color_handler, color_box); + } + spl.addControl("clear",spl_clear_handler); + let isPanning; + function spl_undo_handler(e) { + tool_buttons[0].click(); + } + + function spl_clear_handler(e){ + tool_buttons[1].click(); + spl.panzoom(false); + img_parent.classList.remove("no-point-events"); + img_parent.parentElement.classList.remove("move"); + document.removeEventListener('wheel', preventDefault, false); + setTimeout(function() { + spl.close(false, true); + img_parent.style.flexGrow = "1"; + img_src[i] = ""; + elem.style.transform = "none"; + }, 200); + + } + + function spl_color_handler(e){} + function spl_brush_handler(e){} -onUiUpdate(function() { - //clearInterval(intervalLastUIUpdate); - const img2img_tab = gradioApp().querySelector('#img2img_img2img_tab'); - if(img2img_tab && selectedTabItemId == "tab_img2img"){ - //console.log("UIMASKUPDATE"); - const img2img_tab_index = get_img2img_tab_index()[0]; - if(img2img_tab_index > 3 || img2img_tab_index == 0) return; - - let tabid; - let copytoId; - - if(img2img_tab_index == 1){ - tabid = "#img2img_img2img_sketch_tab";// #img2img_sketch"; - spotlight = spotlight_sketch; - curr_pan = sketch_pan; - }else if(img2img_tab_index == 2){ - tabid = "#img2img_inpaint_tab";// #img2maskimg"; - spotlight = spotlight_inpaint; - curr_pan = inpaint_pan; - }else if(img2img_tab_index == 3){ - tabid = "#img2img_inpaint_sketch_tab";// #inpaint_sketch"; - spotlight = spotlight_inpaint_sketch; - curr_pan = inpaint_sketch_pan; - } + function preventDefault(e) { + e = e || window.event + if (e.preventDefault) { + e.preventDefault() + } + e.returnValue = false + } - - const parent_img2img_tab_img = gradioApp().querySelector(tabid); - //const parent_img2img_tab_copy_to = parent_img2img_tab_img.querySelector(copytoId); - const spotlight_parent = parent_img2img_tab_img.querySelector('div[data-testid="image"]'); - parent_container_img = parent_img2img_tab_img.querySelector('div[data-testid="image"] > div'); - const img2img_tab_img = parent_container_img.querySelector('img'); - img2img_tab_tool_buttons = parent_container_img.querySelectorAll('button'); - - - if(img2img_tab_img){ - pan_toggle(false, curr_pan); - spotlight.panzoom(false); - } - - function getImgSync(image){ - if(curr_src[img2img_tab_index] != image.src){ - //console.log("NEWIMAGE"); - curr_src[img2img_tab_index] = image.src; - - let w = image.naturalWidth; - let h = image.naturalHeight; - parent_container_img.style.width = `${w}px`; - parent_container_img.style.height = `${h}px`; - - spotlight.show([{ - media: "node", - src: spotlight_parent, - //autohide: true, - //control: ["pan","clear","undo","fullscreen","autofit","zoom-in","zoom-out","close"], - class: "relative", - }], - ); + function pan_toggle(val, target){ + isPanning = val; + target.classList.toggle("on", isPanning); + spl.panzoom(val); + + if(isPanning){ + img_parent.classList.add("no-point-events"); + img_parent.parentElement.classList.add("move"); + document.addEventListener('wheel', preventDefault, {passive: false}); + }else{ + img_parent.classList.remove("no-point-events"); + img_parent.parentElement.classList.remove("move"); + document.removeEventListener('wheel', preventDefault, false); + } + + } - parent_container_img.style.flexGrow = "0"; - setTimeout(function() { init_drawing_tools(); }, 500); - - } - - } - - const getImage = async (image) => { - if(!image){ - if(spotlight.panel){ - spotlight.close(false, true); - parent_container_img.style.flexGrow = "1"; - curr_src[img2img_tab_index] = ""; - spotlight_parent.style.transform = "none"; + function spl_pan_handler(e){ + isPanning = !isPanning; + pan_toggle(isPanning, this); + } + + function update_color(listener){ + let input_color = img_parent.querySelector("input[type='color']"); + let spl = img_parent.parentElement.parentElement.parentElement.parentElement.parentElement; + let spl_color = spl.querySelector(".spl-color input[type='color']"); + spl_color.value = input_color.value; + + if(listener){ + spl_color.addEventListener("input", function(ev) { + input_color.value = ev.target.value; + updateInput(input_color); + pan_toggle(false, spl_pan); + }) + } + } + + function update_brush(listener){ + let input_range = img_parent.querySelector("input[type='range']"); + let spl = img_parent.parentElement.parentElement.parentElement.parentElement.parentElement; + let spl_brush = spl.querySelector(".spl-brush input[type='range']"); + spl_brush.value = input_range.value; + + if(listener){ + spl_brush.addEventListener("input", function(ev) { + input_range.value = ev.target.value; + updateInput(input_range); + }) + } + } + + function init_drawing_tools(){ + let input_color = img_parent.querySelector("input[type='color']"); + if(!input_color){ + if(tool_buttons[3]){ + tool_buttons[3].click(); + setTimeout(function() { update_color(true); }, 100); + } + }else{ + setTimeout(function() { update_color(false);}, 100); + } + + let input_range = img_parent.querySelector("input[type='range']"); + if(!input_range){ + if(tool_buttons[2]){ + tool_buttons[2].click(); + setTimeout(function() { update_brush(true); }, 100); + } + }else{ + setTimeout(function() { update_brush(false);}, 100); + } + + } + + let w = img.naturalWidth; + let h = img.naturalHeight; + img_parent.style.width = `${w}px`; + img_parent.style.height = `${h}px`; + + spl.show([{ + media: "node", + src: elem, + //autohide: true, + //control: ["pan","clear","undo","fullscreen","autofit","zoom-in","zoom-out","close"], + class: "relative", + }], + ); + + img_parent.style.flexGrow = "0"; + pan_toggle(false, spl_pan); + spl.panzoom(false); + setTimeout(function() { init_drawing_tools(); }, 500); + + } } - }else if (image.complete) { - return getImgSync(image); - }else{ - return new Promise(resolve => { - image.onload = () => { - resolve(getImgSync(image)); - }; - }); } - }; - - getImage(img2img_tab_img); - - } + })); + observer.observe(container, { childList: true, subtree: true }); }) + /* +let intervalLastUIUpdate; function onLastUIUpdate(){ clearInterval(intervalLastUIUpdate); const img2img_tab = gradioApp().querySelector('#img2img_img2img_tab'); diff --git a/style.css b/style.css index a7c6ad8f..093ae374 100644 --- a/style.css +++ b/style.css @@ -4374,6 +4374,7 @@ input[type=range]::-ms-fill-upper { .spl-progress { position: absolute; top: 0; + left: -1px; width: 100%; height: 3px; background-color: var(--modal-icon-color);