From 70281c4f438fc0f4be0c2e47d4a134b1d5456a17 Mon Sep 17 00:00:00 2001 From: Kalle Date: Tue, 22 Nov 2022 14:54:08 +0200 Subject: [PATCH 1/6] Convert that large gif into 5mb webm embed from 28 to 5mb Former-commit-id: a7c21b6ae476d8f236c8bf477de13640420ab9ba --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cc68e5..6a26bbc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # hello there 🐠 -![openOutpaint creating some undersea wildlife](docs/01-demo-v3-c.gif) +[openOutpaint creating some undersea wildlife](https://user-images.githubusercontent.com/1765167/203318284-a9f6970f-c9f1-44be-8c61-810aa5ed46be.webm) this is a completely vanilla javascript and html canvas outpainting convenience doodad built for the API optionally exposed by [AUTOMATIC1111's stable diffusion webUI](https://github.com/AUTOMATIC1111/stable-diffusion-webui), operating similarly to a few others which certainly have superior functionality. this simply offers an alternative for my following vain desires: From 837de404ee08453a93a88fca0b7653e3915ee107 Mon Sep 17 00:00:00 2001 From: Kalekki Date: Tue, 22 Nov 2022 23:18:40 +0200 Subject: [PATCH 2/6] Upscaling Former-commit-id: b8f0e47edd2f2f5ab2f8cae911c8739bd9d41b7f --- index.html | 4 ++ js/index.js | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 70cb933..e7ac7f1 100644 --- a/index.html +++ b/index.html @@ -89,6 +89,10 @@

