mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-06-01 07:35:38 +02:00
Move image modifiers JS to a separate file
This commit is contained in:
parent
eccb3c643d
commit
4da9843479
@ -251,7 +251,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<script src="media/js/utils.js?v=1"></script>
|
||||||
<script src="media/js/inpainting-editor.js?v=1"></script>
|
<script src="media/js/inpainting-editor.js?v=1"></script>
|
||||||
|
<script src="media/js/image-modifiers.js"></script>
|
||||||
<script src="media/js/auto-save.js?v=1"></script>
|
<script src="media/js/auto-save.js?v=1"></script>
|
||||||
<script src="media/js/main.js?v=1"></script>
|
<script src="media/js/main.js?v=1"></script>
|
||||||
<script src="media/js/themes.js?v=1"></script>
|
<script src="media/js/themes.js?v=1"></script>
|
||||||
|
230
ui/media/js/image-modifiers.js
Normal file
230
ui/media/js/image-modifiers.js
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
let activeTags = []
|
||||||
|
let 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')
|
||||||
|
|
||||||
|
const modifierThumbnailPath = 'media/modifier-thumbnails'
|
||||||
|
const activeCardClass = 'modifier-card-active'
|
||||||
|
|
||||||
|
function createModifierCard(name, previews) {
|
||||||
|
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>
|
||||||
|
<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>`
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
if (typeof previews == 'object') {
|
||||||
|
image.src = previews[0]; // portrait
|
||||||
|
image.setAttribute('preview-type', 'portrait')
|
||||||
|
} else {
|
||||||
|
image.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxLabelLength = 30
|
||||||
|
const nameWithoutBy = name.replace('by ', '')
|
||||||
|
|
||||||
|
if(nameWithoutBy.length <= maxLabelLength) {
|
||||||
|
label.querySelector('p').innerText = nameWithoutBy
|
||||||
|
} else {
|
||||||
|
const tooltipText = document.createElement('span')
|
||||||
|
tooltipText.className = 'tooltip-text'
|
||||||
|
tooltipText.innerText = name
|
||||||
|
|
||||||
|
label.classList.add('tooltip')
|
||||||
|
label.appendChild(tooltipText)
|
||||||
|
|
||||||
|
label.querySelector('p').innerText = nameWithoutBy.substring(0, maxLabelLength) + '...'
|
||||||
|
}
|
||||||
|
|
||||||
|
return modifierCard
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadModifiers() {
|
||||||
|
try {
|
||||||
|
let res = await fetch('/get/modifiers')
|
||||||
|
if (res.status === 200) {
|
||||||
|
res = await res.json()
|
||||||
|
|
||||||
|
modifiers = res; // update global variable
|
||||||
|
|
||||||
|
res.forEach((modifierGroup, idx) => {
|
||||||
|
const title = modifierGroup.category
|
||||||
|
const modifiers = modifierGroup.modifiers
|
||||||
|
|
||||||
|
const titleEl = document.createElement('h5')
|
||||||
|
titleEl.className = 'collapsible'
|
||||||
|
titleEl.innerText = title
|
||||||
|
|
||||||
|
const modifiersEl = document.createElement('div')
|
||||||
|
modifiersEl.classList.add('collapsible-content', 'editor-modifiers-leaf')
|
||||||
|
|
||||||
|
if (idx == 0) {
|
||||||
|
titleEl.className += ' active'
|
||||||
|
modifiersEl.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiers.forEach(modObj => {
|
||||||
|
const modifierName = modObj.modifier
|
||||||
|
const modifierPreviews = modObj?.previews?.map(preview => `${modifierThumbnailPath}/${preview.path}`)
|
||||||
|
|
||||||
|
const modifierCard = createModifierCard(modifierName, modifierPreviews)
|
||||||
|
|
||||||
|
if(typeof modifierCard == 'object') {
|
||||||
|
modifiersEl.appendChild(modifierCard)
|
||||||
|
|
||||||
|
modifierCard.addEventListener('click', () => {
|
||||||
|
if (activeTags.map(x => x.name).includes(modifierName)) {
|
||||||
|
// remove modifier from active array
|
||||||
|
activeTags = activeTags.filter(x => x.name != modifierName)
|
||||||
|
modifierCard.classList.remove(activeCardClass)
|
||||||
|
|
||||||
|
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+'
|
||||||
|
} else {
|
||||||
|
// add modifier to active array
|
||||||
|
activeTags.push({
|
||||||
|
'name': modifierName,
|
||||||
|
'element': modifierCard.cloneNode(true),
|
||||||
|
'originElement': modifierCard,
|
||||||
|
'previews': modifierPreviews
|
||||||
|
})
|
||||||
|
|
||||||
|
modifierCard.classList.add(activeCardClass)
|
||||||
|
|
||||||
|
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshTagsList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let brk = document.createElement('br')
|
||||||
|
brk.style.clear = 'both'
|
||||||
|
modifiersEl.appendChild(brk)
|
||||||
|
|
||||||
|
let e = document.createElement('div')
|
||||||
|
e.appendChild(titleEl)
|
||||||
|
e.appendChild(modifiersEl)
|
||||||
|
|
||||||
|
editorModifierEntries.appendChild(e)
|
||||||
|
})
|
||||||
|
|
||||||
|
createCollapsibles(editorModifierEntries)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log('error fetching modifiers', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshTagsList() {
|
||||||
|
editorModifierTagsList.innerHTML = ''
|
||||||
|
|
||||||
|
if (activeTags.length == 0) {
|
||||||
|
editorTagsContainer.style.display = 'none'
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
editorTagsContainer.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
activeTags.forEach((tag, index) => {
|
||||||
|
tag.element.querySelector('.modifier-card-image-overlay').innerText = '-'
|
||||||
|
tag.element.classList.add('modifier-card-tiny')
|
||||||
|
|
||||||
|
editorModifierTagsList.appendChild(tag.element)
|
||||||
|
|
||||||
|
tag.element.addEventListener('click', () => {
|
||||||
|
let idx = activeTags.indexOf(tag)
|
||||||
|
|
||||||
|
if (idx !== -1) {
|
||||||
|
activeTags[idx].originElement.classList.remove(activeCardClass)
|
||||||
|
activeTags[idx].originElement.querySelector('.modifier-card-image-overlay').innerText = '+'
|
||||||
|
|
||||||
|
activeTags.splice(idx, 1)
|
||||||
|
refreshTagsList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
let brk = document.createElement('br')
|
||||||
|
brk.style.clear = 'both'
|
||||||
|
editorModifierTagsList.appendChild(brk)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 => {
|
||||||
|
obj[preview.name] = preview.path
|
||||||
|
})
|
||||||
|
|
||||||
|
return obj
|
||||||
|
})
|
||||||
|
|
||||||
|
previewImages.forEach(previewImage => {
|
||||||
|
const currentPreviewType = previewImage.getAttribute('preview-type')
|
||||||
|
const relativePreviewPath = previewImage.src.split(modifierThumbnailPath + '/').pop()
|
||||||
|
|
||||||
|
const previews = previewArr.find(preview => relativePreviewPath == preview[currentPreviewType])
|
||||||
|
|
||||||
|
if(typeof previews == 'object') {
|
||||||
|
let preview = null
|
||||||
|
|
||||||
|
if (val == 'portrait') {
|
||||||
|
preview = previews.portrait
|
||||||
|
}
|
||||||
|
else if (val == 'landscape') {
|
||||||
|
preview = previews.landscape
|
||||||
|
}
|
||||||
|
|
||||||
|
if(preview != null) {
|
||||||
|
previewImage.src = `${modifierThumbnailPath}/${preview}`
|
||||||
|
previewImage.setAttribute('preview-type', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeModifierCards(val) {
|
||||||
|
const cardSizePrefix = 'modifier-card-size_'
|
||||||
|
const modifierCardClass = 'modifier-card'
|
||||||
|
|
||||||
|
const modifierCards = document.querySelectorAll(`.${modifierCardClass}`)
|
||||||
|
const cardSize = n => `${cardSizePrefix}${n}`
|
||||||
|
|
||||||
|
modifierCards.forEach(card => {
|
||||||
|
// remove existing size classes
|
||||||
|
const classes = card.className.split(' ').filter(c => !c.startsWith(cardSizePrefix))
|
||||||
|
card.className = classes.join(' ').trim()
|
||||||
|
|
||||||
|
if(val != 0) {
|
||||||
|
card.classList.add(cardSize(val))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
modifierCardSizeSlider.onchange = () => resizeModifierCards(modifierCardSizeSlider.value)
|
||||||
|
previewImageField.onchange = () => changePreviewImages(previewImageField.value)
|
@ -79,16 +79,7 @@ let clearAllPreviewsBtn = document.querySelector("#clear-all-previews")
|
|||||||
let maskSetting = document.querySelector('#enable_mask')
|
let maskSetting = document.querySelector('#enable_mask')
|
||||||
let negativePromptPanelHandle = document.querySelector('#negative_prompt_handle')
|
let negativePromptPanelHandle = document.querySelector('#negative_prompt_handle')
|
||||||
|
|
||||||
let editorModifierEntries = document.querySelector('#editor-modifiers-entries')
|
|
||||||
let editorModifierTagsList = document.querySelector('#editor-inputs-tags-list')
|
|
||||||
let editorTagsContainer = document.querySelector('#editor-inputs-tags-container')
|
|
||||||
|
|
||||||
let imagePreview = document.querySelector("#preview")
|
let imagePreview = document.querySelector("#preview")
|
||||||
let previewImageField = document.querySelector('#preview-image')
|
|
||||||
previewImageField.onchange = () => changePreviewImages(previewImageField.value)
|
|
||||||
|
|
||||||
let modifierCardSizeSlider = document.querySelector('#modifier-card-size-slider')
|
|
||||||
modifierCardSizeSlider.onchange = () => resizeModifierCards(modifierCardSizeSlider.value)
|
|
||||||
|
|
||||||
// let previewPrompt = document.querySelector('#preview-prompt')
|
// let previewPrompt = document.querySelector('#preview-prompt')
|
||||||
|
|
||||||
@ -114,17 +105,12 @@ maskResetButton.style.fontWeight = 'normal'
|
|||||||
maskResetButton.style.fontSize = '10pt'
|
maskResetButton.style.fontSize = '10pt'
|
||||||
|
|
||||||
let serverState = {'status': 'Offline', 'time': Date.now()}
|
let serverState = {'status': 'Offline', 'time': Date.now()}
|
||||||
let activeTags = []
|
|
||||||
let modifiers = []
|
|
||||||
let lastPromptUsed = ''
|
let lastPromptUsed = ''
|
||||||
let bellPending = false
|
let bellPending = false
|
||||||
|
|
||||||
let taskQueue = []
|
let taskQueue = []
|
||||||
let currentTask = null
|
let currentTask = null
|
||||||
|
|
||||||
const modifierThumbnailPath = 'media/modifier-thumbnails'
|
|
||||||
const activeCardClass = 'modifier-card-active'
|
|
||||||
|
|
||||||
function getLocalStorageItem(key, fallback) {
|
function getLocalStorageItem(key, fallback) {
|
||||||
let item = localStorage.getItem(key)
|
let item = localStorage.getItem(key)
|
||||||
if (item === null) {
|
if (item === null) {
|
||||||
@ -1002,28 +988,6 @@ function permutePrompts(promptBase, promptMatrix) {
|
|||||||
return prompts
|
return prompts
|
||||||
}
|
}
|
||||||
|
|
||||||
function permute(arr) {
|
|
||||||
let permutations = []
|
|
||||||
let n = arr.length
|
|
||||||
let n_permutations = Math.pow(2, n)
|
|
||||||
for (let i = 0; i < n_permutations; i++) {
|
|
||||||
let perm = []
|
|
||||||
let mask = Number(i).toString(2).padStart(n, '0')
|
|
||||||
|
|
||||||
for (let idx = 0; idx < mask.length; idx++) {
|
|
||||||
if (mask[idx] === '1' && arr[idx].trim() !== '') {
|
|
||||||
perm.push(arr[idx])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perm.length > 0) {
|
|
||||||
permutations.push(perm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return permutations
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a file name with embedded prompt and metadata
|
// create a file name with embedded prompt and metadata
|
||||||
// for easier cateloging and comparison
|
// for easier cateloging and comparison
|
||||||
function createFileName(prompt, seed, steps, guidance, outputFormat) {
|
function createFileName(prompt, seed, steps, guidance, outputFormat) {
|
||||||
@ -1370,150 +1334,6 @@ promptsFromFileSelector.addEventListener('change', function() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// function showMaskImagePreview() {
|
|
||||||
// if (maskImageSelector.files.length === 0) {
|
|
||||||
// // maskImagePreviewContainer.style.display = 'none'
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let reader = new FileReader()
|
|
||||||
// let file = maskImageSelector.files[0]
|
|
||||||
|
|
||||||
// reader.addEventListener('load', function() {
|
|
||||||
// // maskImagePreview.src = reader.result
|
|
||||||
// // maskImagePreviewContainer.style.display = 'block'
|
|
||||||
// })
|
|
||||||
|
|
||||||
// if (file) {
|
|
||||||
// reader.readAsDataURL(file)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// maskImageSelector.addEventListener('change', showMaskImagePreview)
|
|
||||||
// showMaskImagePreview()
|
|
||||||
|
|
||||||
// maskImageClearBtn.addEventListener('click', function() {
|
|
||||||
// maskImageSelector.value = null
|
|
||||||
// maskImagePreview.src = ''
|
|
||||||
// // maskImagePreviewContainer.style.display = 'none'
|
|
||||||
// })
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/8212878
|
|
||||||
function millisecondsToStr(milliseconds) {
|
|
||||||
function numberEnding (number) {
|
|
||||||
return (number > 1) ? 's' : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
var temp = Math.floor(milliseconds / 1000)
|
|
||||||
var hours = Math.floor((temp %= 86400) / 3600)
|
|
||||||
var s = ''
|
|
||||||
if (hours) {
|
|
||||||
s += hours + ' hour' + numberEnding(hours) + ' '
|
|
||||||
}
|
|
||||||
var minutes = Math.floor((temp %= 3600) / 60)
|
|
||||||
if (minutes) {
|
|
||||||
s += minutes + ' minute' + numberEnding(minutes) + ' '
|
|
||||||
}
|
|
||||||
var seconds = temp % 60
|
|
||||||
if (!hours && minutes < 4 && seconds) {
|
|
||||||
s += seconds + ' second' + numberEnding(seconds)
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://gomakethings.com/finding-the-next-and-previous-sibling-elements-that-match-a-selector-with-vanilla-js/
|
|
||||||
function getNextSibling(elem, selector) {
|
|
||||||
// Get the next sibling element
|
|
||||||
var sibling = elem.nextElementSibling
|
|
||||||
|
|
||||||
// If there's no selector, return the first sibling
|
|
||||||
if (!selector) return sibling
|
|
||||||
|
|
||||||
// If the sibling matches our selector, use it
|
|
||||||
// If not, jump to the next sibling and continue the loop
|
|
||||||
while (sibling) {
|
|
||||||
if (sibling.matches(selector)) return sibling
|
|
||||||
sibling = sibling.nextElementSibling
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createCollapsibles(node) {
|
|
||||||
if (!node) {
|
|
||||||
node = document
|
|
||||||
}
|
|
||||||
|
|
||||||
let collapsibles = node.querySelectorAll(".collapsible")
|
|
||||||
collapsibles.forEach(function(c) {
|
|
||||||
let handle = document.createElement('span')
|
|
||||||
handle.className = 'collapsible-handle'
|
|
||||||
|
|
||||||
if (c.className.indexOf('active') !== -1) {
|
|
||||||
handle.innerHTML = '➖' // minus
|
|
||||||
} else {
|
|
||||||
handle.innerHTML = '➕' // plus
|
|
||||||
}
|
|
||||||
c.insertBefore(handle, c.firstChild)
|
|
||||||
|
|
||||||
c.addEventListener('click', function() {
|
|
||||||
this.classList.toggle("active")
|
|
||||||
let content = getNextSibling(this, '.collapsible-content')
|
|
||||||
if (content.style.display === "block") {
|
|
||||||
content.style.display = "none"
|
|
||||||
handle.innerHTML = '➕' // plus
|
|
||||||
} else {
|
|
||||||
content.style.display = "block"
|
|
||||||
handle.innerHTML = '➖' // minus
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this == advancedPanelHandle) {
|
|
||||||
let state = (content.style.display === 'block' ? 'true' : 'false')
|
|
||||||
localStorage.setItem(ADVANCED_PANEL_OPEN_KEY, state)
|
|
||||||
} else if (this == modifiersPanelHandle) {
|
|
||||||
let state = (content.style.display === 'block' ? 'true' : 'false')
|
|
||||||
localStorage.setItem(MODIFIERS_PANEL_OPEN_KEY, state)
|
|
||||||
} else if (this == negativePromptPanelHandle) {
|
|
||||||
let state = (content.style.display === 'block' ? 'true' : 'false')
|
|
||||||
localStorage.setItem(NEGATIVE_PROMPT_PANEL_OPEN_KEY, state)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
createCollapsibles()
|
|
||||||
|
|
||||||
function refreshTagsList() {
|
|
||||||
editorModifierTagsList.innerHTML = ''
|
|
||||||
|
|
||||||
if (activeTags.length == 0) {
|
|
||||||
editorTagsContainer.style.display = 'none'
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
editorTagsContainer.style.display = 'block'
|
|
||||||
}
|
|
||||||
|
|
||||||
activeTags.forEach((tag, index) => {
|
|
||||||
tag.element.querySelector('.modifier-card-image-overlay').innerText = '-'
|
|
||||||
tag.element.classList.add('modifier-card-tiny')
|
|
||||||
|
|
||||||
editorModifierTagsList.appendChild(tag.element)
|
|
||||||
|
|
||||||
tag.element.addEventListener('click', () => {
|
|
||||||
let idx = activeTags.indexOf(tag)
|
|
||||||
|
|
||||||
if (idx !== -1) {
|
|
||||||
activeTags[idx].originElement.classList.remove(activeCardClass)
|
|
||||||
activeTags[idx].originElement.querySelector('.modifier-card-image-overlay').innerText = '+'
|
|
||||||
|
|
||||||
activeTags.splice(idx, 1)
|
|
||||||
refreshTagsList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
let brk = document.createElement('br')
|
|
||||||
brk.style.clear = 'both'
|
|
||||||
editorModifierTagsList.appendChild(brk)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getDiskPath() {
|
async function getDiskPath() {
|
||||||
try {
|
try {
|
||||||
let diskPath = getSavedDiskPath()
|
let diskPath = getSavedDiskPath()
|
||||||
@ -1535,184 +1355,4 @@ async function getDiskPath() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createModifierCard(name, previews) {
|
createCollapsibles()
|
||||||
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>
|
|
||||||
<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>`
|
|
||||||
|
|
||||||
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'
|
|
||||||
|
|
||||||
if (typeof previews == 'object') {
|
|
||||||
image.src = previews[0]; // portrait
|
|
||||||
image.setAttribute('preview-type', 'portrait')
|
|
||||||
} else {
|
|
||||||
image.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxLabelLength = 30
|
|
||||||
const nameWithoutBy = name.replace('by ', '')
|
|
||||||
|
|
||||||
if(nameWithoutBy.length <= maxLabelLength) {
|
|
||||||
label.querySelector('p').innerText = nameWithoutBy
|
|
||||||
} else {
|
|
||||||
const tooltipText = document.createElement('span')
|
|
||||||
tooltipText.className = 'tooltip-text'
|
|
||||||
tooltipText.innerText = name
|
|
||||||
|
|
||||||
label.classList.add('tooltip')
|
|
||||||
label.appendChild(tooltipText)
|
|
||||||
|
|
||||||
label.querySelector('p').innerText = nameWithoutBy.substring(0, maxLabelLength) + '...'
|
|
||||||
}
|
|
||||||
|
|
||||||
return modifierCard
|
|
||||||
}
|
|
||||||
|
|
||||||
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 => {
|
|
||||||
obj[preview.name] = preview.path
|
|
||||||
})
|
|
||||||
|
|
||||||
return obj
|
|
||||||
})
|
|
||||||
|
|
||||||
previewImages.forEach(previewImage => {
|
|
||||||
const currentPreviewType = previewImage.getAttribute('preview-type')
|
|
||||||
const relativePreviewPath = previewImage.src.split(modifierThumbnailPath + '/').pop()
|
|
||||||
|
|
||||||
const previews = previewArr.find(preview => relativePreviewPath == preview[currentPreviewType])
|
|
||||||
|
|
||||||
if(typeof previews == 'object') {
|
|
||||||
let preview = null
|
|
||||||
|
|
||||||
if (val == 'portrait') {
|
|
||||||
preview = previews.portrait
|
|
||||||
}
|
|
||||||
else if (val == 'landscape') {
|
|
||||||
preview = previews.landscape
|
|
||||||
}
|
|
||||||
|
|
||||||
if(preview != null) {
|
|
||||||
previewImage.src = `${modifierThumbnailPath}/${preview}`
|
|
||||||
previewImage.setAttribute('preview-type', val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function resizeModifierCards(val) {
|
|
||||||
const cardSizePrefix = 'modifier-card-size_'
|
|
||||||
const modifierCardClass = 'modifier-card'
|
|
||||||
|
|
||||||
const modifierCards = document.querySelectorAll(`.${modifierCardClass}`)
|
|
||||||
const cardSize = n => `${cardSizePrefix}${n}`
|
|
||||||
|
|
||||||
modifierCards.forEach(card => {
|
|
||||||
// remove existing size classes
|
|
||||||
const classes = card.className.split(' ').filter(c => !c.startsWith(cardSizePrefix))
|
|
||||||
card.className = classes.join(' ').trim()
|
|
||||||
|
|
||||||
if(val != 0) {
|
|
||||||
card.classList.add(cardSize(val))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadModifiers() {
|
|
||||||
try {
|
|
||||||
let res = await fetch('/get/modifiers')
|
|
||||||
if (res.status === 200) {
|
|
||||||
res = await res.json()
|
|
||||||
|
|
||||||
modifiers = res; // update global variable
|
|
||||||
|
|
||||||
res.forEach((modifierGroup, idx) => {
|
|
||||||
const title = modifierGroup.category
|
|
||||||
const modifiers = modifierGroup.modifiers
|
|
||||||
|
|
||||||
const titleEl = document.createElement('h5')
|
|
||||||
titleEl.className = 'collapsible'
|
|
||||||
titleEl.innerText = title
|
|
||||||
|
|
||||||
const modifiersEl = document.createElement('div')
|
|
||||||
modifiersEl.classList.add('collapsible-content', 'editor-modifiers-leaf')
|
|
||||||
|
|
||||||
if (idx == 0) {
|
|
||||||
titleEl.className += ' active'
|
|
||||||
modifiersEl.style.display = 'block'
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiers.forEach(modObj => {
|
|
||||||
const modifierName = modObj.modifier
|
|
||||||
const modifierPreviews = modObj?.previews?.map(preview => `${modifierThumbnailPath}/${preview.path}`)
|
|
||||||
|
|
||||||
const modifierCard = createModifierCard(modifierName, modifierPreviews)
|
|
||||||
|
|
||||||
if(typeof modifierCard == 'object') {
|
|
||||||
modifiersEl.appendChild(modifierCard)
|
|
||||||
|
|
||||||
modifierCard.addEventListener('click', () => {
|
|
||||||
if (activeTags.map(x => x.name).includes(modifierName)) {
|
|
||||||
// remove modifier from active array
|
|
||||||
activeTags = activeTags.filter(x => x.name != modifierName)
|
|
||||||
modifierCard.classList.remove(activeCardClass)
|
|
||||||
|
|
||||||
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+'
|
|
||||||
} else {
|
|
||||||
// add modifier to active array
|
|
||||||
activeTags.push({
|
|
||||||
'name': modifierName,
|
|
||||||
'element': modifierCard.cloneNode(true),
|
|
||||||
'originElement': modifierCard,
|
|
||||||
'previews': modifierPreviews
|
|
||||||
})
|
|
||||||
|
|
||||||
modifierCard.classList.add(activeCardClass)
|
|
||||||
|
|
||||||
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '-'
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshTagsList()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let brk = document.createElement('br')
|
|
||||||
brk.style.clear = 'both'
|
|
||||||
modifiersEl.appendChild(brk)
|
|
||||||
|
|
||||||
let e = document.createElement('div')
|
|
||||||
e.appendChild(titleEl)
|
|
||||||
e.appendChild(modifiersEl)
|
|
||||||
|
|
||||||
editorModifierEntries.appendChild(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
createCollapsibles(editorModifierEntries)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('error fetching modifiers', e)
|
|
||||||
}
|
|
||||||
}
|
|
103
ui/media/js/utils.js
Normal file
103
ui/media/js/utils.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// https://gomakethings.com/finding-the-next-and-previous-sibling-elements-that-match-a-selector-with-vanilla-js/
|
||||||
|
function getNextSibling(elem, selector) {
|
||||||
|
// Get the next sibling element
|
||||||
|
var sibling = elem.nextElementSibling
|
||||||
|
|
||||||
|
// If there's no selector, return the first sibling
|
||||||
|
if (!selector) return sibling
|
||||||
|
|
||||||
|
// If the sibling matches our selector, use it
|
||||||
|
// If not, jump to the next sibling and continue the loop
|
||||||
|
while (sibling) {
|
||||||
|
if (sibling.matches(selector)) return sibling
|
||||||
|
sibling = sibling.nextElementSibling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCollapsibles(node) {
|
||||||
|
if (!node) {
|
||||||
|
node = document
|
||||||
|
}
|
||||||
|
|
||||||
|
let collapsibles = node.querySelectorAll(".collapsible")
|
||||||
|
collapsibles.forEach(function(c) {
|
||||||
|
let handle = document.createElement('span')
|
||||||
|
handle.className = 'collapsible-handle'
|
||||||
|
|
||||||
|
if (c.className.indexOf('active') !== -1) {
|
||||||
|
handle.innerHTML = '➖' // minus
|
||||||
|
} else {
|
||||||
|
handle.innerHTML = '➕' // plus
|
||||||
|
}
|
||||||
|
c.insertBefore(handle, c.firstChild)
|
||||||
|
|
||||||
|
c.addEventListener('click', function() {
|
||||||
|
this.classList.toggle("active")
|
||||||
|
let content = getNextSibling(this, '.collapsible-content')
|
||||||
|
if (content.style.display === "block") {
|
||||||
|
content.style.display = "none"
|
||||||
|
handle.innerHTML = '➕' // plus
|
||||||
|
} else {
|
||||||
|
content.style.display = "block"
|
||||||
|
handle.innerHTML = '➖' // minus
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this == advancedPanelHandle) {
|
||||||
|
let state = (content.style.display === 'block' ? 'true' : 'false')
|
||||||
|
localStorage.setItem(ADVANCED_PANEL_OPEN_KEY, state)
|
||||||
|
} else if (this == modifiersPanelHandle) {
|
||||||
|
let state = (content.style.display === 'block' ? 'true' : 'false')
|
||||||
|
localStorage.setItem(MODIFIERS_PANEL_OPEN_KEY, state)
|
||||||
|
} else if (this == negativePromptPanelHandle) {
|
||||||
|
let state = (content.style.display === 'block' ? 'true' : 'false')
|
||||||
|
localStorage.setItem(NEGATIVE_PROMPT_PANEL_OPEN_KEY, state)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function permute(arr) {
|
||||||
|
let permutations = []
|
||||||
|
let n = arr.length
|
||||||
|
let n_permutations = Math.pow(2, n)
|
||||||
|
for (let i = 0; i < n_permutations; i++) {
|
||||||
|
let perm = []
|
||||||
|
let mask = Number(i).toString(2).padStart(n, '0')
|
||||||
|
|
||||||
|
for (let idx = 0; idx < mask.length; idx++) {
|
||||||
|
if (mask[idx] === '1' && arr[idx].trim() !== '') {
|
||||||
|
perm.push(arr[idx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (perm.length > 0) {
|
||||||
|
permutations.push(perm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permutations
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/8212878
|
||||||
|
function millisecondsToStr(milliseconds) {
|
||||||
|
function numberEnding (number) {
|
||||||
|
return (number > 1) ? 's' : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
var temp = Math.floor(milliseconds / 1000)
|
||||||
|
var hours = Math.floor((temp %= 86400) / 3600)
|
||||||
|
var s = ''
|
||||||
|
if (hours) {
|
||||||
|
s += hours + ' hour' + numberEnding(hours) + ' '
|
||||||
|
}
|
||||||
|
var minutes = Math.floor((temp %= 3600) / 60)
|
||||||
|
if (minutes) {
|
||||||
|
s += minutes + ' minute' + numberEnding(minutes) + ' '
|
||||||
|
}
|
||||||
|
var seconds = temp % 60
|
||||||
|
if (!hours && minutes < 4 && seconds) {
|
||||||
|
s += seconds + ' second' + numberEnding(seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user