function gradioCustomJS() { console.log("gradioCustomJS Started") // MARK: berechne Helligkeit der Akzentfarbe function berechneHelligkeit(rgb) { const match = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/) if (!match) { throw new Error("Ungültiges Farbformat") } const r = parseInt(match[1]) / 255 const g = parseInt(match[2]) / 255 const b = parseInt(match[3]) / 255 const rLin = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4) const gLin = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4) const bLin = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4) const luminanz = 0.2126 * rLin + 0.7152 * gLin + 0.0722 * bLin return luminanz } // MARK: Textfarbe bestimmen function anpasseTextfarbe(farbe) { const luminanz = berechneHelligkeit(farbe) const textFarbe = luminanz > 0.4 ? "var(--neutral-950)" : "var(--neutral-50)" console.log("Luminanz: " + luminanz + " Text-Farbe: " + textFarbe) return textFarbe } const body = document.querySelector("body") body.className = "dark" // Catppuccin colors const rosewater = "245, 224, 220" const flamingo = "242, 205, 205" const pink = "245, 194, 231" const mauve = "203, 166, 247" const red = "243, 139, 168" const maroon = "235, 160, 172" const peach = "250, 179, 135" const yellow = "249, 226, 175" const green = "166, 227, 161" const teal = "148, 226, 213" const sky = "137, 220, 235" const sapphire = "116, 199, 236" const blue = "137, 180, 250" let colors = [rosewater, flamingo, pink, mauve, red, maroon, peach, yellow, green, teal, sky, sapphire, blue] let usedColor = `rgb(${colors[Math.floor(Math.random() * colors.length)]})` body.style.setProperty("--cat-rosewater", "rgb(" + rosewater + ")") body.style.setProperty("--cat-flamingo", "rgb(" + flamingo + ")") body.style.setProperty("--cat-pink", "rgb(" + pink + ")") body.style.setProperty("--cat-mauve", "rgb(" + mauve + ")") body.style.setProperty("--cat-red", "rgb(" + red + ")") body.style.setProperty("--cat-maroon", "rgb(" + maroon + ")") body.style.setProperty("--cat-peach", "rgb(" + peach + ")") body.style.setProperty("--cat-yellow", "rgb(" + yellow + ")") body.style.setProperty("--cat-green", "rgb(" + green + ")") body.style.setProperty("--cat-teal", "rgb(" + teal + ")") body.style.setProperty("--cat-sky", "rgb(" + sky + ")") body.style.setProperty("--cat-sapphire", "rgb(" + sapphire + ")") body.style.setProperty("--cat-blue", "rgb(" + blue + ")") body.style.setProperty("--primary-600", usedColor) body.style.setProperty("--primary-50", "color-mix(in srgb, var(--primary-600) 5%, white)") body.style.setProperty("--primary-100", "color-mix(in srgb, var(--primary-600) 10%, white)") body.style.setProperty("--primary-200", "color-mix(in srgb, var(--primary-600) 20%, white)") body.style.setProperty("--primary-300", "color-mix(in srgb, var(--primary-600) 60%, white)") body.style.setProperty("--primary-400", "color-mix(in srgb, var(--primary-600) 70%, white)") body.style.setProperty("--primary-500", "color-mix(in srgb, var(--primary-600) 80%, white)") body.style.setProperty("--primary-700", "color-mix(in srgb, var(--primary-600) 80%, black)") body.style.setProperty("--primary-800", "color-mix(in srgb, var(--primary-600) 65%, black)") body.style.setProperty("--primary-900", "color-mix(in srgb, var(--primary-600) 40%, black)") body.style.setProperty("--primary-950", "color-mix(in srgb, var(--primary-600) 30%, black)") body.style.setProperty("--button-primary-background-fill", "var(--primary-600)") body.style.setProperty("--button-primary-background-fill-hover", "var(--primary-500)") body.style.setProperty("--blur-value", "0px") body.style.setProperty("--text-color-by-luminance", anpasseTextfarbe(usedColor)) // MARK: Selectors & Elements const gradioApp = document.querySelector("gradio-app") const gradioContainer = document.querySelector("body > gradio-app > div.gradio-container") const dominantColorField = document.querySelector("#dominant_image_color > label > textarea") const outputImageElem = document.querySelector("#output_image > div.image-container.svelte-1p15vfy > button > div > img") const alertModalElem = document.createElement("div") const alertModalElemP = document.createElement("p") const alertModalElemI = document.createElement("i") alertModalElemI.className = "fas fa-exclamation-circle" const alertModalElemSpan = document.createElement("span") alertModalElemSpan.id = "alertModalText" const alertModalElemButton = document.createElement("button") alertModalElemButton.className = "lg primary run-btn svelte-cmf5ev" alertModalElemButton.id = "alertModalBtn" alertModalElemButton.textContent = "Ok" alertModalElemP.id = "alertModalP" alertModalElemP.append(alertModalElemI, alertModalElemSpan) alertModalElem.id = "alertModal" alertModalElem.style.display = "none" alertModalElem.append(alertModalElemP, alertModalElemButton) //alertModalElem.innerHTML = '

' gradioApp.appendChild(alertModalElem) alertModalElemButton.addEventListener("click", () => { oldText = alertModalElemSpan.textContent alertModalElemButton.disabled = true if (alertModalElemButton.textContent == "Noch mal?") { alertModalElemSpan.innerHTML = 'Na gut, noch mal.
Der "Ok" ... ne, der "Noch mal?" Button ändert nur diesen Text. 😉 In 10 Sekunden wird wieder die ursprüngliche Meldung gezeigt. Cool oder?' setTimeout(() => { alertModalElemSpan.textContent = oldText alertModalElemButton.disabled = false alertModalElemButton.textContent = "Noch mal?" }, 10000) } else if (alertModalElemButton.textContent == "Ok") { alertModalElemSpan.innerHTML = 'Der "Ok" Button ändert nur diesen Text. 🫢
In 6 Sekunden wird wieder die ursprüngliche Meldung gezeigt. Cool oder?' setTimeout(() => { alertModalElemSpan.textContent = oldText alertModalElemButton.disabled = false alertModalElemButton.textContent = "Noch mal?" }, 6000) } }) const prompt_input = document.querySelector("#prompt_input") prompt_input.setAttribute("autocomplete", "off") prompt_input.setAttribute("autocorrect", "off") prompt_input.setAttribute("autocapitalize", "off") prompt_input.setAttribute("spellcheck", "false") const switch_width_height = document.querySelector("#switch_width_height") const random_prompt_btn = document.querySelector("#random_prompt_btn") const switch_ratio_btns = document.querySelectorAll("#image_ratio_buttons label") // MARK: DOM Change Detection function onDominantImageColorChange(callback) { const observer = new MutationObserver(callback) observer.observe(document.querySelector("#dominant_image_color"), { childList: true, subtree: true, }) } function onImageRatioButtonsChange(callback) { const observer = new MutationObserver(callback) observer.observe(document.querySelector("#image_ratio_buttons"), { childList: true, subtree: true, }) } function onDomElemChange(selector) { return new Promise((resolve) => { const element = document.querySelector(selector) if (!element) { console.error(`Element nicht gefunden: ${selector}`) return } const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === "childList" || mutation.type === "attributes") { resolve(element) } }) }) observer.observe(element, { childList: true, subtree: true, attributes: true, }) // Wiederholt aufgerufen werden function watch() { observer.disconnect() observer.observe(element, { childList: true, subtree: true, attributes: true, }) setTimeout(watch, 100) } watch() }) } onDominantImageColorChange(() => { console.log("changed: " + document.querySelector("#dominant_image_color > label > textarea").value) if (document.querySelector("#dominant_image_color > label > textarea").value.match(/^rgb\((\d{1,3}),(\s\d{1,3}),(\s\d{1,3})\)$/) && document.querySelector("#output_image > div.image-container.svelte-1p15vfy > button > div > img").src) { document.querySelector("#output_image > div.image-container.svelte-1p15vfy > button > div > img").style.opacity = "0" document.querySelector("body > gradio-app > div").classList.add("fade-bg") document.querySelector("gradio-app").style.opacity = "0" setTimeout(() => { usedColor = document.querySelector("#dominant_image_color > label > textarea").value body.style.setProperty("--primary-600", document.querySelector("#dominant_image_color > label > textarea").value) body.style.setProperty("--text-color-by-luminance", anpasseTextfarbe(document.querySelector("#dominant_image_color > label > textarea").value)) gradioApp.classList.add("has-bg-image") body.style.setProperty("--bg-image-path", `url("${document.querySelector("#output_image > div.image-container.svelte-1p15vfy > button > div > img").src}")`) }, 400) setTimeout(() => { gradioApp.style.opacity = "1" document.querySelector("#output_image > div.image-container.svelte-1p15vfy > button > div > img").style.opacity = "1" document.querySelector("#dominant_image_color > label > textarea").value = "" }, 800) setTimeout(() => { //document.querySelector("body > gradio-app > div").classList.remove("fade-bg") }, 2000) } }) // MARK: SVGs winking_hand__emoji = '' random_prompt_btn.innerHTML = '' const enhance_prompt_btn = document.querySelector("#enhance_prompt_btn") enhance_prompt_btn.innerHTML = '' const run_btn = document.querySelector("#run_btn") run_btn.innerHTML = '' // switch_width_height.innerHTML = // '' const switch_width_height_inner = document.createElement("div") switch_width_height_inner.id = "switch_width_height_inner" switch_width_height_inner.setAttribute("data-aspect-ratio", "9-16") switch_width_height_inner.className = "hochformat" switch_width_height.append(switch_width_height_inner) const switch_width_height_btn_inner = document.querySelector("div#switch_width_height_inner") switch_width_height.addEventListener("click", () => { //switch_width_height_btn_inner.className = document.querySelector("#image_ratio_buttons > span").textContent.toLocaleLowerCase() }) switch_ratio_btns.forEach((_) => { _.querySelector("input").addEventListener("click", (e) => { switch_width_height_btn_inner.setAttribute("data-aspect-ratio", e.target.value.replace(":", "-").trim()) }) }) onImageRatioButtonsChange(() => { switch_width_height_btn_inner.className = document.querySelector("#image_ratio_buttons > span").textContent.toLocaleLowerCase() const selected_ratio = document.querySelector("#image_ratio_buttons label.selected input").value.replace(":", "-").trim() if (switch_width_height_btn_inner.getAttribute("data-aspect-ratio") != selected_ratio) { switch_width_height_btn_inner.setAttribute("data-aspect-ratio", selected_ratio) } }) // MARK: Element-Ready function function elementReady(selector) { return new Promise((resolve, reject) => { const el = document.querySelector(selector) if (el) { resolve(el) } new MutationObserver((mutationRecords, observer) => { Array.from(document.querySelectorAll(selector)).forEach((element) => { resolve(element) observer.disconnect() }) }).observe(document.documentElement, { childList: true, subtree: true, }) }) } // MARK: Mobile Check function istMobile() { // Überprüfen, ob das Gerät ein Touchscreen hat if ("ontouchstart" in window || (navigator.maxTouchPoints && window.innerWidth < 768)) { gradioContainer.classList.add("blur-container") body.style.setProperty("--blur-value", "12px") gradioApp.style.height = "calc(100vh - 120px)" alertModalElem.style.display = "" alertModalElemSpan.textContent = "Diese Seite ist nicht für mobile Geräte optimiert. Bitte besuche diese Seite von einem Desktop-Computer aus." } else if (window.innerWidth < 1024) { gradioContainer.classList.add("blur-container") body.style.setProperty("--blur-value", "12px") gradioApp.style.height = "calc(100vh - 120px)" alertModalElem.style.display = "" alertModalElemSpan.textContent = "Bildschirm Auflösung oder Fensterbreite zu gering. Bitte besuche diese Seite von einem Desktop-Computer aus." } else { gradioContainer.classList.remove("blur-container") body.style.setProperty("--blur-value", "0px") gradioApp.style.height = "" alertModalElem.style.display = "none" alertModalElemSpan.textContent = "" } } // MARK: Event Listeners window.addEventListener("resize", () => { console.log("Event Window resize.") istMobile() }) elementReady("body > gradio-app > div.gradio-container").then((element) => { console.log("Element exist: " + element) istMobile() }) return "Custom Gradio JS" }