+ + +
+ diff --git a/js/index.js b/js/index.js index a7592dd..3e039af 100644 --- a/js/index.js +++ b/js/index.js @@ -154,6 +154,7 @@ const bgCtx = bgCanvas.getContext("2d"); function startup() { checkIfWebuiIsRunning(); loadSettings(); + getUpscalers(); drawBackground(); changeScaleFactor(); changePaintMode(); @@ -904,8 +905,8 @@ function cropCanvas(sourceCanvas) { return a - b; }); var n = pix.x.length - 1; - w = pix.x[n] - pix.x[0]; - h = pix.y[n] - pix.y[0]; + w = (pix.x[n] - pix.x[0])+1; + h = (pix.y[n] - pix.y[0])+1; // yup sure looks like it try { @@ -940,6 +941,139 @@ function checkIfWebuiIsRunning() { }); } +function getUpscalers() { + + /* + so for some reason when upscalers request returns upscalers, the real-esrgan model names are incorrect, and need to be fetched from /sdapi/v1/realesrgan-models + also the realesrgan models returned are not all correct, extra fun! + LDSR seems to have problems so we dont add that either -> RuntimeError: Number of dimensions of repeat dims can not be smaller than number of dimensions of tensor + need to figure out why that is, if you dont get this error then you can add it back in + + Hacky way to get the correct list all in one go is to purposefully make an incorrect request, which then returns + { detail: "Invalid upscaler, needs to be on of these: None , Lanczos , Nearest , LDSR , BSRGAN , R-ESRGAN General 4xV3 , R-ESRGAN 4x+ Anime6B , ScuNET , ScuNET PSNR , SwinIR_4x" } + from which we can extract the correct list of upscalers + */ + + // hacky way to get the correct list of upscalers + var upscalerSelect = document.getElementById("upscalers"); + var extras_url = document.getElementById("host").value + "/sdapi/v1/extra-single-image/" // endpoint for upscaling, needed for the hacky way to get the correct list of upscalers + var empty_image = new Image(512, 512); + empty_image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAFCAAAAABCAYAAAChpRsuAAAALklEQVR42u3BAQ0AAAgDoJvc6LeHAybtBgAAAAAAAAAAAAAAAAAAAAAAAAB47QD2wAJ/LnnqGgAAAABJRU5ErkJggg=="; //transparent pixel + var purposefully_incorrect_data = { + "resize-mode" : 0, // 0 = just resize, 1 = crop and resize, 2 = resize and fill i assume based on theimg2img tabs options + "upscaling_resize": 2, + "upscaler_1": "fake_upscaler", + "image": empty_image.src, + } + + fetch(extras_url, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify(purposefully_incorrect_data), + }) + .then((response) => response.json()) + .then((data) => { + console.log( "purposefully_incorrect_data response, ignore above error"); + // result = purposefully_incorrect_data response: Invalid upscaler, needs to be on of these: None , Lanczos , Nearest , LDSR , BSRGAN , R-ESRGAN General 4xV3 , R-ESRGAN 4x+ Anime6B , ScuNET , ScuNET PSNR , SwinIR_4x + let upscalers = data.detail.split(": ")[1].trim().split(" , "); // converting the result to a list of upscalers + for (var i = 0; i < upscalers.length; i++) { + if(upscalers[i] == "LDSR") continue; // Skip LDSR, see reason in the first comment + var option = document.createElement("option"); + option.text = upscalers[i]; + option.value = upscalers[i]; + upscalerSelect.add(option); + } + + }) + + + /* THE NON HACKY WAY THAT I SIMPLY COULD NOT GET TO PRODUCE A LIST WITHOUT NON WORKING UPSCALERS, FEEL FREE TO TRY AND FIGURE IT OUT + + var url = document.getElementById("host").value + "/sdapi/v1/upscalers"; + var realesrgan_url = document.getElementById("host").value + "/sdapi/v1/realesrgan-models"; + + // get upscalers + fetch(url) + .then((response) => response.json()) + .then((data) => { + console.log(data); + + for (var i = 0; i < data.length; i++) { + var option = document.createElement("option"); + + if (data[i].name.includes("ESRGAN") || data[i].name.includes("LDSR")) { + continue; + } + option.text = data[i].name; + upscalerSelect.add(option); + } + }) + .catch((error) => { + alert( + "Error getting upscalers, please check console for additional info\n" + + error + ); + }); + // fetch realesrgan models separately + fetch(realesrgan_url) + .then((response) => response.json()) + .then((data) => { + var model = data; + for(var i = 0; i < model.length; i++){ + let option = document.createElement("option"); + option.text = model[i].name; + option.value = model[i].name; + upscalerSelect.add(option); + + } + + }) + */ +} + +async function upscaleAndDownload(){ + // Future improvements: some upscalers take a while to upscale, so we should show a loading bar or something, also a slider for the upscale amount + + // get cropped canvas, send it to upscaler, download result + var upscale_factor = 2; // TODO: make this a user input 1.x - 4.0 or something + var upscaler = document.getElementById("upscalers").value; + var croppedCanvas = cropCanvas(imgCanvas); + if (croppedCanvas != null) { + var upscaler = document.getElementById("upscalers").value; + var url = document.getElementById("host").value + "/sdapi/v1/extra-single-image/"; + var imgdata = croppedCanvas.toDataURL("image/png"); + var data = { + "resize-mode" : 0, // 0 = just resize, 1 = crop and resize, 2 = resize and fill i assume based on theimg2img tabs options + "upscaling_resize": upscale_factor, + "upscaler_1": upscaler, + "image": imgdata, + } + console.log(data); + await fetch(url, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }) + .then((response) => response.json()) + .then((data) => { + console.log(data); + var link = document.createElement("a"); + link.download = + new Date().toISOString().slice(0, 19).replace("T", " ").replace(":", " ") + + " openOutpaint image upscaler_"+upscaler+".png"; + link.href = "data:image/png;base64,"+data["image"]; + link.click(); + }) + } +} + + function loadSettings() { // set default values if not set var _sampler = From 9a796ecd673b3eaf38c78bfeaac4d539b244ae49 Mon Sep 17 00:00:00 2001 From: tim h Date: Tue, 22 Nov 2022 17:40:05 -0600 Subject: [PATCH 3/6] =?UTF-8?q?reenables=20LDSR,=20ran=20prettier,=20versi?= =?UTF-8?q?on=20bump=20(=20=CD=A1=C2=B0=20=CD=9C=CA=96=20=CD=A1=C2=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Former-commit-id: 2c75f84ad9a88f7454a5469bba8c4c90ca09186a --- index.html | 2 +- js/index.js | 95 ++++++++++++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/index.html b/index.html index e7ac7f1..872f161 100644 --- a/index.html +++ b/index.html @@ -117,7 +117,7 @@

- Alpha release v0.0.6.6 + Alpha release v0.0.6.9

