prettier!

This commit is contained in:
tim h 2022-11-20 15:39:24 -06:00
parent 32206ff6ee
commit 327e90c88c
4 changed files with 920 additions and 776 deletions

19
.prettierrc.json Normal file
View file

@ -0,0 +1,19 @@
{
"arrowParens": "always",
"bracketSameLine": true,
"bracketSpacing": false,
"embeddedLanguageFormatting": "auto",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"jsxSingleQuote": false,
"printWidth": 80,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"vueIndentScriptAndStyle": false
}

View file

@ -40,9 +40,7 @@ const commands = {
try { try {
run(copy, state); run(copy, state);
} catch (e) { } catch (e) {
console.warn( console.warn(`Error while running command '${name}' with options:`);
`Error while running command '${name}' with options:`
);
console.warn(copy); console.warn(copy);
console.warn(e); console.warn(e);
return; return;
@ -60,7 +58,7 @@ const commands = {
// Add to history // Add to history
if (commands.history.length > commands.current + 1) if (commands.history.length > commands.current + 1)
commands.history.splice(commands.current + 1); commands.history.splice(commands.current + 1);
commands.history.push({ undo: undoWrapper, redo: redoWrapper }); commands.history.push({undo: undoWrapper, redo: redoWrapper});
commands.current++; commands.current++;
}; };
@ -120,12 +118,7 @@ commands.createCommand(
}, },
(state) => { (state) => {
// Clear destination area // Clear destination area
state.context.clearRect( state.context.clearRect(state.box.x, state.box.y, state.box.w, state.box.h);
state.box.x,
state.box.y,
state.box.w,
state.box.h
);
// Undo // Undo
state.context.drawImage(state.original, state.box.x, state.box.y); state.context.drawImage(state.original, state.box.x, state.box.y);
} }

View file

@ -3,7 +3,8 @@
window.onload = startup; window.onload = startup;
var stableDiffusionData = { //includes img2img data but works for txt2img just fine var stableDiffusionData = {
//includes img2img data but works for txt2img just fine
prompt: "", prompt: "",
negative_prompt: "", negative_prompt: "",
seed: -1, seed: -1,
@ -44,13 +45,19 @@ var stableDiffusionData = { //includes img2img data but works for txt2img just f
// "inpaint_full_res_padding": 0, // px // "inpaint_full_res_padding": 0, // px
// "inpainting_mask_invert": 0, // bool??????? wtf // "inpainting_mask_invert": 0, // bool??????? wtf
// "include_init_images": false // ?????? // "include_init_images": false // ??????
};
}
/** /**
* Some Utility Functions * Some Utility Functions
*/ */
function sliderChangeHandlerFactory(sliderId, textBoxId, dataKey, defaultV, setter = (k, v) => stableDiffusionData[k] = v, getter = (k) => stableDiffusionData[k]) { function sliderChangeHandlerFactory(
sliderId,
textBoxId,
dataKey,
defaultV,
setter = (k, v) => (stableDiffusionData[k] = v),
getter = (k) => stableDiffusionData[k]
) {
const sliderEl = document.getElementById(sliderId); const sliderEl = document.getElementById(sliderId);
const textBoxEl = document.getElementById(textBoxId); const textBoxEl = document.getElementById(textBoxId);
const savedValue = localStorage.getItem(dataKey); const savedValue = localStorage.getItem(dataKey);
@ -63,17 +70,18 @@ function sliderChangeHandlerFactory(sliderId, textBoxId, dataKey, defaultV, sett
if (value) setter(dataKey, value); if (value) setter(dataKey, value);
if (!eventSource || eventSource.id === textBoxId) sliderEl.value = getter(dataKey); if (!eventSource || eventSource.id === textBoxId)
setter(dataKey, Number(sliderEl.value)) sliderEl.value = getter(dataKey);
setter(dataKey, Number(sliderEl.value));
textBoxEl.value = getter(dataKey); textBoxEl.value = getter(dataKey);
localStorage.setItem(dataKey, getter(dataKey)); localStorage.setItem(dataKey, getter(dataKey));
} }
textBoxEl.onchange = changeHandler textBoxEl.onchange = changeHandler;
sliderEl.oninput = changeHandler sliderEl.oninput = changeHandler;
return changeHandler return changeHandler;
} }
// stuff things use // stuff things use
@ -83,7 +91,7 @@ var imageIndex = 0;
var tmpImgXYWH = {}; var tmpImgXYWH = {};
var host = ""; var host = "";
var url = "/sdapi/v1/"; var url = "/sdapi/v1/";
var endpoint = "txt2img" var endpoint = "txt2img";
var frameX = 512; var frameX = 512;
var frameY = 512; var frameY = 512;
var prevMouseX = 0; var prevMouseX = 0;
@ -166,13 +174,13 @@ function startup() {
function drop(imageParams) { function drop(imageParams) {
const img = new Image(); const img = new Image();
img.onload = function () { img.onload = function () {
writeArbitraryImage(img, imageParams.x, imageParams.y) writeArbitraryImage(img, imageParams.x, imageParams.y);
} };
img.src = arbitraryImageBase64; img.src = arbitraryImageBase64;
} }
function writeArbitraryImage(img, x, y) { function writeArbitraryImage(img, x, y) {
commands.runCommand('drawImage', { commands.runCommand("drawImage", {
x, x,
y, y,
image: img, image: img,
@ -187,9 +195,10 @@ function dream(x, y, prompt) {
tmpImgXYWH.y = y; tmpImgXYWH.y = y;
tmpImgXYWH.w = prompt.width; tmpImgXYWH.w = prompt.width;
tmpImgXYWH.h = prompt.height; tmpImgXYWH.h = prompt.height;
console.log("dreaming to " + host + url + endpoint + ":\r\n" + JSON.stringify(prompt)); console.log(
postData(prompt) "dreaming to " + host + url + endpoint + ":\r\n" + JSON.stringify(prompt)
.then((data) => { );
postData(prompt).then((data) => {
returnedImages = data.images; returnedImages = data.images;
totalImagesReturned = data.images.length; totalImagesReturned = data.images.length;
blockNewImages = true; blockNewImages = true;
@ -202,17 +211,17 @@ async function postData(promptData) {
this.host = document.getElementById("host").value; this.host = document.getElementById("host").value;
// Default options are marked with * // Default options are marked with *
const response = await fetch(this.host + this.url + this.endpoint, { const response = await fetch(this.host + this.url + this.endpoint, {
method: 'POST', // *GET, POST, PUT, DELETE, etc. method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin mode: "cors", // no-cors, *cors, same-origin
cache: 'default', // *default, no-cache, reload, force-cache, only-if-cached cache: "default", // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit credentials: "same-origin", // include, *same-origin, omit
headers: { headers: {
'Accept': 'application/json', Accept: "application/json",
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
redirect: 'follow', // manual, *follow, error redirect: "follow", // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(promptData) // body data type must match "Content-Type" header body: JSON.stringify(promptData), // body data type must match "Content-Type" header
}); });
return response.json(); // parses JSON response into native JavaScript objects return response.json(); // parses JSON response into native JavaScript objects
} }
@ -228,11 +237,12 @@ function imageAcceptReject(x, y, data) {
div.style.top = parseInt(y + data.parameters.height) + "px"; div.style.top = parseInt(y + data.parameters.height) + "px";
div.style.width = "150px"; div.style.width = "150px";
div.style.height = "50px"; div.style.height = "50px";
div.innerHTML = "<button onclick=\"prevImg(this)\">&lt;</button><button onclick=\"nextImg(this)\">&gt;</button><span class=\"strokeText\" id=\"currentImgIndex\"></span><span class=\"strokeText\"> of </span><span class=\"strokeText\" id=\"totalImgIndex\"></span><button onclick=\"accept(this)\">Y</button><button onclick=\"reject(this)\">N</button>" div.innerHTML =
'<button onclick="prevImg(this)">&lt;</button><button onclick="nextImg(this)">&gt;</button><span class="strokeText" id="currentImgIndex"></span><span class="strokeText"> of </span><span class="strokeText" id="totalImgIndex"></span><button onclick="accept(this)">Y</button><button onclick="reject(this)">N</button>';
document.getElementById("tempDiv").appendChild(div); document.getElementById("tempDiv").appendChild(div);
document.getElementById("currentImgIndex").innerText = "1"; document.getElementById("currentImgIndex").innerText = "1";
document.getElementById("totalImgIndex").innerText = totalImagesReturned; document.getElementById("totalImgIndex").innerText = totalImagesReturned;
} };
// set the image displayed as the first regardless of batch size/count // set the image displayed as the first regardless of batch size/count
imageIndex = 0; imageIndex = 0;
// load the image data after defining the closure // load the image data after defining the closure
@ -272,7 +282,7 @@ function prevImg(evt) {
} }
function nextImg(evt) { function nextImg(evt) {
if (imageIndex == (totalImagesReturned - 1)) { if (imageIndex == totalImagesReturned - 1) {
imageIndex = -1; imageIndex = -1;
} }
changeImg(true); changeImg(true);
@ -283,7 +293,7 @@ function changeImg(forward) {
tempCtx.clearRect(0, 0, tempCtx.width, tempCtx.height); tempCtx.clearRect(0, 0, tempCtx.width, tempCtx.height);
img.onload = function () { img.onload = function () {
tempCtx.drawImage(img, tmpImgXYWH.x, tmpImgXYWH.y); //imgCtx for actual image, tmp for... holding? tempCtx.drawImage(img, tmpImgXYWH.x, tmpImgXYWH.y); //imgCtx for actual image, tmp for... holding?
} };
var tmpIndex = document.getElementById("currentImgIndex"); var tmpIndex = document.getElementById("currentImgIndex");
if (forward) { if (forward) {
imageIndex++; imageIndex++;
@ -305,7 +315,11 @@ function restoreBackupMask() {
// reapply mask if exists // reapply mask if exists
if (backupMaskChunk != null && backupMaskX != null && backupMaskY != null) { if (backupMaskChunk != null && backupMaskX != null && backupMaskY != null) {
// backup mask data exists // backup mask data exists
var iData = new ImageData(backupMaskChunk.data, backupMaskChunk.height, backupMaskChunk.width); var iData = new ImageData(
backupMaskChunk.data,
backupMaskChunk.height,
backupMaskChunk.width
);
maskPaintCtx.putImageData(iData, backupMaskX, backupMaskY); maskPaintCtx.putImageData(iData, backupMaskX, backupMaskY);
} }
} }
@ -332,22 +346,21 @@ function clearPaintedMask() {
function placeImage() { function placeImage() {
const img = new Image(); const img = new Image();
img.onload = function () { img.onload = function () {
commands.runCommand('drawImage', { commands.runCommand("drawImage", {
x: tmpImgXYWH.x, x: tmpImgXYWH.x,
y: tmpImgXYWH.y, y: tmpImgXYWH.y,
image: img, image: img,
}); });
tmpImgXYWH = {}; tmpImgXYWH = {};
returnedImages = null; returnedImages = null;
} };
// load the image data after defining the closure // load the image data after defining the closure
img.src = "data:image/png;base64," + returnedImages[imageIndex]; img.src = "data:image/png;base64," + returnedImages[imageIndex];
} }
function sleep(ms) { function sleep(ms) {
// what was this even for, anyway? // what was this even for, anyway?
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
} }
function snap(i, scaled = true) { function snap(i, scaled = true) {
@ -356,19 +369,18 @@ function snap(i, scaled = true) {
if (scaled) { if (scaled) {
if (scaleFactor % 2 != 0) { if (scaleFactor % 2 != 0) {
// odd number, snaps to center of cell, oops // odd number, snaps to center of cell, oops
scaleOffset = (basePixelCount / 2); scaleOffset = basePixelCount / 2;
} }
} }
var snapOffset = i % basePixelCount - scaleOffset; var snapOffset = (i % basePixelCount) - scaleOffset;
if (snapOffset == 0) { if (snapOffset == 0) {
return snapOffset; return snapOffset;
} }
return -snapOffset; return -snapOffset;
} }
function mouseMove(evt) { function mouseMove(evt) {
const rect = ovCanvas.getBoundingClientRect() // not-quite pixel offset was driving me insane const rect = ovCanvas.getBoundingClientRect(); // not-quite pixel offset was driving me insane
const canvasOffsetX = rect.left; const canvasOffsetX = rect.left;
const canvasOffsetY = rect.top; const canvasOffsetY = rect.top;
heldButton = evt.buttons; heldButton = evt.buttons;
@ -402,7 +414,12 @@ function mouseMove(evt) {
} }
finalX = snapOffsetX + canvasX; finalX = snapOffsetX + canvasX;
finalY = snapOffsetY + canvasY; finalY = snapOffsetY + canvasY;
ovCtx.strokeRect(parseInt(finalX - ((basePixelCount * scaleFactor) / 2)), parseInt(finalY - ((basePixelCount * scaleFactor) / 2)), basePixelCount * scaleFactor, basePixelCount * scaleFactor); //origin is middle of the frame ovCtx.strokeRect(
parseInt(finalX - (basePixelCount * scaleFactor) / 2),
parseInt(finalY - (basePixelCount * scaleFactor) / 2),
basePixelCount * scaleFactor,
basePixelCount * scaleFactor
); //origin is middle of the frame
} else { } else {
// draw big translucent red blob cursor // draw big translucent red blob cursor
ovCtx.beginPath(); ovCtx.beginPath();
@ -414,27 +431,26 @@ function mouseMove(evt) {
mouseY = parseInt(evt.clientY - canvasOffsetY); mouseY = parseInt(evt.clientY - canvasOffsetY);
if (clicked) { if (clicked) {
// i'm trying to draw, please draw :( // i'm trying to draw, please draw :(
maskPaintCtx.globalCompositeOperation = 'source-over'; maskPaintCtx.globalCompositeOperation = "source-over";
maskPaintCtx.strokeStyle = "#FF6A6A10"; maskPaintCtx.strokeStyle = "#FF6A6A10";
maskPaintCtx.lineWidth = 8 * scaleFactor; maskPaintCtx.lineWidth = 8 * scaleFactor;
maskPaintCtx.beginPath(); maskPaintCtx.beginPath();
maskPaintCtx.moveTo(prevMouseX, prevMouseY); maskPaintCtx.moveTo(prevMouseX, prevMouseY);
maskPaintCtx.lineTo(mouseX, mouseY); maskPaintCtx.lineTo(mouseX, mouseY);
maskPaintCtx.lineJoin = maskPaintCtx.lineCap = 'round'; maskPaintCtx.lineJoin = maskPaintCtx.lineCap = "round";
maskPaintCtx.stroke(); maskPaintCtx.stroke();
} }
// Erase mask if right button is held // Erase mask if right button is held
// no reason to have to tick a checkbox for this, more intuitive for both erases (mask and actual images) to just work on right click and inform the user about it // no reason to have to tick a checkbox for this, more intuitive for both erases (mask and actual images) to just work on right click and inform the user about it
if (evt.buttons == 2) { if (evt.buttons == 2) {
maskPaintCtx.globalCompositeOperation = 'destination-out'; maskPaintCtx.globalCompositeOperation = "destination-out";
maskPaintCtx.beginPath(); maskPaintCtx.beginPath();
maskPaintCtx.strokeStyle = "#FFFFFFFF"; maskPaintCtx.strokeStyle = "#FFFFFFFF";
maskPaintCtx.lineWidth = 8 * scaleFactor; maskPaintCtx.lineWidth = 8 * scaleFactor;
maskPaintCtx.moveTo(prevMouseX, prevMouseY); maskPaintCtx.moveTo(prevMouseX, prevMouseY);
maskPaintCtx.lineTo(mouseX, mouseY); maskPaintCtx.lineTo(mouseX, mouseY);
maskPaintCtx.lineJoin = maskPaintCtx.lineCap = 'round'; maskPaintCtx.lineJoin = maskPaintCtx.lineCap = "round";
maskPaintCtx.stroke(); maskPaintCtx.stroke();
} }
prevMouseX = mouseX; prevMouseX = mouseX;
prevMouseY = mouseY; prevMouseY = mouseY;
@ -442,12 +458,13 @@ function mouseMove(evt) {
} }
function mouseDown(evt) { function mouseDown(evt) {
const rect = ovCanvas.getBoundingClientRect() const rect = ovCanvas.getBoundingClientRect();
var oddOffset = 0; var oddOffset = 0;
if (scaleFactor % 2 != 0) { if (scaleFactor % 2 != 0) {
oddOffset = basePixelCount / 2; oddOffset = basePixelCount / 2;
} }
if (evt.button == 0) { // left click if (evt.button == 0) {
// left click
if (placingArbitraryImage) { if (placingArbitraryImage) {
var nextBox = {}; var nextBox = {};
nextBox.x = evt.offsetX; nextBox.x = evt.offsetX;
@ -465,26 +482,43 @@ function mouseDown(evt) {
} else { } else {
//const rect = ovCanvas.getBoundingClientRect() //const rect = ovCanvas.getBoundingClientRect()
var nextBox = {}; var nextBox = {};
nextBox.x = evt.clientX - ((basePixelCount * scaleFactor) / 2) - rect.left + oddOffset; //origin is middle of the frame nextBox.x =
nextBox.y = evt.clientY - ((basePixelCount * scaleFactor) / 2) - rect.top + oddOffset; //TODO make a way to set the origin to numpad dirs? evt.clientX -
(basePixelCount * scaleFactor) / 2 -
rect.left +
oddOffset; //origin is middle of the frame
nextBox.y =
evt.clientY - (basePixelCount * scaleFactor) / 2 - rect.top + oddOffset; //TODO make a way to set the origin to numpad dirs?
nextBox.w = basePixelCount * scaleFactor; nextBox.w = basePixelCount * scaleFactor;
nextBox.h = basePixelCount * scaleFactor; nextBox.h = basePixelCount * scaleFactor;
drawTargets.push(nextBox); drawTargets.push(nextBox);
} }
} else if (evt.button == 2) { } else if (evt.button == 2) {
if (enableErasing && !paintMode) { // right click, also gotta make sure mask blob isn't being used as it's visually inconsistent with behavior of erased region if (enableErasing && !paintMode) {
ctx = imgCanvas.getContext('2d'); // right click, also gotta make sure mask blob isn't being used as it's visually inconsistent with behavior of erased region
ctx = imgCanvas.getContext("2d");
if (snapToGrid) { if (snapToGrid) {
ctx.clearRect(canvasX + snap(canvasX) - ((basePixelCount * scaleFactor) / 2), canvasY + snap(canvasY) - ((basePixelCount * scaleFactor) / 2), basePixelCount * scaleFactor, basePixelCount * scaleFactor); ctx.clearRect(
canvasX + snap(canvasX) - (basePixelCount * scaleFactor) / 2,
canvasY + snap(canvasY) - (basePixelCount * scaleFactor) / 2,
basePixelCount * scaleFactor,
basePixelCount * scaleFactor
);
} else { } else {
ctx.clearRect(canvasX - ((basePixelCount * scaleFactor) / 2), canvasY - ((basePixelCount * scaleFactor) / 2), basePixelCount * scaleFactor, basePixelCount * scaleFactor); ctx.clearRect(
canvasX - (basePixelCount * scaleFactor) / 2,
canvasY - (basePixelCount * scaleFactor) / 2,
basePixelCount * scaleFactor,
basePixelCount * scaleFactor
);
} }
} }
} }
} }
function mouseUp(evt) { function mouseUp(evt) {
if (evt.button == 0) { // left click if (evt.button == 0) {
// left click
if (placingArbitraryImage) { if (placingArbitraryImage) {
// jeez i REALLY need to refactor tons of this to not be duplicated all over, that's definitely my next chore after figuring out that razza frazza overmask fade // jeez i REALLY need to refactor tons of this to not be duplicated all over, that's definitely my next chore after figuring out that razza frazza overmask fade
var target = dropTargets[dropTargets.length - 1]; //get the last one... why am i storing all of them? var target = dropTargets[dropTargets.length - 1]; //get the last one... why am i storing all of them?
@ -537,8 +571,15 @@ function mouseUp(evt) {
// console.log(downX + ":" + downY + " :: " + this.isCanvasBlank(downX, downY)); // console.log(downX + ":" + downY + " :: " + this.isCanvasBlank(downX, downY));
if (!isCanvasBlank(drawIt.x, drawIt.y, drawIt.w, drawIt.h, imgCanvas)) { if (!isCanvasBlank(drawIt.x, drawIt.y, drawIt.w, drawIt.h, imgCanvas)) {
// image exists, set up for img2img // image exists, set up for img2img
var mainCanvasCtx = document.getElementById("canvas").getContext("2d"); var mainCanvasCtx = document
const imgChunk = mainCanvasCtx.getImageData(drawIt.x, drawIt.y, drawIt.w, drawIt.h); // imagedata object of the image being outpainted .getElementById("canvas")
.getContext("2d");
const imgChunk = mainCanvasCtx.getImageData(
drawIt.x,
drawIt.y,
drawIt.w,
drawIt.h
); // imagedata object of the image being outpainted
const imgChunkData = imgChunk.data; // imagedata.data object, a big inconvenient uint8clampedarray const imgChunkData = imgChunk.data; // imagedata.data object, a big inconvenient uint8clampedarray
// these are the 3 mask monitors on the bottom of the page // these are the 3 mask monitors on the bottom of the page
var initImgCanvas = document.getElementById("initImgCanvasMonitor"); var initImgCanvas = document.getElementById("initImgCanvasMonitor");
@ -549,13 +590,17 @@ function mouseUp(evt) {
var overMaskCanvasCtx = overMaskCanvas.getContext("2d"); var overMaskCanvasCtx = overMaskCanvas.getContext("2d");
// get blank pixels to use as mask // get blank pixels to use as mask
const initImgData = mainCanvasCtx.createImageData(drawIt.w, drawIt.h); const initImgData = mainCanvasCtx.createImageData(drawIt.w, drawIt.h);
let overMaskImgData = overMaskCanvasCtx.createImageData(drawIt.w, drawIt.h); let overMaskImgData = overMaskCanvasCtx.createImageData(
drawIt.w,
drawIt.h
);
// cover entire masks in black before adding masked areas // cover entire masks in black before adding masked areas
for (let i = 0; i < imgChunkData.length; i += 4) { for (let i = 0; i < imgChunkData.length; i += 4) {
// l->r, top->bottom, R G B A pixel values in a big ol array // l->r, top->bottom, R G B A pixel values in a big ol array
// make a simple mask // make a simple mask
if (imgChunkData[i + 3] == 0) { // rgba pixel values, 4th one is alpha, if it's 0 there's "nothing there" in the image display canvas and its time to outpaint if (imgChunkData[i + 3] == 0) {
// rgba pixel values, 4th one is alpha, if it's 0 there's "nothing there" in the image display canvas and its time to outpaint
overMaskImgData.data[i] = 255; // white mask gets painted over overMaskImgData.data[i] = 255; // white mask gets painted over
overMaskImgData.data[i + 1] = 255; overMaskImgData.data[i + 1] = 255;
overMaskImgData.data[i + 2] = 255; overMaskImgData.data[i + 2] = 255;
@ -565,7 +610,8 @@ function mouseUp(evt) {
initImgData.data[i + 1] = 0; initImgData.data[i + 1] = 0;
initImgData.data[i + 2] = 0; initImgData.data[i + 2] = 0;
initImgData.data[i + 3] = 255; initImgData.data[i + 3] = 255;
} else { // leave these pixels alone } else {
// leave these pixels alone
overMaskImgData.data[i] = 0; // black mask gets ignored for in/outpainting overMaskImgData.data[i] = 0; // black mask gets ignored for in/outpainting
overMaskImgData.data[i + 1] = 0; overMaskImgData.data[i + 1] = 0;
overMaskImgData.data[i + 2] = 0; overMaskImgData.data[i + 2] = 0;
@ -578,11 +624,11 @@ function mouseUp(evt) {
} }
} }
// make a list of all the white pixels to expand so we don't waste time on non-mask pixels // make a list of all the white pixels to expand so we don't waste time on non-mask pixels
let pix = { x: [], y: [], index: [] }; let pix = {x: [], y: [], index: []};
var x, y, index; var x, y, index;
for (y = 0; y < drawIt.h; y++) { for (y = 0; y < drawIt.h; y++) {
for (x = 0; x < drawIt.w; x++) { for (x = 0; x < drawIt.w; x++) {
index = ((y * drawIt.w + x) * 4); index = (y * drawIt.w + x) * 4;
if (overMaskImgData.data[index] > 0) { if (overMaskImgData.data[index] > 0) {
pix.x.push(x); pix.x.push(x);
pix.y.push(y); pix.y.push(y);
@ -595,19 +641,37 @@ function mouseUp(evt) {
overMaskCanvasCtx.fillStyle = "black"; overMaskCanvasCtx.fillStyle = "black";
overMaskCanvasCtx.fillRect(0, 0, drawIt.w, drawIt.h); // fill with black instead of null to start overMaskCanvasCtx.fillRect(0, 0, drawIt.w, drawIt.h); // fill with black instead of null to start
for (i = 0; i < overMaskImgData.data.length; i += 4) { for (i = 0; i < overMaskImgData.data.length; i += 4) {
if (overMaskImgData.data[i] == 255) { // white pixel? if (overMaskImgData.data[i] == 255) {
// white pixel?
// just blotch all over the thing // just blotch all over the thing
var rando = Math.floor(Math.random() * overMaskPx); var rando = Math.floor(Math.random() * overMaskPx);
overMaskCanvasCtx.beginPath(); overMaskCanvasCtx.beginPath();
overMaskCanvasCtx.arc(((i / 4) % overMaskCanvas.width), (Math.floor((i / 4) / overMaskCanvas.width)), (4 * scaleFactor) + rando, 0, 2 * Math.PI, true); overMaskCanvasCtx.arc(
(i / 4) % overMaskCanvas.width,
Math.floor(i / 4 / overMaskCanvas.width),
4 * scaleFactor + rando,
0,
2 * Math.PI,
true
);
overMaskCanvasCtx.fillStyle = "#FFFFFFFF"; overMaskCanvasCtx.fillStyle = "#FFFFFFFF";
overMaskCanvasCtx.fill(); overMaskCanvasCtx.fill();
} }
} }
overMaskImgData = overMaskCanvasCtx.getImageData(0, 0, overMaskCanvas.width, overMaskCanvas.height); overMaskImgData = overMaskCanvasCtx.getImageData(
0,
0,
overMaskCanvas.width,
overMaskCanvas.height
);
overMaskCanvasCtx.putImageData(overMaskImgData, 0, 0); overMaskCanvasCtx.putImageData(overMaskImgData, 0, 0);
// also check for painted masks in region, add them as white pixels to mask canvas // also check for painted masks in region, add them as white pixels to mask canvas
const maskChunk = maskPaintCtx.getImageData(drawIt.x, drawIt.y, drawIt.w, drawIt.h); const maskChunk = maskPaintCtx.getImageData(
drawIt.x,
drawIt.y,
drawIt.w,
drawIt.h
);
const maskChunkData = maskChunk.data; const maskChunkData = maskChunk.data;
for (let i = 0; i < maskChunkData.length; i += 4) { for (let i = 0; i < maskChunkData.length; i += 4) {
if (maskChunkData[i + 3] != 0) { if (maskChunkData[i + 3] != 0) {
@ -644,19 +708,32 @@ function mouseUp(evt) {
// easy enough // easy enough
} }
stableDiffusionData.prompt = document.getElementById("prompt").value; stableDiffusionData.prompt = document.getElementById("prompt").value;
stableDiffusionData.negative_prompt = document.getElementById("negPrompt").value; stableDiffusionData.negative_prompt =
document.getElementById("negPrompt").value;
stableDiffusionData.width = drawIt.w; stableDiffusionData.width = drawIt.w;
stableDiffusionData.height = drawIt.h; stableDiffusionData.height = drawIt.h;
stableDiffusionData.firstphase_height = (drawIt.h / 2); stableDiffusionData.firstphase_height = drawIt.h / 2;
stableDiffusionData.firstphase_width = (drawIt.w / 2); stableDiffusionData.firstphase_width = drawIt.w / 2;
dream(drawIt.x, drawIt.y, stableDiffusionData); dream(drawIt.x, drawIt.y, stableDiffusionData);
} }
} }
} }
} }
const changeScaleFactor = sliderChangeHandlerFactory("scaleFactor", "scaleFactorTxt", "scaleFactor", 8, (k, v) => scaleFactor = v, (k) => scaleFactor); const changeScaleFactor = sliderChangeHandlerFactory(
const changeSteps = sliderChangeHandlerFactory("steps", "stepsTxt", "steps", 30); "scaleFactor",
"scaleFactorTxt",
"scaleFactor",
8,
(k, v) => (scaleFactor = v),
(k) => scaleFactor
);
const changeSteps = sliderChangeHandlerFactory(
"steps",
"stepsTxt",
"steps",
30
);
function changePaintMode() { function changePaintMode() {
paintMode = document.getElementById("cbxPaint").checked; paintMode = document.getElementById("cbxPaint").checked;
@ -671,13 +748,29 @@ function changeEnableErasing() {
} }
function changeSampler() { function changeSampler() {
stableDiffusionData.sampler_index = document.getElementById("samplerSelect").value; stableDiffusionData.sampler_index =
document.getElementById("samplerSelect").value;
localStorage.setItem("sampler", stableDiffusionData.sampler_index); localStorage.setItem("sampler", stableDiffusionData.sampler_index);
} }
const changeCfgScale = sliderChangeHandlerFactory("cfgScale", "cfgScaleTxt", "cfg_scale", 7.0); const changeCfgScale = sliderChangeHandlerFactory(
const changeBatchSize = sliderChangeHandlerFactory("batchSize", "batchSizeText", "batch_size", 2); "cfgScale",
const changeBatchCount = sliderChangeHandlerFactory("batchCount", "batchCountText", "n_iter", 2); "cfgScaleTxt",
"cfg_scale",
7.0
);
const changeBatchSize = sliderChangeHandlerFactory(
"batchSize",
"batchSizeText",
"batch_size",
2
);
const changeBatchCount = sliderChangeHandlerFactory(
"batchCount",
"batchCountText",
"n_iter",
2
);
function changeSnapMode() { function changeSnapMode() {
snapToGrid = document.getElementById("cbxSnap").checked; snapToGrid = document.getElementById("cbxSnap").checked;
@ -699,20 +792,23 @@ function changeOverMaskPx() {
} }
function changeHiResFix() { function changeHiResFix() {
stableDiffusionData.enable_hr = Boolean(document.getElementById("cbxHRFix").checked); stableDiffusionData.enable_hr = Boolean(
document.getElementById("cbxHRFix").checked
);
localStorage.setItem("enable_hr", stableDiffusionData.enable_hr); localStorage.setItem("enable_hr", stableDiffusionData.enable_hr);
} }
function isCanvasBlank(x, y, w, h, specifiedCanvas) { function isCanvasBlank(x, y, w, h, specifiedCanvas) {
var canvas = document.getElementById(specifiedCanvas.id); var canvas = document.getElementById(specifiedCanvas.id);
return !canvas.getContext('2d') return !canvas
.getImageData(x, y, w, h).data .getContext("2d")
.some(channel => channel !== 0); .getImageData(x, y, w, h)
.data.some((channel) => channel !== 0);
} }
function drawBackground() { function drawBackground() {
bgCtx.lineWidth = 1; bgCtx.lineWidth = 1;
bgCtx.strokeStyle = '#999'; bgCtx.strokeStyle = "#999";
var gridbox = bgCanvas.getBoundingClientRect(); var gridbox = bgCanvas.getBoundingClientRect();
for (var i = 0; i < gridbox.width; i += 64) { for (var i = 0; i < gridbox.width; i += 64) {
bgCtx.moveTo(i, 0); bgCtx.moveTo(i, 0);
@ -744,25 +840,32 @@ function preloadImage() {
imgCanvas.width = arbitraryImage.width; imgCanvas.width = arbitraryImage.width;
imgCanvas.height = arbitraryImage.height; imgCanvas.height = arbitraryImage.height;
imgCtx.drawImage(arbitraryImage, 0, 0); imgCtx.drawImage(arbitraryImage, 0, 0);
arbitraryImageData = imgCtx.getImageData(0, 0, arbitraryImage.width, arbitraryImage.height); // can't use that to drawImage on a canvas... arbitraryImageData = imgCtx.getImageData(
0,
0,
arbitraryImage.width,
arbitraryImage.height
); // can't use that to drawImage on a canvas...
arbitraryImageBitmap = createImageBitmap(arbitraryImageData); // apparently that either... maybe just the raw image? arbitraryImageBitmap = createImageBitmap(arbitraryImageData); // apparently that either... maybe just the raw image?
arbitraryImageBase64 = imgCanvas.toDataURL(); arbitraryImageBase64 = imgCanvas.toDataURL();
placingArbitraryImage = true; placingArbitraryImage = true;
document.getElementById("overlayCanvas").onmousemove = mouseMove; document.getElementById("overlayCanvas").onmousemove = mouseMove;
document.getElementById("overlayCanvas").onmousedown = mouseDown; document.getElementById("overlayCanvas").onmousedown = mouseDown;
document.getElementById("overlayCanvas").onmouseup = mouseUp; document.getElementById("overlayCanvas").onmouseup = mouseUp;
} };
arbitraryImage.src = evt.target.result; arbitraryImage.src = evt.target.result;
} };
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
function downloadCanvas() { function downloadCanvas() {
var link = document.createElement('a'); var link = document.createElement("a");
link.download = new Date().toISOString().slice(0, 19).replace('T', ' ').replace(':', ' ') + ' openOutpaint image.png'; link.download =
new Date().toISOString().slice(0, 19).replace("T", " ").replace(":", " ") +
" openOutpaint image.png";
var croppedCanvas = cropCanvas(imgCanvas); var croppedCanvas = cropCanvas(imgCanvas);
if (croppedCanvas != null) { if (croppedCanvas != null) {
link.href = croppedCanvas.toDataURL('image/png'); link.href = croppedCanvas.toDataURL("image/png");
link.click(); link.click();
} }
} }
@ -770,8 +873,8 @@ function downloadCanvas() {
function cropCanvas(sourceCanvas) { function cropCanvas(sourceCanvas) {
var w = sourceCanvas.width; var w = sourceCanvas.width;
var h = sourceCanvas.height; var h = sourceCanvas.height;
var pix = { x: [], y: [] }; var pix = {x: [], y: []};
var imageData = sourceCanvas.getContext('2d').getImageData(0, 0, w, h); var imageData = sourceCanvas.getContext("2d").getImageData(0, 0, w, h);
var x, y, index; var x, y, index;
for (y = 0; y < h; y++) { for (y = 0; y < h; y++) {
@ -787,19 +890,25 @@ function cropCanvas(sourceCanvas) {
} }
// ...need to learn what this part does too :badpokerface: // ...need to learn what this part does too :badpokerface:
// is this just determining the boundaries of non-transparent pixel data? // is this just determining the boundaries of non-transparent pixel data?
pix.x.sort(function (a, b) { return a - b }); pix.x.sort(function (a, b) {
pix.y.sort(function (a, b) { return a - b }); return a - b;
});
pix.y.sort(function (a, b) {
return a - b;
});
var n = pix.x.length - 1; var n = pix.x.length - 1;
w = pix.x[n] - pix.x[0]; w = pix.x[n] - pix.x[0];
h = pix.y[n] - pix.y[0]; h = pix.y[n] - pix.y[0];
// yup sure looks like it // yup sure looks like it
try { try {
var cut = sourceCanvas.getContext('2d').getImageData(pix.x[0], pix.y[0], w, h); var cut = sourceCanvas
var cutCanvas = document.createElement('canvas'); .getContext("2d")
.getImageData(pix.x[0], pix.y[0], w, h);
var cutCanvas = document.createElement("canvas");
cutCanvas.width = w; cutCanvas.width = w;
cutCanvas.height = h; cutCanvas.height = h;
cutCanvas.getContext('2d').putImageData(cut, 0, 0); cutCanvas.getContext("2d").putImageData(cut, 0, 0);
} catch (ex) { } catch (ex) {
// probably empty image // probably empty image
//TODO confirm edge cases? //TODO confirm edge cases?
@ -809,24 +918,47 @@ function cropCanvas(sourceCanvas) {
} }
function checkIfWebuiIsRunning() { function checkIfWebuiIsRunning() {
var url = document.getElementById("host").value + "/startup-events" var url = document.getElementById("host").value + "/startup-events";
fetch(url).then(response => { fetch(url)
.then((response) => {
if (response.status == 200) { if (response.status == 200) {
console.log("webui is running"); console.log("webui is running");
} }
}).catch(error => { })
alert("WebUI doesnt seem to be running, please start it and try again\nCheck console for additional info\n" + error); .catch((error) => {
alert(
"WebUI doesnt seem to be running, please start it and try again\nCheck console for additional info\n" +
error
);
}); });
} }
function loadSettings() { function loadSettings() {
// set default values if not set // set default values if not set
var _sampler = localStorage.getItem("sampler") == null ? "DDIM" : localStorage.getItem("sampler"); var _sampler =
var _mask_blur = localStorage.getItem("mask_blur") == null ? 0 : localStorage.getItem("mask_blur"); localStorage.getItem("sampler") == null
var _seed = localStorage.getItem("seed") == null ? -1 : localStorage.getItem("seed"); ? "DDIM"
var _enable_hr = Boolean(localStorage.getItem("enable_hr") == (null || "false") ? false : localStorage.getItem("enable_hr")); : localStorage.getItem("sampler");
var _enable_erase = Boolean(localStorage.getItem("enable_erase") == (null || "false") ? false : localStorage.getItem("enable_erase")); var _mask_blur =
var _overmask_px = localStorage.getItem("overmask_px") == null ? 0 : localStorage.getItem("overmask_px"); localStorage.getItem("mask_blur") == null
? 0
: localStorage.getItem("mask_blur");
var _seed =
localStorage.getItem("seed") == null ? -1 : localStorage.getItem("seed");
var _enable_hr = Boolean(
localStorage.getItem("enable_hr") == (null || "false")
? false
: localStorage.getItem("enable_hr")
);
var _enable_erase = Boolean(
localStorage.getItem("enable_erase") == (null || "false")
? false
: localStorage.getItem("enable_erase")
);
var _overmask_px =
localStorage.getItem("overmask_px") == null
? 0
: localStorage.getItem("overmask_px");
// set the values into the UI // set the values into the UI
document.getElementById("samplerSelect").value = String(_sampler); document.getElementById("samplerSelect").value = String(_sampler);

View file

@ -5,7 +5,7 @@ function dragElement(elmnt) {
p2 = 0, p2 = 0,
p3 = 0, p3 = 0,
p4 = 0; p4 = 0;
var draggableElements = document.getElementsByClassName('draggable'); var draggableElements = document.getElementsByClassName("draggable");
for (var i = 0; i < draggableElements.length; i++) { for (var i = 0; i < draggableElements.length; i++) {
draggableElements[i].onmousedown = dragMouseDown; draggableElements[i].onmousedown = dragMouseDown;
} }
@ -22,8 +22,8 @@ function dragElement(elmnt) {
e.preventDefault(); e.preventDefault();
p1 = p3 - e.clientX; p1 = p3 - e.clientX;
p2 = p4 - e.clientY; p2 = p4 - e.clientY;
elmnt.style.top = (elmnt.offsetTop - (p4-e.clientY)) + "px"; elmnt.style.top = elmnt.offsetTop - (p4 - e.clientY) + "px";
elmnt.style.left = (elmnt.offsetLeft - (p3-e.clientX)) + "px"; elmnt.style.left = elmnt.offsetLeft - (p3 - e.clientX) + "px";
p3 = e.clientX; p3 = e.clientX;
p4 = e.clientY; p4 = e.clientY;
} }