forked from extern/easydiffusion
commit
a72bae9cd2
@ -63,9 +63,39 @@
|
||||
<a href="https://github.com/cmdr2/stable-diffusion-ui/wiki/Writing-prompts#negative-prompts" target="_blank"><i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip top">Click to learn more about Negative Prompts</span></i></a>
|
||||
<small>(optional)</small>
|
||||
</label>
|
||||
<label for="image-modifiers" data-active="false" id="image-modifier-dropdown">
|
||||
Image Modifiers
|
||||
<small>(optional)</small>
|
||||
</label>
|
||||
<div class="collapsible-content">
|
||||
<textarea id="negative_prompt" name="negative_prompt" placeholder="list the things to remove from the image (e.g. fog, green)"></textarea>
|
||||
</div>
|
||||
<div id="editor-modifiers">
|
||||
<div id="editor-modifiers-header">
|
||||
<div id="modifiers-header-left">
|
||||
<h4>Image Modifiers</h4>
|
||||
<span>(drawing style, camera, etc.)</span>
|
||||
</div>
|
||||
<div id="modifiers-header-right">
|
||||
<i id="modifier-settings-btn" class="fa-solid fa-gear section-button">
|
||||
<span class="simple-tooltip left">
|
||||
Add Custom Modifiers
|
||||
</span>
|
||||
</i>
|
||||
<i id="modifiers-container-size-btn" class="fa-solid fa-expand"></i>
|
||||
<i id="modifiers-close-button" class="fa-solid fa-xmark fa-lg"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div id="editor-modifiers-subheader">
|
||||
<div id="modifiers-action-collapsibles-btn">
|
||||
<i class="modifiers-action-icon fa-solid fa-square-plus"></i>
|
||||
<span class="modifiers-action-text">
|
||||
Expand Categories
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="editor-modifiers-entries" class="collapsible-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="editor-inputs-init-image" class="row">
|
||||
@ -102,7 +132,7 @@
|
||||
</div>
|
||||
|
||||
<div id="editor-inputs-tags-container" class="row">
|
||||
<label>Image Modifiers <i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip right">click an Image Modifier to remove it, right-click to temporarily disable it, use Ctrl+Mouse Wheel to adjust its weight</span></i></label>
|
||||
<label>Image Modifiers <i class="fa-solid fa-circle-question help-btn"><span class="simple-tooltip right">Click an Image Modifier to remove it, right-click to temporarily disable it, use Ctrl+Mouse Wheel to adjust its weight</span></i></label>
|
||||
<div id="editor-inputs-tags-list"></div>
|
||||
</div>
|
||||
|
||||
@ -293,29 +323,6 @@
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="editor-modifiers" class="panel-box">
|
||||
<h4 class="collapsible">
|
||||
Image Modifiers (art styles, tags etc)
|
||||
<i id="modifier-settings-btn" class="fa-solid fa-gear section-button">
|
||||
<span class="simple-tooltip left">
|
||||
Add Custom Modifiers
|
||||
</span>
|
||||
</i>
|
||||
</h4>
|
||||
<div id="editor-modifiers-entries" class="collapsible-content">
|
||||
<div id="editor-modifiers-entries-toolbar">
|
||||
<label for="preview-image">Image Style:</label>
|
||||
<select id="preview-image" name="preview-image" value="portrait">
|
||||
<option value="portrait" selected="">Face</option>
|
||||
<option value="landscape">Landscape</option>
|
||||
</select>
|
||||
|
||||
<label for="modifier-card-size-slider">Thumbnail Size:</label>
|
||||
<input id="modifier-card-size-slider" name="modifier-card-size-slider" value="0" type="range" min="-3" max="5">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="preview" class="col-free">
|
||||
@ -522,6 +529,16 @@
|
||||
<p>Set your custom modifiers (one per line)</p>
|
||||
<textarea id="custom-modifiers-input" placeholder="Enter your custom modifiers, one-per-line" spellcheck="false"></textarea>
|
||||
<p><small><b>Tip:</b> You can include special characters like {} () [] and |. You can also put multiple comma-separated phrases in a single line, to make a single modifier that combines all of those.</small></p>
|
||||
<div id="editor-modifiers-entries-toolbar">
|
||||
<label for="preview-image">Image Style:</label>
|
||||
<select id="preview-image" name="preview-image" value="portrait">
|
||||
<option value="portrait" selected="">Face</option>
|
||||
<option value="landscape">Landscape</option>
|
||||
</select>
|
||||
|
||||
<label for="modifier-card-size-slider">Thumbnail Size:</label>
|
||||
<input id="modifier-card-size-slider" name="modifier-card-size-slider" value="0" type="range" min="-2" max="3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -211,10 +211,6 @@ code {
|
||||
#makeImage {
|
||||
border-radius: 6px;
|
||||
}
|
||||
#editor-modifiers h5 {
|
||||
padding: 5pt 0;
|
||||
margin: 0;
|
||||
}
|
||||
#makeImage {
|
||||
flex: 0 0 70px;
|
||||
background: var(--accent-color);
|
||||
@ -284,14 +280,193 @@ button#resume {
|
||||
.collapsible:not(.active) ~ .collapsible-content {
|
||||
display: none !important;
|
||||
}
|
||||
#image-modifier-dropdown {
|
||||
margin-left: 1em;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
#image-modifier-dropdown[data-active="true"]::before {
|
||||
content: "➖";
|
||||
}
|
||||
#image-modifier-dropdown[data-active="false"]::before {
|
||||
content: "➕";
|
||||
}
|
||||
#editor-modifiers {
|
||||
overflow-y: auto;
|
||||
max-width: 75vw;
|
||||
min-width: 50vw;
|
||||
max-height: fit-content;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
display: none;
|
||||
background: var(--background-color1);
|
||||
border: solid 1px var(--background-color3);
|
||||
z-index: 999;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0px 0px 30px black;
|
||||
border: 2px solid rgb(255 255 255 / 10%);
|
||||
}
|
||||
#editor-modifiers.active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
left: 5vw;
|
||||
}
|
||||
.modifiers-maximized {
|
||||
position: fixed !important;
|
||||
top: 0 !important;
|
||||
bottom: 0px !important;
|
||||
left: 0px !important;
|
||||
right: 0px !important;
|
||||
max-width: unset !important;
|
||||
max-height: unset !important;
|
||||
border: 0px !important;
|
||||
border-radius: 0px !important;
|
||||
}
|
||||
.modifiers-maximized #editor-modifiers-entries {
|
||||
max-height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
#editor-modifiers-header {
|
||||
background-color: var(--background-color4);
|
||||
padding: 0.5em;
|
||||
border-bottom: 1px solid rgb(255 255 255 / 10%);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
#editor-modifiers-subheader {
|
||||
background-color: var(--background-color4);
|
||||
padding: 0.5em;
|
||||
border-bottom: 1px solid rgb(255 255 255 / 10%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-gap: 0.8em;
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
#editor-modifiers-subheader::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.02);
|
||||
opacity: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#modifiers-header-left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-gap: 0.1em;
|
||||
}
|
||||
#modifiers-header-left span {
|
||||
font-size: 0.8em;
|
||||
color: rgb(127 127 127);
|
||||
font-weight: 200;
|
||||
}
|
||||
#modifiers-header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
grid-gap: 0.8em;
|
||||
margin-right: 0.3em;
|
||||
}
|
||||
|
||||
#editor-modifiers-subheader i,
|
||||
#modifiers-header-right i {
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#modifiers-header-right .section-button,
|
||||
#editor-modifiers-subheader .section-button {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
#modifiers-action-collapsibles-btn {
|
||||
display: flex;
|
||||
grid-gap: 0.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
.modifiers-action-text {
|
||||
font-size: 0.8em;
|
||||
color: rgb(192 192 192);
|
||||
}
|
||||
#modifiers-expand-btn {
|
||||
z-index: 2;
|
||||
}
|
||||
#modifiers-expand-btn .simple-tooltip {
|
||||
background-color: var(--background-color3);
|
||||
border-radius: 50px;
|
||||
}
|
||||
.modifier-category .collapsible {
|
||||
position: relative;
|
||||
}
|
||||
.modifier-category .collapsible::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
.modifier-category:hover .collapsible::after {
|
||||
opacity: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#editor-modifiers-entries {
|
||||
overflow: auto scroll;
|
||||
max-height: 50vh;
|
||||
height: fit-content;
|
||||
margin-bottom: 0.1em;
|
||||
padding-left: 0px;
|
||||
}
|
||||
#editor-modifiers-entries .collapsible {
|
||||
transition: opacity 0.1s ease;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
#editor-modifiers-entries .modifier-category:nth-child(odd) .collapsible::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.02);
|
||||
opacity: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#editor-modifiers .editor-modifiers-leaf {
|
||||
padding-top: 10pt;
|
||||
padding-bottom: 10pt;
|
||||
}
|
||||
#editor-modifiers h5 {
|
||||
padding: 5pt 0;
|
||||
margin: 0;
|
||||
position: sticky;
|
||||
top: -2px;
|
||||
z-index: 10;
|
||||
background-color: var(--background-color3);
|
||||
border-bottom: 1px solid rgb(255 255 255 / 4%);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
img {
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
@ -310,6 +485,9 @@ div.img-preview img {
|
||||
margin-top: 5pt;
|
||||
display: none;
|
||||
}
|
||||
#editor-inputs-tags-list {
|
||||
max-height: 30em;
|
||||
}
|
||||
#server-status {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
@ -779,7 +957,6 @@ input::file-selector-button {
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
|
||||
.input-toggle {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@ -1083,6 +1260,7 @@ input::file-selector-button {
|
||||
/* POPUPS */
|
||||
.popup:not(.active) {
|
||||
visibility: hidden;
|
||||
overflow-x: hidden; /* fix overflow from body */
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,16 @@
|
||||
.modifier-card {
|
||||
position: relative;
|
||||
box-sizing: content-box; /* fixes border misalignment */
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.1s;
|
||||
border-radius: 7px;
|
||||
margin: 3pt 3pt;
|
||||
float: left;
|
||||
width: 8em;
|
||||
height: 11.5em;
|
||||
width: 6em;
|
||||
height: 9.5em;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 8em 3.5em;
|
||||
grid-template-rows: 6em 3.5em;
|
||||
gap: 0px 0px;
|
||||
grid-auto-flow: row;
|
||||
grid-template-areas:
|
||||
@ -16,82 +18,71 @@
|
||||
"modifier-card-container";
|
||||
border: 2px solid rgba(255, 255, 255, .05);
|
||||
cursor: pointer;
|
||||
}
|
||||
.modifier-card-size_5 {
|
||||
width: 18em;
|
||||
grid-template-rows: 18em 3.5em;
|
||||
height: 21.5em;
|
||||
}
|
||||
.modifier-card-size_5 .modifier-card-image-overlay {
|
||||
font-size: 8em;
|
||||
}
|
||||
.modifier-card-size_4 {
|
||||
width: 14em;
|
||||
grid-template-rows: 14em 3.5em;
|
||||
height: 17.5em;
|
||||
}
|
||||
.modifier-card-size_4 .modifier-card-image-overlay {
|
||||
font-size: 7em;
|
||||
z-index: 2;
|
||||
}
|
||||
.modifier-card-size_3 {
|
||||
width: 11em;
|
||||
grid-template-rows: 11em 3.5em;
|
||||
height: 14.5em;
|
||||
}
|
||||
.modifier-card-size_3 .modifier-card-image-overlay {
|
||||
font-size: 6em;
|
||||
}
|
||||
.modifier-card-size_2 {
|
||||
width: 10em;
|
||||
grid-template-rows: 10em 3.5em;
|
||||
height: 13.5em;
|
||||
}
|
||||
.modifier-card-size_2 .modifier-card-image-overlay {
|
||||
.modifier-card-size_3 .modifier-card-image-overlay {
|
||||
font-size: 6em;
|
||||
}
|
||||
.modifier-card-size_1 {
|
||||
.modifier-card-size_3 .modifier-card-label {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.modifier-card-size_2 {
|
||||
width: 9em;
|
||||
grid-template-rows: 9em 3.5em;
|
||||
height: 12.5em;
|
||||
}
|
||||
.modifier-card-size_1 .modifier-card-image-overlay {
|
||||
.modifier-card-size_2 .modifier-card-image-overlay {
|
||||
font-size: 5em;
|
||||
}
|
||||
.modifier-card-size_-1 {
|
||||
.modifier-card-size_2 .modifier-card-label {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.modifier-card-size_1 {
|
||||
width: 7em;
|
||||
grid-template-rows: 7em 3.5em;
|
||||
height: 10.5em;
|
||||
}
|
||||
.modifier-card-size_-1 .modifier-card-image-overlay {
|
||||
.modifier-card-size_1 .modifier-card-image-overlay {
|
||||
font-size: 4em;
|
||||
}
|
||||
.modifier-card-size_-2 {
|
||||
width: 6em;
|
||||
grid-template-rows: 6em 3.5em;
|
||||
height: 9.5em;
|
||||
}
|
||||
.modifier-card-size_-2 .modifier-card-image-overlay {
|
||||
font-size: 3em;
|
||||
}
|
||||
.modifier-card-size_-3 {
|
||||
.modifier-card-size_-1 {
|
||||
width: 5em;
|
||||
grid-template-rows: 5em 3.5em;
|
||||
height: 8.5em;
|
||||
}
|
||||
.modifier-card-size_-3 .modifier-card-image-overlay {
|
||||
.modifier-card-size_-1 .modifier-card-image-overlay {
|
||||
font-size: 3em;
|
||||
}
|
||||
.modifier-card-size_-3 .modifier-card-label {
|
||||
font-size: 0.8em;
|
||||
.modifier-card-size_-1 .modifier-card-label {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.modifier-card-size_-2 {
|
||||
width: 4em;
|
||||
grid-template-rows: 3.5em 3em;
|
||||
height: 6.5em;
|
||||
}
|
||||
.modifier-card-size_-2 .modifier-card-image-overlay {
|
||||
font-size: 2em;
|
||||
}
|
||||
.modifier-card-size_-2 .modifier-card-label {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
.modifier-card-tiny {
|
||||
width: 6em;
|
||||
height: 9.5em;
|
||||
grid-template-rows: 6em 3.5em;
|
||||
width: 5em;
|
||||
grid-template-rows: 5em 3.5em;
|
||||
height: 8.5em;
|
||||
}
|
||||
.modifier-card-tiny .modifier-card-image-overlay {
|
||||
font-size: 4em;
|
||||
}
|
||||
.modifier-card-tiny .modifier-card-label {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.modifier-card:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 5px 16px 5px rgba(0, 0, 0, 0.25);
|
||||
@ -115,6 +106,7 @@
|
||||
}
|
||||
.modifier-card-image-container * {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
}
|
||||
.modifier-card-container {
|
||||
text-align: center;
|
||||
@ -131,6 +123,7 @@
|
||||
.modifier-card-label {
|
||||
padding: 4px;
|
||||
word-break: break-word;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.modifier-card-image-overlay {
|
||||
width: inherit;
|
||||
@ -140,7 +133,7 @@
|
||||
position: absolute;
|
||||
border-radius: 5px 5px 0 0;
|
||||
opacity: 0;
|
||||
font-size: 5em;
|
||||
font-size: 4em;
|
||||
font-weight: 900;
|
||||
color: rgb(255 255 255 / 50%);
|
||||
display: flex;
|
||||
@ -153,9 +146,8 @@
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
}
|
||||
.modifier-card-overlay:hover ~ .modifier-card-container .modifier-card-label.tooltip .tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
.modifier-card-active .modifier-card-overlay {
|
||||
background-color: rgb(169 78 241 / 40%);
|
||||
}
|
||||
.modifier-card:hover > .modifier-card-image-container .modifier-card-image-overlay {
|
||||
opacity: 1;
|
||||
@ -175,53 +167,24 @@
|
||||
border: 2px solid rgb(179 82 255 / 94%);
|
||||
box-shadow: 0 0px 10px 0 rgb(170 0 229 / 58%);
|
||||
}
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
.tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
width: 120px;
|
||||
background: rgb(101,97,181);
|
||||
background: linear-gradient(180deg, rgba(101,97,181,1) 0%, rgba(47,45,85,1) 100%);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 105%;
|
||||
left: 39%;
|
||||
margin-left: -60px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
border: 2px solid rgb(90 100 177 / 94%);
|
||||
box-shadow: 0px 10px 20px 5px rgb(11 0 58 / 55%);
|
||||
width: 10em;
|
||||
}
|
||||
.tooltip .tooltip-text::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -0.9em;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent rgb(90 100 177 / 94%) transparent;
|
||||
}
|
||||
.tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
#modifier-card-size-slider {
|
||||
width: 6em;
|
||||
margin-bottom: 0.5em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#modifier-settings-btn {
|
||||
float: right;
|
||||
}
|
||||
#modifier-settings-config textarea {
|
||||
width: 90%;
|
||||
height: 150px;
|
||||
}
|
||||
.modifier-card .hidden {
|
||||
display: none;
|
||||
}
|
||||
.support-long-label .modifier-card-overlay:hover ~ .modifier-card-container .modifier-card-label {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
.support-long-label .modifier-card-overlay:hover ~ .modifier-card-container .long-label {
|
||||
display: block;
|
||||
}
|
||||
.support-long-label .modifier-card-overlay:hover ~ .modifier-card-container .regular-label {
|
||||
display: none;
|
||||
}
|
@ -1,14 +1,21 @@
|
||||
let activeTags = []
|
||||
let modifiers = []
|
||||
let customModifiersGroupElement = undefined
|
||||
let customModifiersInitialContent
|
||||
let customModifiersInitialContent = ""
|
||||
let modifierPanelFreezed = false
|
||||
|
||||
let modifiersMainContainer = document.querySelector("#editor-modifiers")
|
||||
let modifierDropdown = document.querySelector("#image-modifier-dropdown")
|
||||
let editorModifiersContainer = document.querySelector("#editor-modifiers")
|
||||
let editorModifierEntries = document.querySelector("#editor-modifiers-entries")
|
||||
let editorModifierTagsList = document.querySelector("#editor-inputs-tags-list")
|
||||
let editorTagsContainer = document.querySelector("#editor-inputs-tags-container")
|
||||
let modifierCardSizeSlider = document.querySelector("#modifier-card-size-slider")
|
||||
let previewImageField = document.querySelector("#preview-image")
|
||||
let modifierSettingsBtn = document.querySelector("#modifier-settings-btn")
|
||||
let modifiersContainerSizeBtn = document.querySelector("#modifiers-container-size-btn")
|
||||
let modifiersCloseBtn = document.querySelector("#modifiers-close-button")
|
||||
let modifiersCollapsiblesBtn = document.querySelector("#modifiers-action-collapsibles-btn")
|
||||
let modifierSettingsOverlay = document.querySelector("#modifier-settings-config")
|
||||
let customModifiersTextBox = document.querySelector("#custom-modifiers-input")
|
||||
let customModifierEntriesToolbar = document.querySelector("#editor-modifiers-entries-toolbar")
|
||||
@ -18,31 +25,31 @@ const activeCardClass = "modifier-card-active"
|
||||
const CUSTOM_MODIFIERS_KEY = "customModifiers"
|
||||
|
||||
function createModifierCard(name, previews, removeBy) {
|
||||
const modifierCard = document.createElement("div")
|
||||
let style = previewImageField.value
|
||||
let styleIndex = style == "portrait" ? 0 : 1
|
||||
let cardPreviewImageType = previewImageField.value
|
||||
|
||||
const modifierCard = document.createElement("div")
|
||||
modifierCard.className = "modifier-card"
|
||||
modifierCard.innerHTML = `
|
||||
<div class="modifier-card-overlay"></div>
|
||||
<div class="modifier-card-image-container">
|
||||
<div class="modifier-card-image-overlay">+</div>
|
||||
<p class="modifier-card-error-label"></p>
|
||||
<p class="modifier-card-error-label">No Image</p>
|
||||
<img onerror="this.remove()" alt="Modifier Image" class="modifier-card-image">
|
||||
</div>
|
||||
<div class="modifier-card-container">
|
||||
<div class="modifier-card-label"><p></p></div>
|
||||
<div class="modifier-card-label">
|
||||
<span class="long-label hidden"></span>
|
||||
<p class="regular-label"></p>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
const image = modifierCard.querySelector(".modifier-card-image")
|
||||
const errorText = modifierCard.querySelector(".modifier-card-error-label")
|
||||
const label = modifierCard.querySelector(".modifier-card-label")
|
||||
|
||||
errorText.innerText = "No Image"
|
||||
const longLabel = modifierCard.querySelector(".modifier-card-label span.long-label")
|
||||
const regularLabel = modifierCard.querySelector(".modifier-card-label p.regular-label")
|
||||
|
||||
if (typeof previews == "object") {
|
||||
image.src = previews[styleIndex] // portrait
|
||||
image.setAttribute("preview-type", style)
|
||||
image.src = previews[cardPreviewImageType == "portrait" ? 0 : 1] // 0 index is portrait, 1 landscape
|
||||
image.setAttribute("preview-type", cardPreviewImageType)
|
||||
} else {
|
||||
image.remove()
|
||||
}
|
||||
@ -50,24 +57,32 @@ function createModifierCard(name, previews, removeBy) {
|
||||
const maxLabelLength = 30
|
||||
const cardLabel = removeBy ? name.replace("by ", "") : name
|
||||
|
||||
if (cardLabel.length <= maxLabelLength) {
|
||||
label.querySelector("p").innerText = cardLabel
|
||||
} else {
|
||||
const tooltipText = document.createElement("span")
|
||||
tooltipText.className = "tooltip-text"
|
||||
tooltipText.innerText = name
|
||||
|
||||
label.classList.add("tooltip")
|
||||
label.appendChild(tooltipText)
|
||||
|
||||
label.querySelector("p").innerText = cardLabel.substring(0, maxLabelLength) + "..."
|
||||
function getFormattedLabel(length) {
|
||||
if (cardLabel?.length <= length) {
|
||||
return cardLabel
|
||||
} else {
|
||||
return cardLabel.substring(0, length) + "..."
|
||||
}
|
||||
}
|
||||
|
||||
modifierCard.dataset.fullName = name // preserve the full name
|
||||
regularLabel.dataset.fullName = name // preserve the full name, legacy support for older plugins
|
||||
|
||||
longLabel.innerText = getFormattedLabel(maxLabelLength * 2)
|
||||
regularLabel.innerText = getFormattedLabel(maxLabelLength)
|
||||
|
||||
if (cardLabel.length > maxLabelLength) {
|
||||
modifierCard.classList.add("support-long-label")
|
||||
|
||||
if (cardLabel.length > maxLabelLength * 2) {
|
||||
modifierCard.title = `"${name}"`
|
||||
}
|
||||
}
|
||||
label.querySelector("p").dataset.fullName = name // preserve the full name
|
||||
|
||||
return modifierCard
|
||||
}
|
||||
|
||||
function createModifierGroup(modifierGroup, initiallyExpanded, removeBy) {
|
||||
function createModifierGroup(modifierGroup, isInitiallyOpen, removeBy) {
|
||||
const title = modifierGroup.category
|
||||
const modifiers = modifierGroup.modifiers
|
||||
|
||||
@ -78,8 +93,8 @@ function createModifierGroup(modifierGroup, initiallyExpanded, removeBy) {
|
||||
const modifiersEl = document.createElement("div")
|
||||
modifiersEl.classList.add("collapsible-content", "editor-modifiers-leaf")
|
||||
|
||||
if (initiallyExpanded === true) {
|
||||
titleEl.className += " active"
|
||||
if (isInitiallyOpen === true) {
|
||||
titleEl.classList.add("active")
|
||||
}
|
||||
|
||||
modifiers.forEach((modObj) => {
|
||||
@ -126,7 +141,7 @@ function createModifierGroup(modifierGroup, initiallyExpanded, removeBy) {
|
||||
e.appendChild(titleEl)
|
||||
e.appendChild(modifiersEl)
|
||||
|
||||
editorModifierEntries.insertBefore(e, customModifierEntriesToolbar.nextSibling)
|
||||
editorModifierEntries.prepend(e)
|
||||
|
||||
return e
|
||||
}
|
||||
@ -149,7 +164,10 @@ async function loadModifiers() {
|
||||
res.reverse()
|
||||
|
||||
res.forEach((modifierGroup, idx) => {
|
||||
createModifierGroup(modifierGroup, idx === res.length - 1, modifierGroup === "Artist" ? true : false) // only remove "By " for artists
|
||||
const isInitiallyOpen = false // idx === res.length - 1
|
||||
const removeBy = modifierGroup === "Artist" ? true : false // only remove "By " for artists
|
||||
|
||||
createModifierGroup(modifierGroup, isInitiallyOpen, removeBy)
|
||||
})
|
||||
|
||||
createCollapsibles(editorModifierEntries)
|
||||
@ -169,7 +187,7 @@ function refreshModifiersState(newTags, inactiveTags) {
|
||||
.querySelector("#editor-modifiers")
|
||||
.querySelectorAll(".modifier-card")
|
||||
.forEach((modifierCard) => {
|
||||
const modifierName = modifierCard.querySelector(".modifier-card-label p").dataset.fullName // pick the full modifier name
|
||||
const modifierName = modifierCard.dataset.fullName // pick the full modifier name
|
||||
if (activeTags.map((x) => x.name).includes(modifierName)) {
|
||||
modifierCard.classList.remove(activeCardClass)
|
||||
modifierCard.querySelector(".modifier-card-image-overlay").innerText = "+"
|
||||
@ -184,8 +202,9 @@ function refreshModifiersState(newTags, inactiveTags) {
|
||||
.querySelector("#editor-modifiers")
|
||||
.querySelectorAll(".modifier-card")
|
||||
.forEach((modifierCard) => {
|
||||
const modifierName = modifierCard.querySelector(".modifier-card-label p").dataset.fullName
|
||||
const modifierName = modifierCard.dataset.fullName
|
||||
const shortModifierName = modifierCard.querySelector(".modifier-card-label p").innerText
|
||||
|
||||
if (trimModifiers(tag) == trimModifiers(modifierName)) {
|
||||
// add modifier to active array
|
||||
if (!activeTags.map((x) => x.name).includes(tag)) {
|
||||
@ -242,10 +261,10 @@ function refreshInactiveTags(inactiveTags) {
|
||||
}
|
||||
|
||||
// update cards
|
||||
let overlays = document.querySelector("#editor-inputs-tags-list").querySelectorAll(".modifier-card-overlay")
|
||||
let overlays = editorModifierTagsList.querySelectorAll(".modifier-card-overlay")
|
||||
overlays.forEach((i) => {
|
||||
let modifierName = i.parentElement.getElementsByClassName("modifier-card-label")[0].getElementsByTagName("p")[0]
|
||||
.dataset.fullName
|
||||
let modifierName = i.parentElement.dataset.fullName
|
||||
|
||||
if (inactiveTags?.find((element) => trimModifiers(element) === modifierName) !== undefined) {
|
||||
i.parentElement.classList.add("modifier-toggle-inactive")
|
||||
}
|
||||
@ -262,6 +281,12 @@ function refreshTagsList(inactiveTags) {
|
||||
editorTagsContainer.style.display = "block"
|
||||
}
|
||||
|
||||
if(activeTags.length > 15) {
|
||||
editorModifierTagsList.style["overflow-y"] = "auto"
|
||||
} else {
|
||||
editorModifierTagsList.style["overflow-y"] = "unset"
|
||||
}
|
||||
|
||||
activeTags.forEach((tag, index) => {
|
||||
tag.element.querySelector(".modifier-card-image-overlay").innerText = "-"
|
||||
tag.element.classList.add("modifier-card-tiny")
|
||||
@ -285,48 +310,42 @@ function refreshTagsList(inactiveTags) {
|
||||
|
||||
let brk = document.createElement("br")
|
||||
brk.style.clear = "both"
|
||||
|
||||
editorModifierTagsList.appendChild(brk)
|
||||
|
||||
refreshInactiveTags(inactiveTags)
|
||||
|
||||
document.dispatchEvent(new Event("refreshImageModifiers")) // notify plugins that the image tags have been refreshed
|
||||
}
|
||||
|
||||
function toggleCardState(modifierName, makeActive) {
|
||||
document
|
||||
.querySelector("#editor-modifiers")
|
||||
.querySelectorAll(".modifier-card")
|
||||
.forEach((card) => {
|
||||
const name = card.querySelector(".modifier-card-label").innerText
|
||||
if (
|
||||
trimModifiers(modifierName) == trimModifiers(name) ||
|
||||
trimModifiers(modifierName) == "by " + trimModifiers(name)
|
||||
) {
|
||||
if (makeActive) {
|
||||
card.classList.add(activeCardClass)
|
||||
card.querySelector(".modifier-card-image-overlay").innerText = "-"
|
||||
} else {
|
||||
card.classList.remove(activeCardClass)
|
||||
card.querySelector(".modifier-card-image-overlay").innerText = "+"
|
||||
}
|
||||
}
|
||||
})
|
||||
const cards = [...document.querySelectorAll("#editor-modifiers .modifier-card")]
|
||||
.filter(cardElem => trimModifiers(cardElem.dataset.fullName) == trimModifiers(modifierName))
|
||||
|
||||
const cardExists = typeof cards == "object" && cards?.length > 0
|
||||
|
||||
if (cardExists) {
|
||||
const card = cards[0]
|
||||
|
||||
if (makeActive) {
|
||||
card.classList.add(activeCardClass)
|
||||
card.querySelector(".modifier-card-image-overlay").innerText = "-"
|
||||
} else {
|
||||
card.classList.remove(activeCardClass)
|
||||
card.querySelector(".modifier-card-image-overlay").innerText = "+"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function changePreviewImages(val) {
|
||||
const previewImages = document.querySelectorAll(".modifier-card-image-container img")
|
||||
|
||||
let previewArr = []
|
||||
|
||||
modifiers.map((x) => x.modifiers).forEach((x) => previewArr.push(...x.map((m) => m.previews)))
|
||||
|
||||
previewArr = previewArr.map((x) => {
|
||||
let obj = {}
|
||||
|
||||
x.forEach((preview) => {
|
||||
const previewArr = modifiers.flatMap((x) => x.modifiers.map((m) => m.previews))
|
||||
.map((x) => x.reduce((obj, preview) => {
|
||||
obj[preview.name] = preview.path
|
||||
})
|
||||
|
||||
return obj
|
||||
})
|
||||
return obj
|
||||
}, {}))
|
||||
|
||||
previewImages.forEach((previewImage) => {
|
||||
const currentPreviewType = previewImage.getAttribute("preview-type")
|
||||
@ -369,17 +388,70 @@ function resizeModifierCards(val) {
|
||||
})
|
||||
}
|
||||
|
||||
function saveCustomModifiers() {
|
||||
localStorage.setItem(CUSTOM_MODIFIERS_KEY, customModifiersTextBox.value.trim())
|
||||
|
||||
loadCustomModifiers()
|
||||
}
|
||||
|
||||
function loadCustomModifiers() {
|
||||
PLUGINS["MODIFIERS_LOAD"].forEach((fn) => fn.loader.call())
|
||||
}
|
||||
|
||||
function showModifierContainer() {
|
||||
document.addEventListener("click", checkIfClickedOutsideDropdownElem)
|
||||
|
||||
modifierDropdown.dataset.active = true
|
||||
editorModifiersContainer.classList.add("active")
|
||||
}
|
||||
|
||||
function hideModifierContainer() {
|
||||
document.removeEventListener("click", checkIfClickedOutsideDropdownElem)
|
||||
|
||||
modifierDropdown.dataset.active = false
|
||||
editorModifiersContainer.classList.remove("active")
|
||||
}
|
||||
|
||||
function checkIfClickedOutsideDropdownElem(e) {
|
||||
const clickedElement = e.target
|
||||
|
||||
const clickedInsideSpecificElems = [modifierDropdown, editorModifiersContainer, modifierSettingsOverlay].some((div) =>
|
||||
div && (div.contains(clickedElement) || div === clickedElement))
|
||||
|
||||
if (!clickedInsideSpecificElems && !modifierPanelFreezed) {
|
||||
hideModifierContainer()
|
||||
}
|
||||
}
|
||||
|
||||
function collapseAllModifierCategory() {
|
||||
const collapsibleElems = editorModifierEntries.querySelectorAll(".modifier-category .collapsible"); // needs to have ";"
|
||||
|
||||
[...collapsibleElems].forEach((elem) => {
|
||||
const isActive = elem.classList.contains("active")
|
||||
|
||||
if(isActive) {
|
||||
elem?.click()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function expandAllModifierCategory() {
|
||||
const collapsibleElems = editorModifierEntries.querySelectorAll(".modifier-category .collapsible"); // needs to have ";"
|
||||
|
||||
[...collapsibleElems].forEach((elem) => {
|
||||
const isActive = elem.classList.contains("active")
|
||||
|
||||
if (!isActive) {
|
||||
elem?.click()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
customModifiersTextBox.addEventListener("change", saveCustomModifiers)
|
||||
|
||||
modifierCardSizeSlider.onchange = () => resizeModifierCards(modifierCardSizeSlider.value)
|
||||
previewImageField.onchange = () => changePreviewImages(previewImageField.value)
|
||||
|
||||
modifierSettingsBtn.addEventListener("click", function(e) {
|
||||
modifierSettingsOverlay.classList.add("active")
|
||||
customModifiersTextBox.setSelectionRange(0, 0)
|
||||
customModifiersTextBox.focus()
|
||||
customModifiersInitialContent = customModifiersTextBox.value // preserve the initial content
|
||||
e.stopPropagation()
|
||||
})
|
||||
|
||||
modifierSettingsOverlay.addEventListener("keydown", function(e) {
|
||||
switch (e.key) {
|
||||
case "Escape": // Escape to cancel
|
||||
@ -397,14 +469,93 @@ modifierSettingsOverlay.addEventListener("keydown", function(e) {
|
||||
}
|
||||
})
|
||||
|
||||
function saveCustomModifiers() {
|
||||
localStorage.setItem(CUSTOM_MODIFIERS_KEY, customModifiersTextBox.value.trim())
|
||||
modifierDropdown.addEventListener("click", e => {
|
||||
const targetElem = e.target
|
||||
const isDropdownActive = targetElem.dataset.active == "true" ? true : false
|
||||
|
||||
loadCustomModifiers()
|
||||
}
|
||||
if (!isDropdownActive)
|
||||
showModifierContainer()
|
||||
else
|
||||
hideModifierContainer()
|
||||
})
|
||||
|
||||
function loadCustomModifiers() {
|
||||
PLUGINS["MODIFIERS_LOAD"].forEach((fn) => fn.loader.call())
|
||||
}
|
||||
let collapsiblesBtnState = false
|
||||
|
||||
customModifiersTextBox.addEventListener("change", saveCustomModifiers)
|
||||
modifiersCollapsiblesBtn.addEventListener("click", (e) => {
|
||||
const btnElem = modifiersCollapsiblesBtn
|
||||
|
||||
const collapseText = "Collapse Categories"
|
||||
const expandText = "Expand Categories"
|
||||
|
||||
const collapseIconClasses = ["fa-solid", "fa-square-minus"]
|
||||
const expandIconClasses = ["fa-solid", "fa-square-plus"]
|
||||
|
||||
const iconElem = btnElem.querySelector(".modifiers-action-icon")
|
||||
const textElem = btnElem.querySelector(".modifiers-action-text")
|
||||
|
||||
if (collapsiblesBtnState) {
|
||||
collapseAllModifierCategory()
|
||||
|
||||
collapsiblesBtnState = false
|
||||
|
||||
collapseIconClasses.forEach((c) => iconElem.classList.remove(c))
|
||||
expandIconClasses.forEach((c) => iconElem.classList.add(c))
|
||||
|
||||
textElem.innerText = expandText
|
||||
} else {
|
||||
expandAllModifierCategory()
|
||||
|
||||
collapsiblesBtnState = true
|
||||
|
||||
expandIconClasses.forEach((c) => iconElem.classList.remove(c))
|
||||
collapseIconClasses.forEach((c) => iconElem.classList.add(c))
|
||||
|
||||
textElem.innerText = collapseText
|
||||
}
|
||||
})
|
||||
|
||||
let containerSizeBtnState = false
|
||||
|
||||
modifiersContainerSizeBtn.addEventListener("click", (e) => {
|
||||
const btnElem = modifiersContainerSizeBtn
|
||||
|
||||
const maximizeIconClasses = ["fa-solid", "fa-expand"]
|
||||
const revertIconClasses = ["fa-solid", "fa-compress"]
|
||||
|
||||
modifiersMainContainer.classList.toggle("modifiers-maximized")
|
||||
|
||||
if(containerSizeBtnState) {
|
||||
revertIconClasses.forEach((c) => btnElem.classList.remove(c))
|
||||
maximizeIconClasses.forEach((c) => btnElem.classList.add(c))
|
||||
|
||||
containerSizeBtnState = false
|
||||
} else {
|
||||
maximizeIconClasses.forEach((c) => btnElem.classList.remove(c))
|
||||
revertIconClasses.forEach((c) => btnElem.classList.add(c))
|
||||
|
||||
containerSizeBtnState = true
|
||||
}
|
||||
})
|
||||
|
||||
modifierSettingsBtn.addEventListener("click", (e) => {
|
||||
modifierSettingsOverlay.classList.add("active")
|
||||
customModifiersTextBox.setSelectionRange(0, 0)
|
||||
customModifiersTextBox.focus()
|
||||
customModifiersInitialContent = customModifiersTextBox.value // preserve the initial content
|
||||
e.stopPropagation()
|
||||
})
|
||||
|
||||
modifiersCloseBtn.addEventListener("click", (e) => {
|
||||
hideModifierContainer()
|
||||
})
|
||||
|
||||
// prevents the modifier panel closing at the same time as the settings overlay
|
||||
new MutationObserver(() => {
|
||||
const isActive = modifierSettingsOverlay.classList.contains("active")
|
||||
|
||||
if (!isActive) {
|
||||
modifierPanelFreezed = true
|
||||
|
||||
setTimeout(() => modifierPanelFreezed = false, 25)
|
||||
}
|
||||
}).observe(modifierSettingsOverlay, { attributes: true })
|
Loading…
Reference in New Issue
Block a user