From 3c596e6a4c1d85dcb1ad809c3d650600b4036ccf Mon Sep 17 00:00:00 2001 From: tim h Date: Wed, 4 Jan 2023 20:00:51 -0600 Subject: [PATCH 01/49] experimental? newer hrfix stuff --- css/index.css | 6 ++++ index.html | 33 ++++++++++++++++++---- js/index.js | 60 ++++++++++++++++++++++++++++++---------- js/ui/tool/dream.js | 12 ++++++-- pages/configuration.html | 2 +- 5 files changed, 90 insertions(+), 23 deletions(-) diff --git a/css/index.css b/css/index.css index 80fa23d..0585f43 100644 --- a/css/index.css +++ b/css/index.css @@ -644,3 +644,9 @@ select > .style-select-option:active { .button.tool.active { background-color: rgb(60, 60, 130); } + +/* Miscellaneous garbage */ + +.thirdwidth { + max-width: 33%; +} diff --git a/index.html b/index.html index ce50bf7..1315cc4 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + @@ -100,8 +100,31 @@
+ +
+ + + +
+
@@ -323,7 +346,7 @@ - + @@ -341,7 +364,7 @@ - + - + diff --git a/js/index.js b/js/index.js index 1424164..8b2ea19 100644 --- a/js/index.js +++ b/js/index.js @@ -111,6 +111,9 @@ var stableDiffusionData = { //firstphase_height: 0, //20230102 welp looks like the entire way HRfix is implemented has become bonkersly different hr_scale: 2.0, hr_upscaler: "None", + hr_second_pass_steps: 0, + hr_resize_x: 0, + hr_resize_y: 0, styles: [], // here's some more fields that might be useful @@ -679,6 +682,17 @@ const lockPxSlider = makeSlider( 1 ); +const hrStepsSlider = makeSlider( + "HRfix Steps", + document.getElementById("hrFixSteps"), + "hr_second_pass_steps", + 0, + localStorage.getItem("openoutpaint/settings.max-steps") || 70, + 5, + 30, + 1 +); + function changeMaskBlur() { stableDiffusionData.mask_blur = parseInt( document.getElementById("maskBlur").value @@ -691,29 +705,45 @@ function changeSeed() { localStorage.setItem("openoutpaint/seed", stableDiffusionData.seed); } +function changeHRFX() { + stableDiffusionData.hr_resize_x = + document.getElementById("hr_resize_x").value; +} + +function changeHRFY() { + stableDiffusionData.hr_resize_y = + document.getElementById("hr_resize_y").value; +} + function changeHiResFix() { stableDiffusionData.enable_hr = Boolean( document.getElementById("cbxHRFix").checked ); localStorage.setItem("openoutpaint/enable_hr", stableDiffusionData.enable_hr); - var hrfSlider = document.getElementById("hrFixScale"); - var hrfOpotions = document.getElementById("hrFixUpscaler"); - var hrfLabel = document.getElementById("hrFixLabel"); - var hrfDenoiseSlider = document.getElementById("hrDenoising"); - var hrfLockPxSlider = document.getElementById("hrFixLockPx"); + // var hrfSlider = document.getElementById("hrFixScale"); + // var hrfOpotions = document.getElementById("hrFixUpscaler"); + // var hrfLabel = document.getElementById("hrFixLabel"); + // var hrfDenoiseSlider = document.getElementById("hrDenoising"); + // var hrfLockPxSlider = document.getElementById("hrFixLockPx"); if (stableDiffusionData.enable_hr) { - hrfSlider.classList.remove("invisible"); - hrfOpotions.classList.remove("invisible"); - hrfLabel.classList.remove("invisible"); - hrfDenoiseSlider.classList.remove("invisible"); - hrfLockPxSlider.classList.remove("invisible"); + document + .querySelectorAll(".hrfix") + .forEach((el) => el.classList.remove("invisible")); + // hrfSlider.classList.remove("invisible"); + // hrfOpotions.classList.remove("invisible"); + // hrfLabel.classList.remove("invisible"); + // hrfDenoiseSlider.classList.remove("invisible"); + // hrfLockPxSlider.classList.remove("invisible"); //state.ctxmenu.keepUnmaskedBlurSliderLinebreak.classList.add("invisible"); } else { - hrfSlider.classList.add("invisible"); - hrfOpotions.classList.add("invisible"); - hrfLabel.classList.add("invisible"); - hrfDenoiseSlider.classList.add("invisible"); - hrfLockPxSlider.classList.add("invisible"); + document + .querySelectorAll(".hrfix") + .forEach((el) => el.classList.add("invisible")); + // hrfSlider.classList.add("invisible"); + // hrfOpotions.classList.add("invisible"); + // hrfLabel.classList.add("invisible"); + // hrfDenoiseSlider.classList.add("invisible"); + // hrfLockPxSlider.classList.add("invisible"); //state.ctxmenu.keepUnmaskedBlurSliderLinebreak.classList.remove("invisible"); } } diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index 77207c5..2d5cc58 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -844,8 +844,16 @@ const dream_generate_callback = async (bb, resolution, state) => { var newWidth = Math.floor(request.width / request.hr_scale); var newHeight = Math.floor(request.height / request.hr_scale); - request.width = newWidth; - request.height = newHeight; + request.hr_resize_x = stableDiffusionData.hr_resize_x; + request.hr_resize_y = stableDiffusionData.hr_resize_y; + request.width = + stableDiffusionData.hr_resize_x || stableDiffusionData.hr_resize_y > 0 + ? request.width + : newWidth; + request.height = + stableDiffusionData.hr_resize_x || stableDiffusionData.hr_resize_y > 0 + ? request.height + : newHeight; //in webUI if _either_ x or y is > 0 then their values are used over scale as per https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/81490780949fffed77493b4bd741e96ec737fe27#diff-ddc07d50fa3b043925b1e831b1373976798d62c9f5c11fcb16c6c830bd3857cdR104 } // For compatibility with the old HRFix API diff --git a/pages/configuration.html b/pages/configuration.html index 5e53994..d8f0935 100644 --- a/pages/configuration.html +++ b/pages/configuration.html @@ -7,7 +7,7 @@ - + From 898cd35f621b1e740881a84bcaf3655a76bd17a7 Mon Sep 17 00:00:00 2001 From: zero01101 Date: Thu, 5 Jan 2023 02:09:53 +0000 Subject: [PATCH 02/49] Fixed resource hashes --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 1315cc4..da484f3 100644 --- a/index.html +++ b/index.html @@ -346,7 +346,7 @@ - + @@ -375,7 +375,7 @@ From b45ce1aeba12e229361ac85d41cd0848d811c608 Mon Sep 17 00:00:00 2001 From: tim h Date: Wed, 4 Jan 2023 23:27:02 -0600 Subject: [PATCH 03/49] WIP - parity with square vs non- in/output HRfix res --- index.html | 27 ++++++--------------------- js/index.js | 29 +++++++++++++++++------------ js/ui/tool/dream.js | 20 ++++++++++---------- 3 files changed, 33 insertions(+), 43 deletions(-) diff --git a/index.html b/index.html index da484f3..ec2c965 100644 --- a/index.html +++ b/index.html @@ -100,28 +100,13 @@
- + +
- - - -
diff --git a/js/index.js b/js/index.js index 8b2ea19..5942bd3 100644 --- a/js/index.js +++ b/js/index.js @@ -114,6 +114,7 @@ var stableDiffusionData = { hr_second_pass_steps: 0, hr_resize_x: 0, hr_resize_y: 0, + hr_square_aspect: false, styles: [], // here's some more fields that might be useful @@ -729,25 +730,19 @@ function changeHiResFix() { document .querySelectorAll(".hrfix") .forEach((el) => el.classList.remove("invisible")); - // hrfSlider.classList.remove("invisible"); - // hrfOpotions.classList.remove("invisible"); - // hrfLabel.classList.remove("invisible"); - // hrfDenoiseSlider.classList.remove("invisible"); - // hrfLockPxSlider.classList.remove("invisible"); - //state.ctxmenu.keepUnmaskedBlurSliderLinebreak.classList.add("invisible"); } else { document .querySelectorAll(".hrfix") .forEach((el) => el.classList.add("invisible")); - // hrfSlider.classList.add("invisible"); - // hrfOpotions.classList.add("invisible"); - // hrfLabel.classList.add("invisible"); - // hrfDenoiseSlider.classList.add("invisible"); - // hrfLockPxSlider.classList.add("invisible"); - //state.ctxmenu.keepUnmaskedBlurSliderLinebreak.classList.remove("invisible"); } } +function changeHiResSquare() { + stableDiffusionData.hr_square_aspect = Boolean( + document.getElementById("cbxHRFSquare").checked + ); +} + function changeRestoreFaces() { stableDiffusionData.restore_faces = Boolean( document.getElementById("cbxRestoreFaces").checked @@ -845,7 +840,17 @@ async function getUpscalers() { .split(",") .map((v) => v.trim()); // need "None" for stupid hrfix changes razza frazza const upscalers = upscalersPlusNone.filter((v) => v !== "None"); // converting the result to a list of upscalers + // upscalersPlusNone.push([ + // "Latent", + // "Latent (antialiased)", + // "Latent (bicubic)", + // "Latent (bicubic, antialiased)", + // "Latent (nearest)", + // ]); upscalersPlusNone.push("Latent"); + upscalersPlusNone.push("Latent (antialiased)"); + upscalersPlusNone.push("Latent (bicubic)"); + upscalersPlusNone.push("Latent (bicubic, antialiased)"); upscalersPlusNone.push("Latent (nearest)"); // GRUMBLE GRUMBLE upscalerAutoComplete.options = upscalers.map((u) => { diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index 2d5cc58..9ef6706 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -844,20 +844,20 @@ const dream_generate_callback = async (bb, resolution, state) => { var newWidth = Math.floor(request.width / request.hr_scale); var newHeight = Math.floor(request.height / request.hr_scale); - request.hr_resize_x = stableDiffusionData.hr_resize_x; - request.hr_resize_y = stableDiffusionData.hr_resize_y; - request.width = - stableDiffusionData.hr_resize_x || stableDiffusionData.hr_resize_y > 0 - ? request.width - : newWidth; - request.height = - stableDiffusionData.hr_resize_x || stableDiffusionData.hr_resize_y > 0 - ? request.height - : newHeight; //in webUI if _either_ x or y is > 0 then their values are used over scale as per https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/81490780949fffed77493b4bd741e96ec737fe27#diff-ddc07d50fa3b043925b1e831b1373976798d62c9f5c11fcb16c6c830bd3857cdR104 + if (stableDiffusionData.hr_square_aspect) { + larger = newWidth > newHeight ? newWidth : newHeight; + newWidth = larger; + newHeight = larger; + } + request.hr_resize_x = request.width; + request.hr_resize_y = request.height; // screw the scale, damn the man, setting specified output dimensions overrides it anyway, who needs the thing, i need to revisit like all the hrfix code now though because i don't know if NOT lying to it is even worthwhile anymore + request.width = newWidth; + request.height = newHeight; } // For compatibility with the old HRFix API if (global.isOldHRFix && request.enable_hr) { + // For compatibility with the old HRFix API request.firstphase_width = request.width / 2; request.firstphase_height = request.height / 2; } From ee8166a387a1b2b0fb51ed5e9dd046b773938940 Mon Sep 17 00:00:00 2001 From: zero01101 Date: Thu, 5 Jan 2023 05:27:30 +0000 Subject: [PATCH 04/49] Fixed resource hashes --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index ec2c965..64c2c7c 100644 --- a/index.html +++ b/index.html @@ -349,7 +349,7 @@ - + - + From bb815d62f914659e07090c2920ab997ac64cd53f Mon Sep 17 00:00:00 2001 From: tim h Date: Thu, 5 Jan 2023 17:42:50 -0600 Subject: [PATCH 05/49] option to enforce square firstpass aspect ratio --- index.html | 14 ++++---- js/index.js | 3 +- js/ui/tool/dream.js | 69 +++++++++++++++++++++++++--------------- pages/configuration.html | 10 ++++-- 4 files changed, 60 insertions(+), 36 deletions(-) diff --git a/index.html b/index.html index 64c2c7c..16629da 100644 --- a/index.html +++ b/index.html @@ -98,14 +98,16 @@ step="1" />
- +
- +
@@ -331,7 +333,7 @@ - + @@ -349,7 +351,7 @@ - + - + diff --git a/js/index.js b/js/index.js index 5942bd3..7f341d4 100644 --- a/js/index.js +++ b/js/index.js @@ -165,6 +165,7 @@ function startup() { changeSmoothRendering(); changeSeed(); changeHiResFix(); + changeHiResSquare(); changeRestoreFaces(); changeSyncCursorSize(); } @@ -690,7 +691,7 @@ const hrStepsSlider = makeSlider( 0, localStorage.getItem("openoutpaint/settings.max-steps") || 70, 5, - 30, + 0, 1 ); diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index 9ef6706..af9caed 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -156,6 +156,7 @@ const _dream = async (endpoint, request) => { generating(false); } var responseSubdata = JSON.parse(data.info); + console.debug(responseSubdata); var returnData = { images: data.images, seeds: responseSubdata.all_seeds, @@ -815,44 +816,60 @@ const dream_generate_callback = async (bb, resolution, state) => { // Use txt2img if canvas is blank if (isCanvasBlank(0, 0, bb.w, bb.h, visibleCanvas)) { - if ( - !global.isOldHRFix && - request.enable_hr && - localStorage.getItem("openoutpaint/settings.hrfix-liar") == "true" - ) { + if (!global.isOldHRFix && request.enable_hr) { /** * try and make the new HRfix method useful for our purposes - * since it now returns an image that's been upscaled x the hr_scale parameter, - * we cheekily lie to SD and tell it that the original dimensions are _divided_ - * by the scale factor so it returns something about the same size as we wanted initially */ - // ok so instead, only do that if stableDiffusionData.hr_fix_lock_px > 0 - if (stableDiffusionData.hr_fix_lock_px > 0) { + //laziness convenience + let lockpx = stableDiffusionData.hr_fix_lock_px; + var divW = Math.floor(request.width / request.hr_scale); + var divH = Math.floor(request.height / request.hr_scale); + if (lockpx > 0) { // find the appropriate scale factor for hrfix var widthFactor = - request.width / stableDiffusionData.hr_fix_lock_px <= 4 - ? request.width / stableDiffusionData.hr_fix_lock_px - : 4; + request.width / lockpx <= 4 ? request.width / lockpx : 4; var heightFactor = - request.height / stableDiffusionData.hr_fix_lock_px <= 4 - ? request.height / stableDiffusionData.hr_fix_lock_px - : 4; + request.height / lockpx <= 4 ? request.height / lockpx : 4; var factor = heightFactor > widthFactor ? heightFactor : widthFactor; request.hr_scale = hrFixScaleSlider.value = factor < 1 ? 1 : factor; } - var newWidth = Math.floor(request.width / request.hr_scale); - var newHeight = Math.floor(request.height / request.hr_scale); - if (stableDiffusionData.hr_square_aspect) { - larger = newWidth > newHeight ? newWidth : newHeight; - newWidth = larger; - newHeight = larger; + if (localStorage.getItem("openoutpaint/settings.hrfix-liar") == "true") { + /** + * since it now returns an image that's been upscaled x the hr_scale parameter, + * we cheekily lie to SD and tell it that the original dimensions are _divided_ + * by the scale factor so it returns something about the same size as we wanted initially + */ + var firstpassWidth = divW; + var firstpassHeight = divH; // liar's firstpass output resolution + var desiredWidth = request.width; + var desiredHeight = request.height; // truthful desired output resolution + } else { + // use scale normally, dump supersampled image into undersized reticle + var desiredWidth = request.width * request.hr_scale; + var desiredHeight = request.height * request.hr_scale; //desired 2nd-pass output resolution + var firstpassWidth = request.width; + var firstpassHeight = request.height; } - request.hr_resize_x = request.width; - request.hr_resize_y = request.height; // screw the scale, damn the man, setting specified output dimensions overrides it anyway, who needs the thing, i need to revisit like all the hrfix code now though because i don't know if NOT lying to it is even worthwhile anymore - request.width = newWidth; - request.height = newHeight; + + // ensure firstpass "resolution" complies with lockpx + if (lockpx > 0) { + //sigh repeated code + // scale down by hr_scale? + firstpassWidth = divW < lockpx ? divW : lockpx; + firstpassHeight = divH < lockpx ? divH : lockpx; + } + + if (stableDiffusionData.hr_square_aspect) { + larger = + firstpassWidth > firstpassHeight ? firstpassWidth : firstpassHeight; + firstpassWidth = firstpassHeight = larger; + } + request.width = firstpassWidth; + request.height = firstpassHeight; + request.hr_resize_x = desiredWidth; + request.hr_resize_y = desiredHeight; } // For compatibility with the old HRFix API diff --git a/pages/configuration.html b/pages/configuration.html index d8f0935..ac40172 100644 --- a/pages/configuration.html +++ b/pages/configuration.html @@ -84,11 +84,12 @@ step="0.1" value="30.0" /> + +
-

Refresh the page to apply settings.

- + @@ -362,7 +362,7 @@ From 16ad7a550da66a6544262eeb7dc2f45415af701e Mon Sep 17 00:00:00 2001 From: tim h Date: Fri, 6 Jan 2023 12:49:15 -0600 Subject: [PATCH 07/49] think this was out-of-order and causing math problems with resolutions but i could be an idiot --- js/ui/tool/dream.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index af9caed..7760de4 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -820,13 +820,10 @@ const dream_generate_callback = async (bb, resolution, state) => { /** * try and make the new HRfix method useful for our purposes */ - - //laziness convenience + // laziness convenience let lockpx = stableDiffusionData.hr_fix_lock_px; - var divW = Math.floor(request.width / request.hr_scale); - var divH = Math.floor(request.height / request.hr_scale); if (lockpx > 0) { - // find the appropriate scale factor for hrfix + // find the most appropriate scale factor for hrfix var widthFactor = request.width / lockpx <= 4 ? request.width / lockpx : 4; var heightFactor = @@ -834,6 +831,9 @@ const dream_generate_callback = async (bb, resolution, state) => { var factor = heightFactor > widthFactor ? heightFactor : widthFactor; request.hr_scale = hrFixScaleSlider.value = factor < 1 ? 1 : factor; } + // moar laziness convenience + var divW = Math.floor(request.width / request.hr_scale); + var divH = Math.floor(request.height / request.hr_scale); if (localStorage.getItem("openoutpaint/settings.hrfix-liar") == "true") { /** @@ -855,8 +855,7 @@ const dream_generate_callback = async (bb, resolution, state) => { // ensure firstpass "resolution" complies with lockpx if (lockpx > 0) { - //sigh repeated code - // scale down by hr_scale? + //sigh repeated loop firstpassWidth = divW < lockpx ? divW : lockpx; firstpassHeight = divH < lockpx ? divH : lockpx; } From 53c358809abd790c8dd9e35d203e59218f764400 Mon Sep 17 00:00:00 2001 From: zero01101 Date: Fri, 6 Jan 2023 18:49:43 +0000 Subject: [PATCH 08/49] Fixed resource hashes --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 44e72e3..7d6ae00 100644 --- a/index.html +++ b/index.html @@ -365,7 +365,7 @@ src="js/ui/tool/generic.js?v=2bcd36d" type="text/javascript"> - + From c678d4cbe2135cb42b8932054838451d08d6545a Mon Sep 17 00:00:00 2001 From: tim h Date: Fri, 6 Jan 2023 12:56:15 -0600 Subject: [PATCH 09/49] update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6dc6466..133e606 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ this is a completely vanilla javascript and html canvas outpainting convenience ## operation +**_NOTE: [PLEASE SEE DOCUMENTATION REGARDING NEW HRfix FEATURES](https://github.com/zero01101/openOutpaint/wiki/Manual#hrfix) IMPLEMENTED AS OF webUI COMMIT [ef27a18](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d)_** + ### prerequisities you'll obviously need A1111's webUI installed before you can use this, thus you're presumed to have an operational python install up and running to boot. From 7bb634fd455ece91f795ca6decfcf15dd48583c3 Mon Sep 17 00:00:00 2001 From: tim h Date: Fri, 6 Jan 2023 14:16:51 -0600 Subject: [PATCH 10/49] add link to user manual in debug menu maybe useful? --- index.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 7d6ae00..3ea88ca 100644 --- a/index.html +++ b/index.html @@ -203,6 +203,12 @@ Alpha release v0.0.12.5 +
+ + User Manual +
@@ -333,7 +339,7 @@ - + @@ -362,7 +368,7 @@ From 6bb9d34408bf6ad6e4730c350dc6c177102118b1 Mon Sep 17 00:00:00 2001 From: zero01101 Date: Fri, 6 Jan 2023 20:17:32 +0000 Subject: [PATCH 11/49] Fixed resource hashes --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 3ea88ca..dcbf766 100644 --- a/index.html +++ b/index.html @@ -339,7 +339,7 @@ - + @@ -368,7 +368,7 @@ From dbcd588e29270be325a7f419d966773e0d0fbc80 Mon Sep 17 00:00:00 2001 From: tim h Date: Fri, 6 Jan 2023 16:00:07 -0600 Subject: [PATCH 12/49] remove claim of bug that's probably my fault --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 133e606..e833692 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ this is a completely vanilla javascript and html canvas outpainting convenience - floating toolbox with handy keyboard shortcuts - optional grid snapping for precision - optional hi-res fix for blank/txt2img dreams - - **_NOTE: as of v0.0.12.5/webUI commit [ef27a18](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d), HRfix has been COMPLETELY reworked and no longer works even remotely the same and webUI would actively use the newly "invalid" firstpass sizes as the_ desired output resolution _after yelling about them being invalid, thus openOutpaint's implementation is no longer compatible with versions of A1111 predating that. You will be alerted to the outdated webUI and the HRfix option will become disabled in this event._** + - **_NOTE: as of v0.0.12.5/webUI commit [ef27a18](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d), HRfix has been COMPLETELY reworked and no longer works remotely the same, thus openOutpaint's implementation is no longer compatible with versions of A1111 predating that. You will be alerted to the outdated webUI and the HRfix option will become limited to simply using [reticle dimensions / 2] in this event._** - optional overmasking for potentially better seams between outpaints - set overmask px value to 0 to disable the feature - import arbitrary images and scale/stamp on the canvas whenever, wherever you'd like - upscaler support for final output images From 548eefe7693226504a754dce377519c70c8c6f98 Mon Sep 17 00:00:00 2001 From: tim h Date: Sat, 7 Jan 2023 14:06:37 -0600 Subject: [PATCH 13/49] checks tab focus before doing XHR background stuff, replaces connectivity check endpoint for a lighter response --- js/index.js | 161 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 50 deletions(-) diff --git a/js/index.js b/js/index.js index 7f341d4..6333aca 100644 --- a/js/index.js +++ b/js/index.js @@ -143,6 +143,7 @@ var stableDiffusionData = { var host = ""; var url = "/sdapi/v1/"; const basePixelCount = 64; //64 px - ALWAYS 64 PX +var focused = true; function startup() { testHostConfiguration(); @@ -168,6 +169,7 @@ function startup() { changeHiResSquare(); changeRestoreFaces(); changeSyncCursorSize(); + checkFocus(); } function setFixedHost(h, changePromptMessage) { @@ -335,7 +337,23 @@ async function testHostConnection() { let checkInProgress = false; - const checkConnection = async (notify = false) => { + const checkConnection = async ( + notify = false, + simpleProgressStatus = false + ) => { + const apiIssueResult = () => { + setConnectionStatus("apiissue"); + const message = `The host is online, but the API seems to be disabled.\nHave you run the webui with the flag '--api', or is the flag '--gradio-debug' currently active?`; + console.error(message); + if (notify) alert(message); + }; + + const offlineResult = () => { + setConnectionStatus("offline"); + const message = `The connection with the host returned an error: ${response.status} - ${response.statusText}`; + console.error(message); + if (notify) alert(message); + }; if (checkInProgress) throw new CheckInProgressError( "Check is currently in progress, please try again" @@ -344,50 +362,64 @@ async function testHostConnection() { var url = document.getElementById("host").value + "/startup-events"; // Attempt normal request try { - // Check if API is available - const response = await fetch( - document.getElementById("host").value + "/sdapi/v1/options" - ); - const optionsdata = await response.json(); - if (optionsdata["use_scale_latent_for_hires_fix"]) { - const message = `You are using an outdated version of A1111 webUI.\nThe HRfix options will not work until you update to at least commit ef27a18 or newer.\n(https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d)\nHRfix will fallback to half-resolution only.`; - console.warn(message); - if (notify) alert(message); - // Hide all new hrfix options - document - .querySelectorAll(".hrfix") - .forEach((el) => (el.style.display = "none")); - - // We are using old HRFix - global.isOldHRFix = true; - stableDiffusionData.enable_hr = false; - } - switch (response.status) { - case 200: { - setConnectionStatus("online"); - // Load data as soon as connection is first stablished - if (firstTimeOnline) { - getConfig(); - getStyles(); - getSamplers(); - getUpscalers(); - getModels(); - firstTimeOnline = false; + if (simpleProgressStatus) { + const response = await fetch( + document.getElementById("host").value + "/sdapi/v1/progress" // seems to be the "lightest" endpoint? + ); + const responseData = await response.json(); + switch (response.status) { + case 200: { + setConnectionStatus("online"); + break; + } + case 404: { + apiIssueResult(); + break; + } + default: { + offlineResult(); } - break; } - case 404: { - setConnectionStatus("apiissue"); - const message = `The host is online, but the API seems to be disabled.\nHave you run the webui with the flag '--api', or is the flag '--gradio-debug' currently active?`; - console.error(message); + } else { + // Check if API is available + const response = await fetch( + document.getElementById("host").value + "/sdapi/v1/options" + ); + const optionsdata = await response.json(); + if (optionsdata["use_scale_latent_for_hires_fix"]) { + const message = `You are using an outdated version of A1111 webUI.\nThe HRfix options will not work until you update to at least commit ef27a18 or newer.\n(https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d)\nHRfix will fallback to half-resolution only.`; + console.warn(message); if (notify) alert(message); - break; + // Hide all new hrfix options + document + .querySelectorAll(".hrfix") + .forEach((el) => (el.style.display = "none")); + + // We are using old HRFix + global.isOldHRFix = true; + stableDiffusionData.enable_hr = false; } - default: { - setConnectionStatus("offline"); - const message = `The connection with the host returned an error: ${response.status} - ${response.statusText}`; - console.error(message); - if (notify) alert(message); + switch (response.status) { + case 200: { + setConnectionStatus("online"); + // Load data as soon as connection is first stablished + if (firstTimeOnline) { + getConfig(); + getStyles(); + getSamplers(); + getUpscalers(); + getModels(); + firstTimeOnline = false; + } + break; + } + case 404: { + apiIssueResult(); + break; + } + default: { + offlineResult(); + } } } } catch (e) { @@ -413,7 +445,9 @@ async function testHostConnection() { return status; }; - await checkConnection(!urlParams.has("noprompt")); + if (focused) { + await checkConnection(!urlParams.has("noprompt")); + } // On click, attempt to refresh connectionIndicator.onclick = async () => { @@ -425,18 +459,32 @@ async function testHostConnection() { } }; - // Checks every 5 seconds if offline, 30 seconds if online + // Checks every 5 seconds if offline, 60 seconds if online const checkAgain = () => { - setTimeout( - async () => { - await checkConnection(); + if (focused) { + setTimeout( + async () => { + let simple = !firstTimeOnline; + await checkConnection(false, simple); + checkFocus(); + checkAgain(); + }, + connectionStatus ? 60000 : 5000 + //connectionStatus ? 5000 : 5000 //TODO REMOVE DEBUG REPLACE TO 60000 : 5000 + ); + } else { + setTimeout(() => { + console.debug("unfocused, zzz"); + checkFocus(); checkAgain(); - }, - connectionStatus ? 30000 : 5000 - ); + }, 60000); + //}, 5000); //TODO REMOVE DEBUG REPLACE TO 60000 + } }; - checkAgain(); + if (focused) { + checkAgain(); + } return () => { checkConnection().catch(() => {}); @@ -1242,3 +1290,16 @@ function resetToDefaults() { localStorage.clear(); } } + +document.addEventListener("visibilitychange", () => { + checkFocus(); +}); + +function checkFocus() { + if (!document.hidden) { + focused = true; + } else { + focused = false; + } + console.debug("FOCUSED: " + focused); //TODO comment out or something +} From 810e4a5a568a447afb2ed0fe9ad864414f1d2b1a Mon Sep 17 00:00:00 2001 From: zero01101 Date: Sat, 7 Jan 2023 20:07:04 +0000 Subject: [PATCH 14/49] Fixed resource hashes --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index dcbf766..32decf1 100644 --- a/index.html +++ b/index.html @@ -357,7 +357,7 @@ - + - + - + @@ -379,7 +379,7 @@ src="js/ui/tool/colorbrush.js?v=8acb4f6" type="text/javascript"> - + - + @@ -349,11 +350,11 @@ - + @@ -368,7 +369,7 @@ @@ -379,7 +380,7 @@ src="js/ui/tool/colorbrush.js?v=8acb4f6" type="text/javascript"> - + @@ -368,10 +368,10 @@ - + diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index 7760de4..daa0670 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -177,6 +177,7 @@ const _dream = async (endpoint, request) => { * @returns {Promise} */ const _generate = async (endpoint, request, bb, options = {}) => { + var alertCount = 0; defaultOpt(options, { drawEvery: 0.2 / request.n_iter, keepUnmask: null, @@ -532,9 +533,14 @@ const _generate = async (endpoint, request, bb, options = {}) => { seeds.push(...dreamData.seeds); imageindextxt.textContent = `${at}/${images.length - 1}`; } catch (e) { - alert( - `Error generating images. Please try again or see console for more details` - ); + if (alertCount < 2) { + alert( + `Error generating images. Please try again or see console for more details` + ); + } else { + eagerGenerateCount = 0; + } + alertCount++; console.warn(`[dream] Error generating images:`); console.warn(e); } finally { From b166efc5e2ffde4b94bff583cb18fa397b88297a Mon Sep 17 00:00:00 2001 From: zero01101 Date: Sun, 8 Jan 2023 22:45:15 +0000 Subject: [PATCH 22/49] Fixed resource hashes --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 797c48d..2494d65 100644 --- a/index.html +++ b/index.html @@ -339,7 +339,7 @@ - + @@ -368,7 +368,7 @@ From 857cb29c121eb7a556ed2f58f783e02856a00c07 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Tue, 10 Jan 2023 01:02:19 -0300 Subject: [PATCH 23/49] migrates vp to DOMMatrix implementation breaks select, but it was broken anyway. Signed-off-by: Victor Seiji Hariki --- css/layers.css | 1 + index.html | 17 +++--- js/initalize/layers.populate.js | 105 ++++++++++++++++++-------------- js/lib/util.js | 10 +++ js/ui/tool/colorbrush.js | 4 +- js/ui/tool/dream.js | 9 ++- js/ui/tool/generic.js | 9 ++- pages/configuration.html | 2 +- 8 files changed, 89 insertions(+), 68 deletions(-) diff --git a/css/layers.css b/css/layers.css index a4f2ee7..6b616f9 100644 --- a/css/layers.css +++ b/css/layers.css @@ -25,6 +25,7 @@ .layer-render-target .collection { position: absolute; + transform-origin: 0px 0px; } .layer-render-target .collection > .collection-input-overlay { diff --git a/index.html b/index.html index 2494d65..929997e 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ - + @@ -49,6 +49,7 @@ +
@@ -331,15 +332,15 @@
+ src="pages/configuration.html?v=7fca00b">
- + - + @@ -349,7 +350,7 @@ @@ -368,15 +369,15 @@ - + diff --git a/js/initalize/layers.populate.js b/js/initalize/layers.populate.js index 9efd861..66a1a4b 100644 --- a/js/initalize/layers.populate.js +++ b/js/initalize/layers.populate.js @@ -65,12 +65,6 @@ uiCanvas.width = uiCanvas.clientWidth; uiCanvas.height = uiCanvas.clientHeight; const uiCtx = uiCanvas.getContext("2d", {desynchronized: true}); -/** @type {HTMLCanvasElement} */ -const uiDebugCanvas = document.getElementById("layer-debug-overlay"); // where mouse cursor renders -uiDebugCanvas.width = uiDebugCanvas.clientWidth; -uiDebugCanvas.height = uiDebugCanvas.clientHeight; -const uiDebugCtx = uiDebugCanvas.getContext("2d", {desynchronized: true}); - /** * Here we setup canvas dynamic scaling */ @@ -166,68 +160,54 @@ debugLayer.hide(); // Hidden by default * The global viewport object (may be modularized in the future). All * coordinates given are of the center of the viewport * - * cx and cy are the viewport's world coordinates. + * cx and cy are the viewport's world coordinates, scaled to zoom level. + * _x and _y are actual coordinates in the DOM space * * The transform() function does some transforms and writes them to the * provided element. */ const viewport = { - cx: 0, - cy: 0, + get cx() { + return this._x * this.zoom; + }, + + set cx(v) { + return (this._x = v / this.zoom); + }, + _x: 0, + get cy() { + return this._y * this.zoom; + }, + set cy(v) { + return (this._y = v / this.zoom); + }, + _y: 0, zoom: 1, rotation: 0, get w() { - return window.innerWidth * 1; + return (window.innerWidth * 1) / this.zoom; }, get h() { - return window.innerHeight * 1; + return (window.innerHeight * 1) / this.zoom; }, viewToCanvas(x, y) { - return this.matrix.transformPoint({x, y}); return { x: this.cx + this.w * (x / window.innerWidth - 0.5), y: this.cy + this.h * (y / window.innerHeight - 0.5), }; }, canvasToView(x, y) { - return this.imatrix.transformPoint({x, y}); return { x: window.innerWidth * ((x - this.cx) / this.w) + window.innerWidth / 2, y: window.innerHeight * ((y - this.cy) / this.h) + window.innerHeight / 2, }; }, - - /** - * The transformation matrix (vp to world) - * - * @type {DOMMatrix} - */ - get matrix() { - const matrix = new DOMMatrix(); - - matrix.scaleSelf(1 / this.zoom); - matrix.translateSelf(this.cx - this.w / 2, this.cy - this.h / 2); - - return matrix; - }, - - /** - * The transformation matrix (world to vp) - * - * @type {DOMMatrix} - */ - get imatrix() { - return this.matrix.invertSelf(); - }, - /** * Apply transformation * * @param {HTMLElement} el Element to apply CSS transform to */ transform(el) { - el.style.transform = this.imatrix; - return; el.style.transformOrigin = `${this.cx}px ${this.cy}px`; el.style.transform = `scale(${this.zoom}) translate(${-( this._x - @@ -236,8 +216,8 @@ const viewport = { }, }; -//viewport.cx = imageCollection.size.w / 2; -//viewport.cy = imageCollection.size.h / 2; +viewport.cx = imageCollection.size.w / 2; +viewport.cy = imageCollection.size.h / 2; let worldInit = null; @@ -340,8 +320,8 @@ const cameraPaintStart = (evn) => { const cameraPaint = (evn) => { if (worldInit) { - viewport.cx = worldInit.x + (evn.ix - evn.x); - viewport.cy = worldInit.y + (evn.iy - evn.y); + viewport.cx = worldInit.x + (evn.ix - evn.x) / viewport.zoom; + viewport.cy = worldInit.y + (evn.iy - evn.y) / viewport.zoom; // Limits viewport.cx = Math.max( @@ -357,6 +337,13 @@ const cameraPaint = (evn) => { } viewport.transform(imageCollection.element); + if (global.debug) { + debugCtx.clearRect(0, 0, debugCanvas.width, debugCanvas.height); + debugCtx.fillStyle = "#F0F"; + debugCtx.beginPath(); + debugCtx.arc(viewport.cx, viewport.cy, 5, 0, Math.PI * 2); + debugCtx.fill(); + } }; const cameraPaintEnd = (evn) => { From 487f3bed0c78180804dc1fa3e227936c6252feff Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Tue, 10 Jan 2023 14:30:09 -0300 Subject: [PATCH 25/49] implements #164 Signed-off-by: Victor Seiji Hariki --- index.html | 2 +- js/ui/tool/dream.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 2494d65..aa35115 100644 --- a/index.html +++ b/index.html @@ -371,7 +371,7 @@ src="js/ui/tool/generic.js?v=2bcd36d" type="text/javascript"> - + diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index daa0670..3713d0a 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -775,6 +775,20 @@ const _generate = async (endpoint, request, bb, options = {}) => { }); imageSelectMenu.appendChild(resourcebtn); + const deletebtn = document.createElement("button"); + deletebtn.textContent = "D"; + deletebtn.title = "Delete Image"; + deletebtn.addEventListener("click", async () => { + images.splice(at, 1); + seeds.splice(at, 1); + + at = Math.min(at, images.length - 1); + + imageindextxt.textContent = `${at}/${images.length - 1}`; + redraw(); + }); + imageSelectMenu.appendChild(deletebtn); + const savebtn = document.createElement("button"); savebtn.textContent = "S"; savebtn.title = "Download image to computer"; From 16c2b36c1baf885ecc1e748ef2fed8175119d1d6 Mon Sep 17 00:00:00 2001 From: tim h Date: Tue, 10 Jan 2023 17:00:45 -0600 Subject: [PATCH 26/49] ...also implements 164 quite similarly --- js/ui/tool/dream.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index daa0670..aed0098 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -517,6 +517,17 @@ const _generate = async (endpoint, request, bb, options = {}) => { }); }; + const removeImg = async () => { + if (!images[at]) return; + images.splice(at, 1); + seeds.splice(at, 1); + if (at >= images.length) at = 0; + imageindextxt.textContent = `${at}/${images.length - 1}`; + var seed = seeds[at]; + seedbtn.title = "Use seed " + seed; + redraw(); + }; + const makeMore = async () => { const moreQ = await waitQueue(); try { @@ -596,6 +607,9 @@ const _generate = async (endpoint, request, bb, options = {}) => { case "+": makeMore(); break; + case "-": + removeImg(); + break; default: switch (evn.code) { case "ArrowRight": @@ -659,7 +673,11 @@ const _generate = async (endpoint, request, bb, options = {}) => { const oncancelhandler = mouse.listen.world.btn.right.onclick.on( (evn, state) => { if (!state.dream_processed && bb.contains(evn.x, evn.y)) { - discardImg(); + if (images.length > 1) { + removeImg(); + } else { + discardImg(); + } imageCollection.inputElement.style.cursor = "auto"; state.dream_processed = true; } @@ -743,6 +761,12 @@ const _generate = async (endpoint, request, bb, options = {}) => { morebtn.addEventListener("click", makeMore); imageSelectMenu.appendChild(morebtn); + const removebtn = document.createElement("button"); + removebtn.textContent = "-"; + removebtn.title = "Remove From Batch"; + removebtn.addEventListener("click", removeImg); + imageSelectMenu.appendChild(removebtn); + const acceptbtn = document.createElement("button"); acceptbtn.textContent = "Y"; acceptbtn.title = "Apply Current"; From 1ad9dd1e087aa4dd38a987069308664e4555092a Mon Sep 17 00:00:00 2001 From: zero01101 Date: Tue, 10 Jan 2023 23:02:32 +0000 Subject: [PATCH 27/49] Fixed resource hashes --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 2494d65..af89d74 100644 --- a/index.html +++ b/index.html @@ -371,7 +371,7 @@ src="js/ui/tool/generic.js?v=2bcd36d" type="text/javascript"> - + From d7e20f87dc8783d2a2aab1f7caacfb8e994f2549 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Wed, 11 Jan 2023 00:36:14 -0300 Subject: [PATCH 28/49] putting back selection 1 Signed-off-by: Victor Seiji Hariki --- index.html | 6 ++-- js/lib/util.js | 5 +++ js/ui/tool/generic.js | 59 ++++++++++++++++++++++++++++------- js/ui/tool/select.js | 71 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 113 insertions(+), 28 deletions(-) diff --git a/index.html b/index.html index 0462b61..e608e25 100644 --- a/index.html +++ b/index.html @@ -341,7 +341,7 @@ - + @@ -370,7 +370,7 @@ @@ -381,7 +381,7 @@ src="js/ui/tool/colorbrush.js?v=3f8c01a" type="text/javascript"> - + - + @@ -370,7 +370,7 @@ @@ -381,7 +381,7 @@ src="js/ui/tool/colorbrush.js?v=3f8c01a" type="text/javascript"> - + @@ -370,7 +370,7 @@ @@ -381,7 +381,7 @@ src="js/ui/tool/colorbrush.js?v=3f8c01a" type="text/javascript"> + From e198cf9af4967b25063d5236ecccd123ff99d5a4 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Thu, 12 Jan 2023 23:00:34 -0300 Subject: [PATCH 34/49] allow stamp rotation(drag) and scaling(wheel) also adds shift as a 'finetune' for wheel. works for dream and stamp. if shift is pressed, wheel will scale slower (not snapping to 128 for dream, or 0.1 for stamp) Signed-off-by: Victor Seiji Hariki --- index.html | 8 +-- js/config.js | 14 ++--- js/ui/tool/dream.js | 18 +++++- js/ui/tool/select.js | 2 +- js/ui/tool/stamp.js | 142 ++++++++++++++++++++++++++++++++++++------- 5 files changed, 147 insertions(+), 37 deletions(-) diff --git a/index.html b/index.html index 49b4fb5..7795d08 100644 --- a/index.html +++ b/index.html @@ -355,7 +355,7 @@ type="text/javascript"> - + @@ -373,7 +373,7 @@ src="js/ui/tool/generic.js?v=f5ad9d7" type="text/javascript"> - + @@ -381,9 +381,9 @@ src="js/ui/tool/colorbrush.js?v=3f8c01a" type="text/javascript"> - + diff --git a/js/config.js b/js/config.js index 8133dab..5f55a75 100644 --- a/js/config.js +++ b/js/config.js @@ -25,15 +25,15 @@ const config = makeReadOnly( rotationSnappingDistance: (10 * Math.PI) / 180, // Rotation Snapping Angles rotationSnappingAngles: [ + (-Math.PI * 4) / 4, + (-Math.PI * 3) / 4, + (-Math.PI * 2) / 4, + (-Math.PI * 1) / 4, 0, - Math.PI / 4, - Math.PI / 2, + (Math.PI * 1) / 4, + (Math.PI * 2) / 4, (Math.PI * 3) / 4, - Math.PI, - (Math.PI * 5) / 4, - (Math.PI * 6) / 4, - (Math.PI * 7) / 4, - Math.PI * 2, + (Math.PI * 4) / 4, ], // Endpoint diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index bfab2c5..c90e022 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -1255,10 +1255,16 @@ const _dream_onwheel = (evn, state) => { return; } - // A simple but (I hope) effective fix for mouse wheel behavior - _dream_wheel_accum += evn.delta; + let delta = evn.delta; + if (evn.evn.shiftKey) delta *= 0.01; - if (Math.abs(_dream_wheel_accum) > config.wheelTickSize) { + // A simple but (I hope) effective fix for mouse wheel behavior + _dream_wheel_accum += delta; + + if ( + !evn.evn.shiftKey && + Math.abs(_dream_wheel_accum) > config.wheelTickSize + ) { // Snap to next or previous position const v = state.cursorSize - @@ -1267,6 +1273,12 @@ const _dream_onwheel = (evn, state) => { state.cursorSize = state.setCursorSize(v + snap(v, 0, 128)); state.mousemovecb(evn); + _dream_wheel_accum = 0; // Zero accumulation + } else if (evn.evn.shiftKey && Math.abs(_dream_wheel_accum) >= 1) { + const v = state.cursorSize - _dream_wheel_accum; + state.cursorSize = state.setCursorSize(v); + state.mousemovecb(evn); + _dream_wheel_accum = 0; // Zero accumulation } }; diff --git a/js/ui/tool/select.js b/js/ui/tool/select.js index eac3c29..32d1a5a 100644 --- a/js/ui/tool/select.js +++ b/js/ui/tool/select.js @@ -375,7 +375,7 @@ const selectTransformTool = () => angle = config.rotationSnappingAngles.find( (v) => Math.abs(v - angle) < config.rotationSnappingDistance - ) || angle; + ) ?? angle; state.selected.rotation = angle; } diff --git a/js/ui/tool/stamp.js b/js/ui/tool/stamp.js index fc1cb89..31cd054 100644 --- a/js/ui/tool/stamp.js +++ b/js/ui/tool/stamp.js @@ -1,3 +1,41 @@ +/** + * Generic wheel handler + */ +let _stamp_wheel_accum = 0; + +const _stamp_onwheel = (evn, state) => { + if (evn.mode !== WheelEvent.DOM_DELTA_PIXEL) { + // We don't really handle non-pixel scrolling + return; + } + + let delta = evn.delta; + if (evn.evn.shiftKey) delta *= 0.01; + + // A simple but (I hope) effective fix for mouse wheel behavior + _stamp_wheel_accum += delta; + + if ( + !evn.evn.shiftKey && + Math.abs(_stamp_wheel_accum) > config.wheelTickSize + ) { + // Snap to next or previous position + const v = + state.scale - 0.1 * (_stamp_wheel_accum / Math.abs(_stamp_wheel_accum)); + + state.setScale(v + snap(v, 0, 0.1)); + state.redraw(evn); + + _stamp_wheel_accum = 0; // Zero accumulation + } else if (evn.evn.shiftKey && Math.abs(_stamp_wheel_accum) >= 1) { + const v = state.scale - _stamp_wheel_accum * 0.01; + state.setScale(v); + state.redraw(evn); + + _stamp_wheel_accum = 0; // Zero accumulation + } +}; + const stampTool = () => toolbar.registerTool( "./res/icons/file-up.svg", @@ -14,6 +52,12 @@ const stampTool = () => mouse.listen.world.btn.left.onclick.on(state.drawcb); mouse.listen.world.btn.right.onclick.on(state.cancelcb); + mouse.listen.world.btn.left.ondragstart.on(state.dragstartcb); + mouse.listen.world.btn.left.ondrag.on(state.dragcb); + mouse.listen.world.btn.left.ondragend.on(state.dragendcb); + + mouse.listen.world.onwheel.on(state.onwheelcb); + // For calls from other tools to paste image if (opt && opt.image) { state.addResource( @@ -41,6 +85,12 @@ const stampTool = () => mouse.listen.world.btn.left.onclick.clear(state.drawcb); mouse.listen.world.btn.right.onclick.clear(state.cancelcb); + mouse.listen.world.btn.left.ondragstart.clear(state.dragstartcb); + mouse.listen.world.btn.left.ondrag.clear(state.dragcb); + mouse.listen.world.btn.left.ondragend.clear(state.dragendcb); + + mouse.listen.world.onwheel.clear(state.onwheelcb); + ovLayer.clear(); }, { @@ -54,7 +104,15 @@ const stampTool = () => state.lastMouseMove = {x: 0, y: 0}; state.block_res_change = true; + // Current Rotation + let rotation = 0; + let rotating = null; + // Current Scale + state.scale = 1; + state.selectResource = (resource, nolock = true, deselect = true) => { + rotation = 0; + state.setScale(1); if (nolock && state.ctxmenu.uploadButton.disabled) return; console.debug( @@ -290,32 +348,65 @@ const stampTool = () => syncResources(); }; - state.movecb = (evn) => { - let x = evn.x; - let y = evn.y; - if (state.snapToGrid) { - x += snap(evn.x, 0, 64); - y += snap(evn.y, 0, 64); + state.onwheelcb = (evn) => { + _stamp_onwheel(evn, state); + }; + + state.dragstartcb = (evn) => { + const {x, y, sx, sy} = _tool._process_cursor(evn, state.snapToGrid); + rotating = {x: sx, y: sy}; + }; + + state.dragcb = (evn) => { + if (rotating) { + rotation = Math.atan2(rotating.x - evn.x, evn.y - rotating.y); + + if (evn.evn.shiftKey) + rotation = + config.rotationSnappingAngles.find( + (v) => + Math.abs(v - rotation) < config.rotationSnappingDistance + ) ?? rotation; } + }; - const vpc = viewport.canvasToView(x, y); - uiCtx.clearRect(0, 0, uiCanvas.width, uiCanvas.height); - state.erasePrevCursor && state.erasePrevCursor(); + state.dragendcb = (evn) => { + rotating = null; + }; - uiCtx.save(); + let erasePrevCursor = () => null; + + state.movecb = (evn) => { + const {x, y, sx, sy} = _tool._process_cursor(evn, state.snapToGrid); + + // Erase Previous Cursors + erasePrevCursor(); state.lastMouseMove = evn; ovLayer.clear(); + let px = sx; + let py = sy; + + if (rotating) { + px = rotating.x; + py = rotating.y; + } + // Draw selected image if (state.selected) { - ovCtx.drawImage(state.selected.image, x, y); + ovCtx.save(); + ovCtx.translate(px, py); + ovCtx.scale(state.scale, state.scale); + ovCtx.rotate(rotation); + + ovCtx.drawImage(state.selected.image, 0, 0); + ovCtx.restore(); } // Draw current cursor location - state.erasePrevCursor = _tool._cursor_draw(x, y); - uiCtx.restore(); + erasePrevCursor = _tool._cursor_draw(px, py); }; state.redraw = () => { @@ -323,20 +414,16 @@ const stampTool = () => }; state.drawcb = (evn) => { - let x = evn.x; - let y = evn.y; - if (state.snapToGrid) { - x += snap(evn.x, 0, 64); - y += snap(evn.y, 0, 64); - } + const {x, y, sx, sy} = _tool._process_cursor(evn, state.snapToGrid); const resource = state.selected; if (resource) { + const {canvas, bb} = cropCanvas(ovCanvas, {border: 10}); commands.runCommand("drawImage", "Image Stamp", { - image: resource.image, - x, - y, + image: canvas, + x: bb.x, + y: bb.y, }); if (resource.temporary) { @@ -380,6 +467,16 @@ const stampTool = () => ); state.ctxmenu.snapToGridLabel = array; + // Scale Slider + const scaleSlider = _toolbar_input.slider(state, "scale", "Scale", { + min: 0.01, + max: 10, + step: 0.1, + textStep: 0.01, + }); + state.ctxmenu.scaleSlider = scaleSlider.slider; + state.setScale = scaleSlider.setValue; + // Create resource list const uploadButtonId = `upload-btn-${guid()}`; @@ -528,6 +625,7 @@ const stampTool = () => }, populateContextMenu: (menu, state) => { menu.appendChild(state.ctxmenu.snapToGridLabel); + menu.appendChild(state.ctxmenu.scaleSlider); menu.appendChild(state.ctxmenu.resourceManager); }, shortcut: "U", From b590b6d124c7ac41989c5cce530dd203ca588cdd Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Thu, 12 Jan 2023 23:03:15 -0300 Subject: [PATCH 35/49] remove debugging by default Signed-off-by: Victor Seiji Hariki --- index.html | 2 +- js/initalize/debug.populate.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/index.html b/index.html index 7795d08..9cc895f 100644 --- a/index.html +++ b/index.html @@ -396,7 +396,7 @@ src="js/initalize/toolbar.populate.js?v=c1ca438" type="text/javascript"> @@ -383,7 +383,7 @@ - + diff --git a/js/ui/tool/generic.js b/js/ui/tool/generic.js index 62d19f1..04073b8 100644 --- a/js/ui/tool/generic.js +++ b/js/ui/tool/generic.js @@ -399,10 +399,12 @@ const _tool = { } hoveringRotateHandle(x, y, scale = 1) { - const localc = this.matrix.inverse().transformPoint({x, y}); + const localc = this.rtmatrix.inverse().transformPoint({x, y}); const localrh = { x: 0, - y: -this.canvas.height / 2 - config.rotateHandleDistance * scale, + y: + (-this.scale.y * this.canvas.height) / 2 - + config.rotateHandleDistance * scale, }; const dx = Math.abs(localc.x - localrh.x); diff --git a/js/ui/tool/stamp.js b/js/ui/tool/stamp.js index 31cd054..2ac60bd 100644 --- a/js/ui/tool/stamp.js +++ b/js/ui/tool/stamp.js @@ -472,7 +472,7 @@ const stampTool = () => min: 0.01, max: 10, step: 0.1, - textStep: 0.01, + textStep: 0.001, }); state.ctxmenu.scaleSlider = scaleSlider.slider; state.setScale = scaleSlider.setValue; diff --git a/pages/embed.test.html b/pages/embed.test.html index 729eacd..b4ac0ab 100644 --- a/pages/embed.test.html +++ b/pages/embed.test.html @@ -8,8 +8,8 @@ - + From aaf142e181ef3e3915d9a03d309566f11c1ada32 Mon Sep 17 00:00:00 2001 From: tim h Date: Sat, 14 Jan 2023 10:21:27 -0600 Subject: [PATCH 40/49] bug report form update --- .github/ISSUE_TEMPLATE/bug_report.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2b14085..e0fe904 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -65,11 +65,22 @@ body: - Apple Safari - Microsoft Edge - Other + validations: + required: true - type: textarea id: browser-extensions attributes: label: Browser Extensions/Addons description: Please list all browser extensions/addons you have running. Some have been known to cause issues with openOutpaint. + validations: + required: true + - type: textarea + id: webui-commandline + attributes: + label: AUTOMATIC1111 webUI Commandline Arguments + description: Please list all used commandline arguments passed to A1111 webUI (i.e. `--api`). + validations: + required: true - type: textarea id: misc attributes: From 3e19bef7b66ea775162171e455c45fabaa04a30a Mon Sep 17 00:00:00 2001 From: tim h Date: Sat, 14 Jan 2023 11:07:24 -0600 Subject: [PATCH 41/49] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index e0fe904..0418bc7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -53,6 +53,8 @@ body: - iOS - Android - Other/Cloud + validations: + required: true - type: dropdown id: browsers attributes: @@ -65,22 +67,22 @@ body: - Apple Safari - Microsoft Edge - Other - validations: - required: true + validations: + required: true - type: textarea id: browser-extensions attributes: label: Browser Extensions/Addons description: Please list all browser extensions/addons you have running. Some have been known to cause issues with openOutpaint. - validations: - required: true + validations: + required: true - type: textarea id: webui-commandline attributes: label: AUTOMATIC1111 webUI Commandline Arguments description: Please list all used commandline arguments passed to A1111 webUI (i.e. `--api`). - validations: - required: true + validations: + required: true - type: textarea id: misc attributes: From a3ea8576969f51140def7086d3eb510b0eb42ebd Mon Sep 17 00:00:00 2001 From: tim h Date: Sat, 14 Jan 2023 11:08:46 -0600 Subject: [PATCH 42/49] Update feature_request.yml --- .github/ISSUE_TEMPLATE/feature_request.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 820e076..60157dc 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -14,6 +14,8 @@ body: attributes: label: Is your feature request related to a problem? Please describe. description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + validations: + required: true - type: textarea id: feature attributes: @@ -37,6 +39,8 @@ body: attributes: label: Describe alternatives you've considered description: A clear and concise description of any alternative solutions or features you've considered. + validations: + required: true - type: textarea id: misc attributes: From 9c4451db7859f1264f6f74ce86a77950951763b4 Mon Sep 17 00:00:00 2001 From: tim h Date: Sat, 14 Jan 2023 12:54:25 -0600 Subject: [PATCH 43/49] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 0418bc7..70e54f8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -66,7 +66,8 @@ body: - Brave - Apple Safari - Microsoft Edge - - Other + - Opera + - Other (please list in additional information) validations: required: true - type: textarea From 4bbffb82aab5667fb37397be33e2c1662e0dff8a Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Sat, 14 Jan 2023 18:42:43 -0300 Subject: [PATCH 44/49] fix giant check for chrome (again) Signed-off-by: Victor Seiji Hariki --- css/ui/generic.css | 1 + index.html | 2 +- pages/configuration.html | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/css/ui/generic.css b/css/ui/generic.css index 801e2ba..09eb6ea 100644 --- a/css/ui/generic.css +++ b/css/ui/generic.css @@ -231,6 +231,7 @@ div.autocomplete > .autocomplete-list { } div.autocomplete > .autocomplete-list > .autocomplete-option { + position: relative; cursor: pointer; overflow: hidden; diff --git a/index.html b/index.html index 29dd5dc..53b8b87 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - + diff --git a/pages/configuration.html b/pages/configuration.html index 3243ab6..583721f 100644 --- a/pages/configuration.html +++ b/pages/configuration.html @@ -10,7 +10,7 @@ - + From dcb84a8de8bdb62f696b7b586b84b38b616fa96d Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Sat, 14 Jan 2023 18:44:31 -0300 Subject: [PATCH 45/49] fix fancy checkbox icons Signed-off-by: Victor Seiji Hariki --- css/icons.css | 2 ++ index.html | 2 +- pages/configuration.html | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/css/icons.css b/css/icons.css index e808b3b..d1c89d7 100644 --- a/css/icons.css +++ b/css/icons.css @@ -17,7 +17,9 @@ bottom: 15%; mask-size: contain; + -webkit-mask-size: contain; mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; max-height: 70%; aspect-ratio: 1; diff --git a/index.html b/index.html index 53b8b87..543ee99 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ openOutpaint 🐠 - + diff --git a/pages/configuration.html b/pages/configuration.html index 583721f..0dd887e 100644 --- a/pages/configuration.html +++ b/pages/configuration.html @@ -5,7 +5,7 @@ openOutpaint 🐠 - + From c30314b2ac14beb759f03613457d43261afb9c74 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Sat, 14 Jan 2023 18:46:01 -0300 Subject: [PATCH 46/49] remove now irrelevant TODO Signed-off-by: Victor Seiji Hariki --- index.html | 2 +- js/ui/tool/select.js | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/index.html b/index.html index 543ee99..be27d75 100644 --- a/index.html +++ b/index.html @@ -381,7 +381,7 @@ src="js/ui/tool/colorbrush.js?v=3f8c01a" type="text/javascript"> - + diff --git a/js/initalize/layers.populate.js b/js/initalize/layers.populate.js index cda7d89..296d087 100644 --- a/js/initalize/layers.populate.js +++ b/js/initalize/layers.populate.js @@ -322,8 +322,7 @@ mouse.listen.camera.onwheel.on((evn) => { //viewport.transform(imageCollection.element); - toolbar._current_tool.state.redrawui && - toolbar._current_tool.state.redrawui(); + toolbar._current_tool.redrawui && toolbar._current_tool.redrawui(); }); const cameraPaintStart = (evn) => { diff --git a/js/lib/toolbar.js b/js/lib/toolbar.js index 47be1e8..6706410 100644 --- a/js/lib/toolbar.js +++ b/js/lib/toolbar.js @@ -91,7 +91,7 @@ const toolbar = { enabled: false, _element: null, state: { - redrawui: () => tool.redraw(), + redrawui: () => tool.state.redraw && tool.state.redraw(), }, options, /** From b5c72392d81ab56272de390dff2f547ad52959b8 Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Sat, 14 Jan 2023 18:54:58 -0300 Subject: [PATCH 48/49] fix expand canvas icons Signed-off-by: Victor Seiji Hariki --- css/ui/layers.css | 2 ++ index.html | 2 +- pages/configuration.html | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/css/ui/layers.css b/css/ui/layers.css index c433b9c..385498d 100644 --- a/css/ui/layers.css +++ b/css/ui/layers.css @@ -158,7 +158,9 @@ background-color: #293d3d77; + -webkit-mask-image: url("../../res/icons/chevron-up.svg"); mask-image: url("../../res/icons/chevron-up.svg"); + -webkit-mask-size: contain; mask-size: contain; width: 60px; diff --git a/index.html b/index.html index e159383..c5fbb50 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ - + diff --git a/pages/configuration.html b/pages/configuration.html index 0dd887e..a182188 100644 --- a/pages/configuration.html +++ b/pages/configuration.html @@ -13,7 +13,7 @@ - + From 87cc1d8fa94b0c34df92958f30ff85405432c9e3 Mon Sep 17 00:00:00 2001 From: tim h Date: Sat, 14 Jan 2023 16:02:28 -0600 Subject: [PATCH 49/49] version bump, update readme --- README.md | 6 +++--- index.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e833692..7baf3f8 100644 --- a/README.md +++ b/README.md @@ -29,16 +29,16 @@ this is a completely vanilla javascript and html canvas outpainting convenience - optional (visibly) inverted mask mode - red masks get mutated, blue masks stay the same, but you can't take both pills at once - inpainting color brush to bring out your inner vincent van bob ross - dedicated img2img tool with optional border masking for enhanced output coherence with existing subject matter -- marquee select tool to select regions and arbitrarily scale, create stamps, move chunks, peek at lower layers, do all sorts of damage +- marquee select tool to select regions and arbitrarily scale, rotate, create stamps, move chunks, peek at lower layers, do all sorts of damage - optionally decoupled cursor size and output resolution - interrogate tool - floating control panel to easily change models/samplers/steps/prompts/CFG/etc options for each dream summoned from the latent void _(NOTE: model switching requires A1111 webUI to be on commit [5a6387e](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/5a6387e189dc365c47a7979b9040d5b6fdd7ba43) or more recent)_ - floating toolbox with handy keyboard shortcuts - optional grid snapping for precision - optional hi-res fix for blank/txt2img dreams - - **_NOTE: as of v0.0.12.5/webUI commit [ef27a18](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d), HRfix has been COMPLETELY reworked and no longer works remotely the same, thus openOutpaint's implementation is no longer compatible with versions of A1111 predating that. You will be alerted to the outdated webUI and the HRfix option will become limited to simply using [reticle dimensions / 2] in this event._** + - **_NOTE: as of v0.0.12.5/webUI commit [ef27a18](https://github.com/AUTOMATIC1111/stable-diffusion-webui/commit/ef27a18b6b7cb1a8eebdc9b2e88d25baf2c2414d), HRfix has been COMPLETELY reworked and no longer works remotely the same, thus openOutpaint's implementation is no longer compatible with versions of A1111 predating that. You will be alerted to the outdated webUI and the HRfix option will become limited to simply using [reticle dimensions / 2] in this event. Please see the [manual entry](https://github.com/zero01101/openOutpaint/wiki/Manual#hrfix) regarding HRfix and its available options._** - optional overmasking for potentially better seams between outpaints - set overmask px value to 0 to disable the feature -- import arbitrary images and scale/stamp on the canvas whenever, wherever you'd like +- import arbitrary images and rotate/scale/stamp on the canvas whenever, wherever you'd like - upscaler support for final output images - saves your preferences/imported images to browser localstorage for maximum convenience - reset to defaults button to unsave your preferences if things go squirrely diff --git a/index.html b/index.html index c5fbb50..f87960c 100644 --- a/index.html +++ b/index.html @@ -202,7 +202,7 @@
- Alpha release v0.0.12.5 + Alpha release v0.0.13