diff --git a/js/index.js b/js/index.js index 3e039af..d3b3674 100644 --- a/js/index.js +++ b/js/index.js @@ -905,8 +905,8 @@ function cropCanvas(sourceCanvas) { return a - b; }); var n = pix.x.length - 1; - w = (pix.x[n] - pix.x[0])+1; - h = (pix.y[n] - pix.y[0])+1; + w = pix.x[n] - pix.x[0] + 1; + h = pix.y[n] - pix.y[0] + 1; // yup sure looks like it try { @@ -942,7 +942,6 @@ function checkIfWebuiIsRunning() { } function getUpscalers() { - /* so for some reason when upscalers request returns upscalers, the real-esrgan model names are incorrect, and need to be fetched from /sdapi/v1/realesrgan-models also the realesrgan models returned are not all correct, extra fun! @@ -953,19 +952,21 @@ function getUpscalers() { { detail: "Invalid upscaler, needs to be on of these: None , Lanczos , Nearest , LDSR , BSRGAN , R-ESRGAN General 4xV3 , R-ESRGAN 4x+ Anime6B , ScuNET , ScuNET PSNR , SwinIR_4x" } from which we can extract the correct list of upscalers */ - + // hacky way to get the correct list of upscalers var upscalerSelect = document.getElementById("upscalers"); - var extras_url = document.getElementById("host").value + "/sdapi/v1/extra-single-image/" // endpoint for upscaling, needed for the hacky way to get the correct list of upscalers + var extras_url = + document.getElementById("host").value + "/sdapi/v1/extra-single-image/"; // endpoint for upscaling, needed for the hacky way to get the correct list of upscalers var empty_image = new Image(512, 512); - empty_image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAFCAAAAABCAYAAAChpRsuAAAALklEQVR42u3BAQ0AAAgDoJvc6LeHAybtBgAAAAAAAAAAAAAAAAAAAAAAAAB47QD2wAJ/LnnqGgAAAABJRU5ErkJggg=="; //transparent pixel + empty_image.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAFCAAAAABCAYAAAChpRsuAAAALklEQVR42u3BAQ0AAAgDoJvc6LeHAybtBgAAAAAAAAAAAAAAAAAAAAAAAAB47QD2wAJ/LnnqGgAAAABJRU5ErkJggg=="; //transparent pixel var purposefully_incorrect_data = { - "resize-mode" : 0, // 0 = just resize, 1 = crop and resize, 2 = resize and fill i assume based on theimg2img tabs options - "upscaling_resize": 2, - "upscaler_1": "fake_upscaler", - "image": empty_image.src, - } - + "resize-mode": 0, // 0 = just resize, 1 = crop and resize, 2 = resize and fill i assume based on theimg2img tabs options + upscaling_resize: 2, + upscaler_1: "fake_upscaler", + image: empty_image.src, + }; + fetch(extras_url, { method: "POST", headers: { @@ -974,21 +975,19 @@ function getUpscalers() { }, body: JSON.stringify(purposefully_incorrect_data), }) - .then((response) => response.json()) - .then((data) => { - console.log( "purposefully_incorrect_data response, ignore above error"); - // result = purposefully_incorrect_data response: Invalid upscaler, needs to be on of these: None , Lanczos , Nearest , LDSR , BSRGAN , R-ESRGAN General 4xV3 , R-ESRGAN 4x+ Anime6B , ScuNET , ScuNET PSNR , SwinIR_4x - let upscalers = data.detail.split(": ")[1].trim().split(" , "); // converting the result to a list of upscalers - for (var i = 0; i < upscalers.length; i++) { - if(upscalers[i] == "LDSR") continue; // Skip LDSR, see reason in the first comment - var option = document.createElement("option"); - option.text = upscalers[i]; - option.value = upscalers[i]; - upscalerSelect.add(option); - } - - }) - + .then((response) => response.json()) + .then((data) => { + console.log("purposefully_incorrect_data response, ignore above error"); + // result = purposefully_incorrect_data response: Invalid upscaler, needs to be on of these: None , Lanczos , Nearest , LDSR , BSRGAN , R-ESRGAN General 4xV3 , R-ESRGAN 4x+ Anime6B , ScuNET , ScuNET PSNR , SwinIR_4x + let upscalers = data.detail.split(": ")[1].trim().split(" , "); // converting the result to a list of upscalers + for (var i = 0; i < upscalers.length; i++) { + // if(upscalers[i] == "LDSR") continue; // Skip LDSR, see reason in the first comment // readded because worksonmymachine.jpg but leaving it here in case of, uh, future disaster? + var option = document.createElement("option"); + option.text = upscalers[i]; + option.value = upscalers[i]; + upscalerSelect.add(option); + } + }); /* THE NON HACKY WAY THAT I SIMPLY COULD NOT GET TO PRODUCE A LIST WITHOUT NON WORKING UPSCALERS, FEEL FREE TO TRY AND FIGURE IT OUT @@ -1034,7 +1033,7 @@ function getUpscalers() { */ } -async function upscaleAndDownload(){ +async function upscaleAndDownload() { // Future improvements: some upscalers take a while to upscale, so we should show a loading bar or something, also a slider for the upscale amount // get cropped canvas, send it to upscaler, download result @@ -1043,14 +1042,15 @@ async function upscaleAndDownload(){ var croppedCanvas = cropCanvas(imgCanvas); if (croppedCanvas != null) { var upscaler = document.getElementById("upscalers").value; - var url = document.getElementById("host").value + "/sdapi/v1/extra-single-image/"; + var url = + document.getElementById("host").value + "/sdapi/v1/extra-single-image/"; var imgdata = croppedCanvas.toDataURL("image/png"); var data = { - "resize-mode" : 0, // 0 = just resize, 1 = crop and resize, 2 = resize and fill i assume based on theimg2img tabs options - "upscaling_resize": upscale_factor, - "upscaler_1": upscaler, - "image": imgdata, - } + "resize-mode": 0, // 0 = just resize, 1 = crop and resize, 2 = resize and fill i assume based on theimg2img tabs options + upscaling_resize: upscale_factor, + upscaler_1: upscaler, + image: imgdata, + }; console.log(data); await fetch(url, { method: "POST", @@ -1060,20 +1060,25 @@ async function upscaleAndDownload(){ }, body: JSON.stringify(data), }) - .then((response) => response.json()) - .then((data) => { - console.log(data); - var link = document.createElement("a"); - link.download = - new Date().toISOString().slice(0, 19).replace("T", " ").replace(":", " ") + - " openOutpaint image upscaler_"+upscaler+".png"; - link.href = "data:image/png;base64,"+data["image"]; - link.click(); - }) + .then((response) => response.json()) + .then((data) => { + console.log(data); + var link = document.createElement("a"); + link.download = + new Date() + .toISOString() + .slice(0, 19) + .replace("T", " ") + .replace(":", " ") + + " openOutpaint image upscaler_" + + upscaler + + ".png"; + link.href = "data:image/png;base64," + data["image"]; + link.click(); + }); } } - function loadSettings() { // set default values if not set var _sampler = From 624c01f5cbdd3ef4b7a630d4c2b8398376bb85f0 Mon Sep 17 00:00:00 2001 From: tim h Date: Tue, 22 Nov 2022 17:41:14 -0600 Subject: [PATCH 4/6] update readme Former-commit-id: 32c8618e4432a21eef4cda0bb5054e6349229ea3 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a26bbc..90e1b15 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,14 @@ this is a completely vanilla javascript and html canvas outpainting convenience - optional hi-res fix for blank/txt2img dreams which, if enabled, uses image width/height / 2 as firstpass size - import arbitrary images and superimpose on the canvas wherever you'd like ([extra fun with transparent .pngs!](#arbitrary_transparent)) - "temporary" monitors at the bottom to see exactly what mask/image you're feeding img2img, no i'm certainly not using them as actual imagedata sources or anything +- upscaler support for final output images _(NOTE: LDSR has had reports of not operating correctly when selected - please test and see if it works as expected)_ - saves your preferences to browser localstorage for maximum convenience - undo/redo with ctrl+z/y keyboard shortcuts for additional maximum convenience ## collaborator credits πŸ‘‘ - [@jasonmhead](https://github.com/jasonmhead) - [the most minimal launch script](https://github.com/zero01101/openOutpaint/pull/1) -- [@Kalekki](https://github.com/Kalekki) - [what i was calling "smart crop"](https://github.com/zero01101/openOutpaint/pull/2), [localstorage](https://github.com/zero01101/openOutpaint/pull/5), [right-click erase](https://github.com/zero01101/openOutpaint/pull/7), [delightful floating UI](https://github.com/zero01101/openOutpaint/pull/11), [mask erase fix](https://github.com/zero01101/openOutpaint/pull/17), [checkerboard background and non bonkers canvas borders](https://github.com/zero01101/openOutpaint/pull/24) +- [@Kalekki](https://github.com/Kalekki) - [what i was calling "smart crop"](https://github.com/zero01101/openOutpaint/pull/2), [localstorage](https://github.com/zero01101/openOutpaint/pull/5), [right-click erase](https://github.com/zero01101/openOutpaint/pull/7), [delightful floating UI](https://github.com/zero01101/openOutpaint/pull/11), [mask erase fix](https://github.com/zero01101/openOutpaint/pull/17), [checkerboard background and non bonkers canvas borders](https://github.com/zero01101/openOutpaint/pull/24), [upscaling output image](https://github.com/zero01101/openOutpaint/pull/35) - [@seijihariki](https://github.com/seijihariki) - [realtime slider value updates, gracious code cleanup](https://github.com/zero01101/openOutpaint/pull/14), [blessed undo/redo](https://github.com/zero01101/openOutpaint/pull/21), [even more wildly massive rework of loads of my miserable of JS holy crap](https://github.com/zero01101/openOutpaint/pull/22), [undo/redo keyboard shortcuts and keyboard input support](https://github.com/zero01101/openOutpaint/pull/30), [scrumptious photography-shoppe-style history palette](https://github.com/zero01101/openOutpaint/commit/b12fc0d2a02074cb31c0ef35ce56d2bd02244908) - [@lifeh2o](https://www.reddit.com/user/lifeh2o/overview) - overmasking concept ~~that is still driving me crazy getting it to work right~~ ([a](https://www.reddit.com/r/StableDiffusion/comments/ywf8np/i_made_a_completely_local_offline_opensource/iwl6s06/),[b](https://www.reddit.com/r/StableDiffusion/comments/ys9lhq/kollai_an_infinite_multiuser_canvas_running_on/ivzygwk/?context=3)) [possible betterness?](https://github.com/zero01101/openOutpaint/commit/8002772ee6aa4b2f5b544af82cb6d545cf81368f) @@ -167,6 +168,7 @@ imported a transparent clip of a [relatively famous happy lil kitty](https://com - 0.0.6 - absolutely brilliant undo/redo system, logical and straightforward enough to the point where even i can understand what it's doing [25681b3](https://github.com/zero01101/openOutpaint/commit/25681b3a83bbd7a1d1b3e675f26f141692d77c79) - 0.0.6.1 - finally think i've got overmasking working better with a bit of "humanization" to the automated masks, please play around with it and see if it's any better or just sucks in general [8002772](https://github.com/zero01101/openOutpaint/commit/8002772ee6aa4b2f5b544af82cb6d545cf81368f) - 0.0.6.5 - checkerboard background, far more attractive painted masking, HUGE code cleanup omg [74d5f13](https://github.com/zero01101/openOutpaint/commit/74d5f13aa582695e3e359ad46f7e629a25fb0091) +- 0.0.6.9 - upscaler support for final output image [3b91a89](https://github.com/zero01101/openOutpaint/commit/3b91a89214e22930ad75fdc2d9e6e79a5f40ee82) ## what's with the fish? From 9cf5ca236a388c8777185934f97fdd12b0a71230 Mon Sep 17 00:00:00 2001 From: tim h Date: Tue, 22 Nov 2022 18:08:16 -0600 Subject: [PATCH 5/6] remove giant gifs, goodbye gifs Former-commit-id: a9150cc43e002515418852582bd3b49365973883 --- docs/01-demo-v2.gif.REMOVED.git-id | 1 - docs/01-demo-v3-c.gif.REMOVED.git-id | 1 - 2 files changed, 2 deletions(-) delete mode 100644 docs/01-demo-v2.gif.REMOVED.git-id delete mode 100644 docs/01-demo-v3-c.gif.REMOVED.git-id diff --git a/docs/01-demo-v2.gif.REMOVED.git-id b/docs/01-demo-v2.gif.REMOVED.git-id deleted file mode 100644 index cfb0204..0000000 --- a/docs/01-demo-v2.gif.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4b5fbd2adfcf11a8758f18d02ec6295942a3a941 \ No newline at end of file diff --git a/docs/01-demo-v3-c.gif.REMOVED.git-id b/docs/01-demo-v3-c.gif.REMOVED.git-id deleted file mode 100644 index c8aab39..0000000 --- a/docs/01-demo-v3-c.gif.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c3f0f5c0a67b0e6052db6d34d48f636fb06259d6 \ No newline at end of file From e619636d3392459b336a829ebf8592eafd73cb34 Mon Sep 17 00:00:00 2001 From: tim h Date: Tue, 22 Nov 2022 19:35:15 -0600 Subject: [PATCH 6/6] not super attractive but really simple progress indicator during generation (not so much on upscale yet) Former-commit-id: 802cb7507d160035207b8c15b98b9d6fa9855525 --- README.md | 3 ++- js/index.js | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 90e1b15..5749183 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,8 @@ you'll obviously need A1111's webUI installed before you can use this, thus you' - [x] image erase region in case you decide later that you're not too happy with earlier results (technically i guess you could just mask over the entire region you dislike but that's... bad) - [ ] controls for the rest of API-available options (e.g. ~~hires fix~~, inpaint fill modes, etc) - [x] ~~save user-set option values to browser localstorage to persist your preferred, uh, preferences~~ -- [ ] render progress spinner/bar +- [x] render progress spinner/bar +- [ ] make render progress bar prettier - [x] ~~smart crop downloaded image~~ - [x] import external image and ~~scale/~~ superimpose at will on canvas for in/outpainting - [ ] scaling of imported arbitrary image before superimposition diff --git a/js/index.js b/js/index.js index d3b3674..8f6fed3 100644 --- a/js/index.js +++ b/js/index.js @@ -126,6 +126,7 @@ var placingArbitraryImage = false; // for when the user has loaded an existing i var enableErasing = false; // accidental right-click erase if the user isn't trying to erase is a bad thing var marchOffset = 0; var marching = false; +var inProgress = false; var marchCoords = {}; // info div, sometimes hidden @@ -209,6 +210,7 @@ function dream(x, y, prompt) { //console.log(data); // JSON data parsed by `data.json()` call imageAcceptReject(x, y, data); }); + checkProgress(); } async function postData(promptData) { @@ -231,6 +233,8 @@ async function postData(promptData) { } function imageAcceptReject(x, y, data) { + inProgress = false; + document.getElementById("progressDiv").remove(); const img = new Image(); img.onload = function () { tempCtx.drawImage(img, x, y); //imgCtx for actual image, tmp for... holding? @@ -242,7 +246,7 @@ function imageAcceptReject(x, y, data) { div.style.width = "200px"; div.style.height = "70px"; div.innerHTML = - ' of '; + ' of '; document.getElementById("tempDiv").appendChild(div); document.getElementById("currentImgIndex").innerText = "1"; document.getElementById("totalImgIndex").innerText = totalImagesReturned; @@ -404,6 +408,39 @@ function drawMarchingAnts() { tgtCtx.strokeRect(marchCoords.x, marchCoords.y, marchCoords.w, marchCoords.h); } +function checkProgress() { + document.getElementById("progressDiv") && + document.getElementById("progressDiv").remove(); + endpoint = "progress?skip_current_image=false"; + var div = document.createElement("div"); + div.id = "progressDiv"; + div.style.position = "absolute"; + div.style.width = "200px"; + div.style.height = "70px"; + div.style.left = parseInt(marchCoords.x + marchCoords.w - 100) + "px"; + div.style.top = parseInt(marchCoords.y + marchCoords.h) + "px"; + div.innerHTML = ''; + document.getElementById("tempDiv").appendChild(div); + updateProgress(); +} + +function updateProgress() { + if (inProgress) { + fetch(host + url + endpoint) + .then((response) => response.json()) + .then((data) => { + var estimate = + Math.round(data.progress * 100) + + "% :: " + + Math.floor(data.eta_relative) + + " sec."; + + document.getElementById("estRemaining").innerText = estimate; + }); + setTimeout(updateProgress, 500); + } +} + function mouseMove(evt) { const rect = ovCanvas.getBoundingClientRect(); // not-quite pixel offset was driving me insane const canvasOffsetX = rect.left; @@ -569,7 +606,7 @@ function mouseUp(evt) { if (!blockNewImages) { //TODO seriously, refactor this blockNewImages = true; - marching = true; + marching = inProgress = true; var drawIt = {}; //why am i doing this???? var target = drawTargets[drawTargets.length - 1]; //get the last one... why am i storing all of them? var oddOffset = 0;