aboutsummaryrefslogtreecommitdiffstats
path: root/javascript/aspectRatioSliders.js
diff options
context:
space:
mode:
authorGerschel <Gerschel_Payne@hotmail.com>2023-02-09 02:57:32 +0000
committerGerschel <Gerschel_Payne@hotmail.com>2023-02-09 02:57:32 +0000
commit374fe636b80169c78b4b5f92013681d75fa2fad6 (patch)
tree31ec58ffee3ac8f18f2cbadccb1fb918a3743372 /javascript/aspectRatioSliders.js
parent5d483bf307c766aee97caec857d414946fad47db (diff)
downloadstable-diffusion-webui-gfx803-374fe636b80169c78b4b5f92013681d75fa2fad6.tar.gz
stable-diffusion-webui-gfx803-374fe636b80169c78b4b5f92013681d75fa2fad6.tar.bz2
stable-diffusion-webui-gfx803-374fe636b80169c78b4b5f92013681d75fa2fad6.zip
Squashed commit of the following:
commit b030b67ad005bfe29bcda692238a00042dcae816 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Wed Feb 8 16:38:56 2023 -0800 styling adjustements commit 80a2acb0230dd77489b0eb466f2efe827a053f6d Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Wed Feb 8 10:49:47 2023 -0800 badge indicator toggles visibility by selection commit 898922e025a6422ac947fb45c1fa4f1109882f0a Merge: 745382a0 31bbfa72 Author: Gerschel <9631031+Gerschel@users.noreply.github.com> Date: Wed Feb 8 08:35:26 2023 -0800 Merge pull request #1 from w-e-w/Rounding-Method Rounding Method commit 31bbfa729a15ef35fa1f905345d3ba2b17b26ab9 Author: w-e-w <40751091+w-e-w@users.noreply.github.com> Date: Wed Feb 8 19:41:45 2023 +0900 use switch commit 85dbe511c33521d3ac62224bf0e0f3a48194ce63 Author: w-e-w <40751091+w-e-w@users.noreply.github.com> Date: Wed Feb 8 16:47:52 2023 +0900 Rounding Method commit 745382a0f4b8d16241545a3460d5206915959255 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Tue Feb 7 21:19:20 2023 -0800 default set to round commit 728579c618af30ec98a5af0991bd3f28bdaca399 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Tue Feb 7 21:17:03 2023 -0800 cleaned some commented code out; added indicator commit 5b288c24a1edd8a5c2f35214b9634316d05b8dae Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Tue Feb 7 18:19:00 2023 -0800 needs cleaning; attempt at rounding commit d9f18ae92b929576b0b8c5f1ef8b3b38e441e381 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Tue Feb 7 15:46:25 2023 -0800 add rounding option in setting for aspect ratio commit af22106802c9e42205649e4c71c23fcf5b8c62f6 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Tue Feb 7 13:18:45 2023 -0800 added some ratios, sorted ratios by commonality commit 11e2fba73cffe8cdbf4cd0860641b94428ca0e74 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Tue Feb 7 10:46:53 2023 -0800 snaps to mulitples of 8 and along ratio commit fa00387e07460b10ee82671a1bfa8687e00ee60b Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 14:54:59 2023 -0800 updated slidercomponentcontroller commit 8059bc111c3e2d1edb3314e05ab21b65120fa1dd Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 14:29:11 2023 -0800 added step size adjustment on number field commit 641157b9f27a874a24ee7b0a854a092e9eac3eec Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 14:12:03 2023 -0800 added return step size to default when ratio is disabled commit 5fb75ad28f2476f36100ec93922a8199adbd2a68 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 14:09:34 2023 -0800 added step size adjustment commit e33532883bc4709cd41c3775cbb646d1d5ab0584 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 11:56:15 2023 -0800 adjusted dropdown size, padding, text-align commit 81937329cee77f466c5a5b23c268d0c810128f84 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 11:39:57 2023 -0800 added positioning and styling commit 86eb4583782d92880a9a113a54ffbac9d92f3753 Author: Gerschel <Gerschel_Payne@hotmail.com> Date: Mon Feb 6 08:54:45 2023 -0800 fix typo in defaults; added preventDefault in event
Diffstat (limited to 'javascript/aspectRatioSliders.js')
-rw-r--r--javascript/aspectRatioSliders.js164
1 files changed, 152 insertions, 12 deletions
diff --git a/javascript/aspectRatioSliders.js b/javascript/aspectRatioSliders.js
index f577750a..d9c4f675 100644
--- a/javascript/aspectRatioSliders.js
+++ b/javascript/aspectRatioSliders.js
@@ -1,14 +1,61 @@
class AspectRatioSliderController {
- constructor(widthSlider, heightSlider, ratioSource) {
+ constructor(widthSlider, heightSlider, ratioSource, roundingSource, roundingMethod) {
+ //References
this.widthSlider = new SliderComponentController(widthSlider);
this.heightSlider = new SliderComponentController(heightSlider);
this.ratioSource = new DropdownComponentController(ratioSource);
- this.widthSlider.childRangeField.addEventListener("change", () => this.resize("width"));
- this.widthSlider.childNumField.addEventListener("change", () => this.resize("width"));
- this.heightSlider.childRangeField.addEventListener("change", () => this.resize("height"));
- this.heightSlider.childNumField.addEventListener("change", () => this.resize("height"));
+ this.roundingSource = new CheckboxComponentController(roundingSource);
+ this.roundingMethod = new RadioComponentController(roundingMethod);
+ this.roundingIndicatorBadge = document.createElement("div");
+ // Badge implementation
+ this.roundingIndicatorBadge.innerText = "📐";
+ this.roundingIndicatorBadge.classList.add("rounding-badge");
+ this.ratioSource.element.appendChild(this.roundingIndicatorBadge);
+ // Check initial value of ratioSource to set badge visbility
+ let initialRatio = this.ratioSource.getVal();
+ if (!initialRatio.includes(":")) {
+ this.roundingIndicatorBadge.style.display = "none";
+ }
+ //Adjust badge icon if rounding is on
+ if (this.roundingSource.getVal()) {
+ this.roundingIndicatorBadge.classList.add("active");
+ this.roundingIndicatorBadge.innerText = "⚠️";
+ }
+ //Make badge clickable to toggle setting
+ this.roundingIndicatorBadge.addEventListener("click", () => {
+ this.roundingSource.setVal(!this.roundingSource.getVal());
+ });
+ //Make rounding setting toggle badge text and style if setting changes
+ this.roundingSource.child.addEventListener("change", () => {
+ if (this.roundingSource.getVal()) {
+ this.roundingIndicatorBadge.classList.add("active");
+ this.roundingIndicatorBadge.innerText = "⚠️";
+ }
+ else {
+ this.roundingIndicatorBadge.classList.remove("active");
+ this.roundingIndicatorBadge.innerText = "📐";
+ }
+ this.adjustStepSize();
+ });
+ //Other event listeners
+ this.widthSlider.childRangeField.addEventListener("change", (e) => { e.preventDefault(); this.resize("width"); });
+ this.widthSlider.childNumField.addEventListener("change", (e) => { e.preventDefault(); this.resize("width"); });
+ this.heightSlider.childRangeField.addEventListener("change", (e) => { e.preventDefault(); this.resize("height"); });
+ this.heightSlider.childNumField.addEventListener("change", (e) => { e.preventDefault(); this.resize("height"); });
+ this.ratioSource.childSelector.addEventListener("change", (e) => {
+ e.preventDefault();
+ //Check and toggle display of badge conditionally on dropdown selection
+ if (!this.ratioSource.getVal().includes(":")) {
+ this.roundingIndicatorBadge.style.display = 'none';
+ }
+ else {
+ this.roundingIndicatorBadge.style.display = 'block';
+ }
+ this.adjustStepSize();
+ });
}
resize(dimension) {
+ //For moving slider or number field
let val = this.ratioSource.getVal();
if (!val.includes(":")) {
return;
@@ -16,26 +63,119 @@ class AspectRatioSliderController {
let [width, height] = val.split(":").map(Number);
let ratio = width / height;
if (dimension == 'width') {
- this.heightSlider.setVal(Math.round(parseFloat(this.widthSlider.getVal()) / ratio).toString());
+ let newHeight = parseInt(this.widthSlider.getVal()) / ratio;
+ if (this.roundingSource.getVal()) {
+ switch (this.roundingMethod.getVal()) {
+ case 'Round':
+ newHeight = Math.round(newHeight / 8) * 8;
+ break;
+ case 'Ceiling':
+ newHeight = Math.ceil(newHeight / 8) * 8;
+ break;
+ case 'Floor':
+ newHeight = Math.floor(newHeight / 8) * 8;
+ break;
+ }
+ }
+ this.heightSlider.setVal(newHeight.toString());
}
else if (dimension == "height") {
- this.widthSlider.setVal(Math.round(parseFloat(this.heightSlider.getVal()) * ratio).toString());
+ let newWidth = parseInt(this.heightSlider.getVal()) * ratio;
+ if (this.roundingSource.getVal()) {
+ switch (this.roundingMethod.getVal()) {
+ case 'Round':
+ newWidth = Math.round(newWidth / 8) * 8;
+ break;
+ case 'Ceiling':
+ newWidth = Math.ceil(newWidth / 8) * 8;
+ break;
+ case 'Floor':
+ newWidth = Math.floor(newWidth / 8) * 8;
+ break;
+ }
+ }
+ this.widthSlider.setVal(newWidth.toString());
+ }
+ }
+ adjustStepSize() {
+ /* Sets scales/precision/rounding steps;*/
+ let val = this.ratioSource.getVal();
+ if (!val.includes(":")) {
+ //If ratio unlocked
+ this.widthSlider.childRangeField.step = "8";
+ this.widthSlider.childRangeField.min = "64";
+ this.widthSlider.childNumField.step = "8";
+ this.widthSlider.childNumField.min = "64";
+ this.heightSlider.childRangeField.step = "8";
+ this.heightSlider.childRangeField.min = "64";
+ this.heightSlider.childNumField.step = "8";
+ this.heightSlider.childNumField.min = "64";
+ return;
+ }
+ //Format string and calculate step sizes
+ let [width, height] = val.split(":").map(Number);
+ let decimalPlaces = (width.toString().split(".")[1] || []).length;
+ //keep upto 6 decimal points of precision of ratio
+ //euclidean gcd does not support floats, so we scale it up
+ decimalPlaces = decimalPlaces > 6 ? 6 : decimalPlaces;
+ let gcd = this.gcd(width * 10 ** decimalPlaces, height * 10 ** decimalPlaces) / 10 ** decimalPlaces;
+ let stepSize = 8 * height / gcd;
+ let stepSizeOther = 8 * width / gcd;
+ if (this.roundingSource.getVal()) {
+ //If rounding is on set/keep default stepsizes
+ this.widthSlider.childRangeField.step = "8";
+ this.widthSlider.childRangeField.min = "64";
+ this.widthSlider.childNumField.step = "8";
+ this.widthSlider.childNumField.min = "64";
+ this.heightSlider.childRangeField.step = "8";
+ this.heightSlider.childRangeField.min = "64";
+ this.heightSlider.childNumField.step = "8";
+ this.heightSlider.childNumField.min = "64";
+ }
+ else {
+ //if rounding is off, set step sizes so they enforce snapping
+ //min is changed, because it offsets snap positions
+ this.widthSlider.childRangeField.step = stepSizeOther.toString();
+ this.widthSlider.childRangeField.min = stepSizeOther.toString();
+ this.widthSlider.childNumField.step = stepSizeOther.toString();
+ this.widthSlider.childNumField.min = stepSizeOther.toString();
+ this.heightSlider.childRangeField.step = stepSize.toString();
+ this.heightSlider.childRangeField.min = stepSize.toString();
+ this.heightSlider.childNumField.step = stepSize.toString();
+ this.heightSlider.childNumField.min = stepSize.toString();
+ }
+ let currentWidth = parseInt(this.widthSlider.getVal());
+ //Rounding treated kinda like pythons divmod
+ let stepsTaken = Math.round(currentWidth / stepSizeOther);
+ //this snaps it to closest rule matches (rules being html step points, and ratio)
+ let newWidth = stepsTaken * stepSizeOther;
+ this.widthSlider.setVal(newWidth.toString());
+ this.heightSlider.setVal(Math.round(newWidth / (width / height)).toString());
+ }
+ gcd(a, b) {
+ //euclidean gcd
+ if (b === 0) {
+ return a;
}
+ return this.gcd(b, a % b);
}
- static observeStartup(widthSliderId, heightSliderId, ratioSourceId) {
+ static observeStartup(widthSliderId, heightSliderId, ratioSourceId, roundingSourceId, roundingMethodId) {
let observer = new MutationObserver(() => {
let widthSlider = document.querySelector("gradio-app").shadowRoot.getElementById(widthSliderId);
let heightSlider = document.querySelector("gradio-app").shadowRoot.getElementById(heightSliderId);
let ratioSource = document.querySelector("gradio-app").shadowRoot.getElementById(ratioSourceId);
- if (widthSlider && heightSlider && ratioSource) {
+ let roundingSource = document.querySelector("gradio-app").shadowRoot.getElementById(roundingSourceId);
+ let roundingMethod = document.querySelector("gradio-app").shadowRoot.getElementById(roundingMethodId);
+ if (widthSlider && heightSlider && ratioSource && roundingSource && roundingMethod) {
observer.disconnect();
- new AspectRatioSliderController(widthSlider, heightSlider, ratioSource);
+ new AspectRatioSliderController(widthSlider, heightSlider, ratioSource, roundingSource, roundingMethod);
}
});
observer.observe(gradioApp(), { childList: true, subtree: true });
}
}
document.addEventListener("DOMContentLoaded", () => {
- AspectRatioSliderController.observeStartup("txt2img_width", "txt2img_height", "txt2img_ratio");
- AspectRatioSliderController.observeStartup("img2img_width", "img2img_height", "img2img_ratio");
+ //Register mutation observer for self start-up;
+ AspectRatioSliderController.observeStartup("txt2img_width", "txt2img_height", "txt2img_ratio", "setting_aspect_ratios_rounding", "setting_aspect_ratios_rounding_method");
+ AspectRatioSliderController.observeStartup("img2img_width", "img2img_height", "img2img_ratio", "setting_aspect_ratios_rounding", "setting_aspect_ratios_rounding_method");
});