diff --git a/css/ghostkwebb.css b/css/ghostkwebb.css new file mode 100644 index 0000000..e9edee4 --- /dev/null +++ b/css/ghostkwebb.css @@ -0,0 +1,442 @@ +/* Ghostkwebb Theme - Refined Clean Style */ + +/* Global Font and Reset */ +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + color: #e0e0e0; +} + +/* Sidebar - Clean Dark Mode */ +.w3-sidebar { + background-color: rgba(20, 20, 20, 0.95) !important; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: none !important; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); +} + +/* Main Settings Sidebar (#thesidebar) */ +#thesidebar { + top: 80px !important; + /* Position below the logo */ + left: 20px !important; + bottom: auto !important; + transform: none !important; + /* Remove vertical centering */ + height: auto !important; + max-height: calc(100vh - 100px); + /* Prevent overflow */ + overflow-y: auto; + /* Scroll if needed */ + border-radius: 20px; + background-color: rgba(25, 25, 25, 0.98) !important; + border: 1px solid rgba(255, 255, 255, 0.1) !important; + padding: 20px; + width: 360px !important; + z-index: 1000; +} + +#thesidebar>.w3-bar-item:first-child, +#themoodbar>.w3-bar-item:first-child, +#theposebar>.w3-bar-item:first-child { + display: none !important; +} + +/* Sidebar Items */ +.w3-bar-item { + transition: all 0.2s ease; +} + +/* Floating Bars (Mood and Pose) */ +#themoodbar, +#theposebar { + top: 80px !important; + bottom: auto !important; + transform: none !important; + height: auto !important; + max-height: calc(100vh - 100px); + border-radius: 24px; + + width: 60px !important; + min-width: 60px !important; + max-width: 60px !important; + padding: 12px 0 !important; + padding-left: 0 !important; + padding-right: 0 !important; + + overflow-x: hidden; + background-color: rgba(30, 30, 30, 0.85) !important; + border: 1px solid rgba(255, 255, 255, 0.08) !important; + + display: flex; + flex-direction: column; + align-items: center; +} + +#themoodbar { + left: 20px !important; +} + +#theposebar { + right: 20px !important; +} + +/* Sidebar Items Spacing */ +/* Sidebar Items Spacing */ +/* Sidebar Items Spacing */ +#themoodbar>div, +#theposebar>div { + margin-left: auto !important; + margin-right: auto !important; + margin-bottom: 16px !important; + + width: 44px !important; + height: 44px !important; + border-radius: 50% !important; + transition: background-color 0.2s; + box-sizing: border-box !important; + + display: grid !important; + place-items: center !important; + padding: 0 !important; + position: static !important; +} + +/* Specific selector to override inline styles */ +#themoodbar>div>img, +#theposebar>div>img, +#themoodbar img, +#theposebar img { + width: 28px !important; + height: 28px !important; + + /* Reset Absolute positioning - Grid handles it better */ + position: static !important; + transform: none !important; + + margin: 0 !important; + padding: 0 !important; + display: block !important; + border: none !important; + object-fit: contain !important; +} + +#themoodbar br, +#theposebar br { + display: none !important; +} + +/* Sidebar Animations */ +@keyframes slideInLeft { + from { + transform: translateX(-100%); + opacity: 0; + } + + to { + transform: translateX(0); + opacity: 1; + } +} + +@keyframes slideOutLeft { + from { + transform: translateX(0); + opacity: 1; + } + + to { + transform: translateX(-100%); + opacity: 0; + } +} + +.sidebar-open { + animation: slideInLeft 0.4s cubic-bezier(0.25, 0.8, 0.25, 1) forwards !important; +} + +.sidebar-close { + animation: slideOutLeft 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) forwards !important; +} + +#themoodbar>div:hover, +#theposebar>div:hover { + background-color: rgba(255, 255, 255, 0.15) !important; + /* Slightly stronger highlight */ +} + +/* Buttons - Minimalist */ +.w3-button { + background-color: rgba(255, 255, 255, 0.05) !important; + color: #f0f0f0 !important; + border-radius: 10px; + margin: 6px 0; + padding: 10px 16px !important; + transition: all 0.2s ease; + font-weight: 500; + border: 1px solid transparent; + text-align: left; +} + +.w3-button:hover { + background-color: rgba(255, 255, 255, 0.15) !important; + border-color: rgba(255, 255, 255, 0.2); + color: #ffffff !important; + transform: translateX(4px); +} + +.w3-button:active { + background-color: rgba(255, 255, 255, 0.1) !important; + transform: scale(0.98) translateX(4px); +} + +#thesidebar>button.w3-button { + background-color: rgba(255, 255, 255, 0.08) !important; + font-weight: 600; + letter-spacing: 0.5px; + border-left: 3px solid #007AFF; + /* Accent to mark as header */ + margin-top: 12px; + margin-bottom: 4px; + border-radius: 8px; + text-transform: uppercase; + font-size: 12px; + color: #bbb !important; +} + +#thesidebar>button.w3-button:hover { + background-color: rgba(255, 255, 255, 0.15) !important; + color: #fff !important; + transform: translateX(2px); +} + +/* Effect Keys and Config Keys (Dropdowns) - Clean Cards */ +div.effectkey, +div.confkey { + background-color: rgba(40, 40, 40, 0.6) !important; + border-radius: 8px; + margin: 8px 0; + padding: 12px 16px; + transition: all 0.2s ease; + border: 1px solid rgba(255, 255, 255, 0.05); + font-size: 14px; +} + +div.effectkey:hover, +div.confkey:hover { + background-color: rgba(60, 60, 60, 0.8) !important; + border-color: rgba(255, 255, 255, 0.2); +} + +/* Inputs - Sleek */ +input[type="text"], +input[type="number"], +select { + background-color: rgba(0, 0, 0, 0.5); + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 6px; + color: #fff; + padding: 8px 12px; + outline: none; + transition: border-color 0.2s, background-color 0.2s; + font-size: 13px; + width: 100%; + box-sizing: border-box; + margin-top: 6px; +} + +input[type="text"]:focus, +input[type="number"]:focus, +select:focus { + border-color: #007AFF; + background-color: rgba(0, 0, 0, 0.7); +} + +/* Range Sliders - Refined */ +input[type=range] { + -webkit-appearance: none; + background: transparent; + width: 100%; + margin: 14px 0; +} + +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 4px; + cursor: pointer; + background: rgba(255, 255, 255, 0.2); + border-radius: 2px; +} + +input[type=range]::-webkit-slider-thumb { + height: 16px; + width: 16px; + border-radius: 50%; + background: #007AFF; + cursor: pointer; + -webkit-appearance: none; + margin-top: -6px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.4); + transition: transform 0.1s; + border: 2px solid #1a1a1a; +} + +input[type=range]::-webkit-slider-thumb:hover { + transform: scale(1.15); + background: #298dff; +} + +/* Checkboxes */ +input[type="checkbox"] { + accent-color: #007AFF; + width: 16px; + height: 16px; + cursor: pointer; + margin-right: 10px; + vertical-align: middle; +} + +/* System Box (Logo) - Slide Out Animation */ +div.systembox { + background: rgba(20, 20, 20, 0.8); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + padding: 8px; + border-radius: 30px; + /* Pill shape */ + border: 1px solid rgba(255, 255, 255, 0.1); + transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); + display: flex; + align-items: center; + width: 50px; + /* Initial width (logo only) */ + overflow: hidden; + white-space: nowrap; + cursor: pointer; + position: absolute; + top: 20px; + left: 20px; + z-index: 1001; + /* Above sidebar */ +} + +div.systembox:hover { + width: 180px; + /* Expanded width */ + background: rgba(40, 40, 40, 0.95); + border-color: rgba(255, 255, 255, 0.25); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); +} + +#systemimg { + height: 34px !important; + /* Slightly smaller */ + width: 34px; + min-width: 34px; + transition: transform 0.4s ease; + filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3)); +} + +div.systembox:hover #systemimg { + transform: rotate(360deg); + /* Rotate on hover */ +} + +/* FIX: Logo Alignment - Perfect vertical centering */ +text.systemtext { + font-weight: 500; + letter-spacing: 0.5px; + color: #ffffff; + font-size: 16px; + margin-left: 12px; + opacity: 0; + transform: translateX(-20px); + transition: all 0.3s ease 0.1s; + /* Delay slightly */ + display: block; + /* Ensure block behavior for alignment */ + line-height: 34px; + /* Match logo height */ + height: 34px; + margin-top: 0; + padding-top: 2px; + /* Optical adjustment */ +} + +div.systembox:hover text.systemtext { + opacity: 1; + transform: translateX(0); +} + +/* Tooltips - Clean */ +.w3-tooltip { + position: relative; + display: inline-block; +} + +.w3-text.w3-tag { + background-color: #1a1a1a !important; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 6px; + padding: 6px 10px; + font-size: 12px; + color: #eee; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); +} + +/* Scrollbar - Minimal */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.1); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.2); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.4); +} + +/* Animations - Subtle */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.w3-bar-item { + animation: fadeIn 0.3s ease-out forwards; +} + +/* Alert Box */ +div.alertbox { + background: rgba(200, 40, 40, 0.95); + backdrop-filter: blur(10px); + border-radius: 12px; + padding: 12px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + border: 1px solid rgba(255, 255, 255, 0.15); + bottom: 20px; + right: 20px; +} + +text.alerttext { + background-color: transparent !important; + color: #fff; + font-size: 14px; + font-weight: 500; +} \ No newline at end of file diff --git a/css/openlive3d.css b/css/openlive3d.css index 6663784..e127b19 100644 --- a/css/openlive3d.css +++ b/css/openlive3d.css @@ -4,6 +4,7 @@ canvas.vrm { left: 0%; z-index: -1; } + div.bgimg { position: absolute; background-size: cover; @@ -13,12 +14,14 @@ div.bgimg { height: 100%; z-index: -3; } + div.systembox { position: absolute; top: 5px; left: 7px; z-index: 3; } + div.alertbox { position: absolute; bottom: 7px; @@ -26,6 +29,7 @@ div.alertbox { z-index: 4; display: none; } + div.loadbox { position: absolute; top: 0px; @@ -35,12 +39,14 @@ div.loadbox { z-index: 5; background-color: #ffff; } + div.webcambox { position: absolute; top: 0px; left: 0px; z-index: -5; } + div.effectkey { color: #fff; cursor: pointer; @@ -48,6 +54,7 @@ div.effectkey { background-color: #000a; padding-left: 16px; } + div.confkey { color: #fff; cursor: pointer; @@ -55,6 +62,7 @@ div.confkey { background-color: #000a; padding-left: 16px; } + text.systemtext { color: #FFFFFF00; position: absolute; @@ -65,6 +73,7 @@ text.systemtext { cursor: pointer; user-select: none; } + text.alerttext { color: #FFFFFFFF; background-color: #00000088; @@ -77,6 +86,7 @@ text.alerttext { font-size: 16px; user-select: none; } + text.loading { position: absolute; top: 5px; @@ -85,6 +95,7 @@ text.loading { font-size: 28px; user-select: none; } + span { position: absolute; left: -10px; @@ -93,11 +104,13 @@ span { width: 250px; z-index: 6; } + div.vrm { position: absolute; top: 0%; left: 0%; } + canvas.backgroundeffect { position: absolute; top: 0%; @@ -105,10 +118,21 @@ canvas.backgroundeffect { z-index: -2; pointer-events: none; } + canvas.foregroundeffect { position: absolute; top: 0%; left: 0%; z-index: 1; pointer-events: none; +} + +#themoodbar>div, +#theposebar>div { + margin-bottom: 20px; +} + +#themoodbar img, +#theposebar img { + margin-left: 12px; } \ No newline at end of file diff --git a/js/config/config-manager.js b/js/config/config-manager.js index 75d252d..95298b7 100644 --- a/js/config/config-manager.js +++ b/js/config/config-manager.js @@ -111,7 +111,8 @@ let defaultConfig = { 'IN_MOOD_SELECT': false, 'IN_TRACKING_MODE_SELECT': false, 'TEST_MOBILE_ENTRY': false, - 'TEST_SAFARI_ENTRY': false + 'TEST_SAFARI_ENTRY': false, + 'UI_THEME': "OpenLive3D" }; function getDefaultCMV(key) { @@ -330,7 +331,7 @@ function getBinaryCM() { } function getSelectCM() { - return ['LANGUAGE', 'TRACKING_MODE']; + return ['LANGUAGE', 'TRACKING_MODE', 'UI_THEME']; } function getSideBoxes() { @@ -574,6 +575,11 @@ function getConfigModifiers() { 'range': [-1, 1] }], 'UI': [{ + 'key': 'UI_THEME', + 'title': 'UI Theme', + 'describe': 'Select the UI theme.', + 'valid': ["OpenLive3D", "Ghostkwebb"] + }, { 'key': 'UI_TRACKING_MODE_COLLAPSE', 'title': 'Collapse Tracking Mode UI', 'describe': 'Change the UI selection framework format', diff --git a/js/gui/gui-layout.js b/js/gui/gui-layout.js index 12ea260..10481f4 100644 --- a/js/gui/gui-layout.js +++ b/js/gui/gui-layout.js @@ -3,26 +3,43 @@ let sidebar = document.getElementById("thesidebar"); let moodbar = document.getElementById("themoodbar"); let posebar = document.getElementById("theposebar"); let systembox = document.getElementById("systembox"); -systembox.onclick = function() { +systembox.onclick = function () { console.log("click SYSTEM_IMG"); - if (sidebar.style.display == "none") { + if (sidebar.style.display == "none" || sidebar.classList.contains('sidebar-close')) { + // Open Sidebar sidebar.style.display = "block"; + sidebar.classList.remove('sidebar-close'); + sidebar.classList.add('sidebar-open'); + + // Hide other bars moodbar.style.display = "none"; posebar.style.display = "none"; } else { - sidebar.style.display = "none"; - moodbar.style.display = "block"; - posebar.style.display = "block"; + // Close Sidebar with Animation + sidebar.classList.remove('sidebar-open'); + sidebar.classList.add('sidebar-close'); + + // Wait for animation to finish before hiding + setTimeout(() => { + if (sidebar.classList.contains('sidebar-close')) { + sidebar.style.display = "none"; + sidebar.classList.remove('sidebar-close'); + + // Show other bars + moodbar.style.display = "block"; + posebar.style.display = "block"; + } + }, 300); // Match animation duration } if (checkCameraPaused()) { playCapture(); } }; let systemtext = document.getElementById("systemtext"); -systembox.onmouseover = function() { +systembox.onmouseover = function () { systemtext.style.color = "#FFFFFFFF"; }; -systembox.onmouseout = function() { +systembox.onmouseout = function () { if (sidebar.style.display == "none") { systemtext.style.color = "#FFFFFF00"; } @@ -136,7 +153,7 @@ function createBGImageLayout(group) { let file = item.files[0]; if (file) { let reader = new FileReader(); - reader.onloadend = function() { + reader.onloadend = function () { setCMV("BG_UPLOAD", "url(" + reader.result + ")"); setBackGround(); } @@ -149,7 +166,7 @@ function createBGImageLayout(group) { let cancelitem = document.createElement("input"); cancelitem.setAttribute("type", "button"); cancelitem.setAttribute("value", "Remove Image"); - cancelitem.onclick = function() { + cancelitem.onclick = function () { item.value = ""; setCMV("BG_UPLOAD", ""); setBackGround(); @@ -178,25 +195,25 @@ let songList = [] function updateMusicList() { const musicList = document.getElementById("musiclist") - musicList.innerHTML = "" - + musicList.innerHTML = "" + songList.forEach((music, index) => { const listItem = document.createElement('div') //Box listItem.className = "music-item" - listItem.style.display = "flex" - listItem.style.alignItems = "center" - + listItem.style.display = "flex" + listItem.style.alignItems = "center" + //decode - const arrayBuffer = music.data - const blob = new Blob([arrayBuffer], { type: 'audio/mp3' }) - const url = URL.createObjectURL(blob) + const arrayBuffer = music.data + const blob = new Blob([arrayBuffer], { type: 'audio/mp3' }) + const url = URL.createObjectURL(blob) //assign url to new audio object - const audio = new Audio(url) - audio.controls = true + const audio = new Audio(url) + audio.controls = true audio.style.height = "28.5px" listItem.appendChild(audio) - + //element const deleteBtn = document.createElement('button') deleteBtn.innerText = getL('Delete') @@ -220,6 +237,7 @@ function updateMusicList() { } function createLayout() { + updateTheme(); setBackGround(); // vrm loading button @@ -231,7 +249,7 @@ function createLayout() { vrmbtn.setAttribute("type", "file"); vrmbtn.setAttribute("accept", ".vrm"); vrmbtn.style.display = "none"; - vrmbtn.onchange = function() { + vrmbtn.onchange = function () { if ('files' in vrmbtn && vrmbtn.files.length > 0) { let files = vrmbtn.files; let file = files[0]; @@ -250,7 +268,7 @@ function createLayout() { vrmbtnkey.className = "confkey"; vrmbtnkey.id = "vrmbtnkey"; vrmbtnkey.innerHTML = "ᐅ " + getL("Upload VRM Model"); - vrmbtnkey.onclick = function() { + vrmbtnkey.onclick = function () { vrmbtn.click(); } vrmbox.appendChild(vrmbtnkey); @@ -263,7 +281,7 @@ function createLayout() { vrmurlbox.className = "w3-hide"; vrmurlbox.id = "vrmurlbox"; vrmurlbox.style.color = "white"; - vrmurlkey.onclick = function() { + vrmurlkey.onclick = function () { if (vrmurlbox.className == "w3-hide") { vrmurlkey.innerHTML = "ᐁ " + getL("Set VRM URL"); vrmurlbox.className = ""; @@ -280,7 +298,7 @@ function createLayout() { let vrmurlsubmit = document.createElement("input"); vrmurlsubmit.setAttribute("type", "button"); vrmurlsubmit.setAttribute("value", getL("Set URL")); - vrmurlsubmit.onclick = function() { + vrmurlsubmit.onclick = function () { loadVRM(vrmurlinput.value); setCMV("MODEL", vrmurlinput.value); setCMV("CUSTOM_MODEL", true); @@ -291,7 +309,7 @@ function createLayout() { let videoctlbtn = document.getElementById("videoctlbutton"); videoctlbtn.innerHTML = getL("Video Control"); let videoselect = document.getElementById("videoselect"); - videoselect.onchange = function() { + videoselect.onchange = function () { console.log("set camera: ", videoselect.value); setVideoStream(videoselect.value); } @@ -327,13 +345,13 @@ function createLayout() { effectbox.innerHTML = ""; //all effects let alleffects = getAllEffects(); - Object.keys(alleffects).forEach(function(key) { + Object.keys(alleffects).forEach(function (key) { let effectkey = document.createElement('div'); effectkey.className = "effectkey"; effectkey.id = "effectkey_" + key; effectkey.innerHTML = "ᐅ " + getL(key); - effectkey.onclick = function() { - Object.keys(alleffects).forEach(function(otherkey) { + effectkey.onclick = function () { + Object.keys(alleffects).forEach(function (otherkey) { let tmpkey = document.getElementById("effectkey_" + otherkey); let tmpgroup = document.getElementById("effectgroup_" + otherkey); if (otherkey == key && tmpgroup.className == "w3-margin w3-hide") { @@ -378,12 +396,12 @@ function createLayout() { itemcheck.id = effectitem['key'] + "_box"; itemcheck.setAttribute("type", "checkbox"); itemcheck.checked = false; - itemcheck.onclick = function() { + itemcheck.onclick = function () { if (itemcheck.checked) { effectitem['enableEffect'](); itemdiv.style.display = "block"; } else { - effectitem['disableEffect'](); + effectitem['disableEffect'](); itemdiv.style.display = "none"; } } @@ -392,7 +410,7 @@ function createLayout() { itemdiv.style.display = "none"; effectgroup.appendChild(itemdiv); if (effectitem['parameters']) { - Object.keys(effectitem['parameters']).forEach(function(parameter) { + Object.keys(effectitem['parameters']).forEach(function (parameter) { let partext = document.createElement('text'); partext.className = "w3-tooltip"; partext.style.color = "#fff"; @@ -403,7 +421,7 @@ function createLayout() { let parColor = document.createElement('input'); parColor.setAttribute("type", "color"); parColor.setAttribute("value", effectitem['parameters'][parameter]); - parColor.onchange = function() { + parColor.onchange = function () { console.log(parameter, parColor.value); effectitem['parameters'][parameter] = parColor.value; }; @@ -418,7 +436,7 @@ function createLayout() { let setrange = parArr[2] - parArr[1]; let setvalue = (parArr[0] - parArr[1]) * 1000 / setrange; parrange.setAttribute("value", setvalue); - parrange.onchange = function() { + parrange.onchange = function () { let newvalue = Math.floor(parrange.value / 1000 * setrange + parArr[1]); parval.value = newvalue; parval.onchange(); @@ -428,11 +446,11 @@ function createLayout() { parval.style.textAlign = "right"; parval.style.width = "100px"; parval.value = parArr[0]; - parval.onchange = function() { + parval.onchange = function () { console.log(parameter, parval.value); if (parval.value < parArr[1]) { parval.value = parArr[1]; - } else if (parval.value < parArr[2]) {} else { + } else if (parval.value < parArr[2]) { } else { parval.value = parArr[2]; } let newvalue = Math.floor((parval.value - parArr[1]) * 1000 / setrange); @@ -451,49 +469,49 @@ function createLayout() { //music let songCounter = 0; let musicboxbtn = document.getElementById("musicboxbutton") - musicboxbtn.innerHTML = getL("Music"); - let musicbox = document.getElementById("musicbox") - musicbox.innerHTML = "" + musicboxbtn.innerHTML = getL("Music"); + let musicbox = document.getElementById("musicbox") + musicbox.innerHTML = "" let musicbtn = document.createElement('input') musicbtn.setAttribute("type", "file") musicbtn.setAttribute("accept", ".mp3") musicbox.appendChild(musicbtn) - musicbtn.onchange = function() { + musicbtn.onchange = function () { if (musicbtn.files.length > 0) { let file = musicbtn.files[0] const reader = new FileReader() - reader.onload = function(event) { + reader.onload = function (event) { const arrayBuffer = event.target.result songCounter++ - const song = {id: songCounter, name: file.name, data: arrayBuffer } + const song = { id: songCounter, name: file.name, data: arrayBuffer } songList.push(song) - addSong(song) - updateMusicList() + addSong(song) + updateMusicList() } reader.readAsArrayBuffer(file) - musicbtn.value = '' + musicbtn.value = '' } } musicbox.appendChild(musicbtn) let musicList = document.createElement('div') musicList.id = "musiclist" musicbox.appendChild(musicList) - openIndex() - + openIndex() + // config modifier let confbox = document.getElementById("confbox"); confbox.innerHTML = ""; let confmodifiers = getConfigModifiers(); - Object.keys(confmodifiers).forEach(function(key) { + Object.keys(confmodifiers).forEach(function (key) { confmodifier = confmodifiers[key]; let confkey = document.createElement('div'); confkey.className = "confkey"; confkey.id = "confkey_" + key; confkey.innerHTML = "ᐅ " + getL(key); - confkey.onclick = function() { - Object.keys(confmodifiers).forEach(function(otherkey) { + confkey.onclick = function () { + Object.keys(confmodifiers).forEach(function (otherkey) { let tmpkey = document.getElementById("confkey_" + otherkey); let tmpgroup = document.getElementById("confgroup_" + otherkey); if (otherkey == key && tmpgroup.className == "w3-margin w3-hide") { @@ -564,6 +582,8 @@ function createLayout() { createLayout(); } else if (configitem['key'] == "TRACKING_MODE") { setTrackingModeSelect(itemselect.value); + } else if (configitem['key'] == "UI_THEME") { + updateTheme(); } }; confgroup.appendChild(itemselect); @@ -574,7 +594,7 @@ function createLayout() { let setrange = configitem['range'][1] - configitem['range'][0]; let setvalue = (getCMV(configitem['key']) - configitem['range'][0]) * 1000 / setrange; item.setAttribute("value", setvalue); - item.onchange = function() { + item.onchange = function () { let newvalue = item.value / 1000 * setrange + configitem['range'][0]; itemval.value = newvalue; itemval.onchange(); @@ -583,11 +603,11 @@ function createLayout() { itemval.style.textAlign = "right"; itemval.style.width = "100px"; itemval.value = getCMV(configitem['key']); - itemval.onchange = function() { + itemval.onchange = function () { console.log(configitem['key'], itemval.value); if (itemval.value < configitem['range'][0]) { itemval.value = configitem['range'][0]; - } else if (itemval.value < configitem['range'][1]) {} else { + } else if (itemval.value < configitem['range'][1]) { } else { itemval.value = configitem['range'][1]; } let newvalue = (itemval.value - configitem['range'][0]) * 1000 / setrange; @@ -615,7 +635,7 @@ function createLayout() { loggroup.className = "w3-margin w3-hide"; loggroup.id = "logbox_" + key; loggroup.style.color = "white"; - logkey.onclick = function() { + logkey.onclick = function () { if (loggroup.className == "w3-margin w3-hide") { logkey.innerHTML = "ᐁ " + getL(key); loggroup.className = "w3-margin"; @@ -636,7 +656,7 @@ function createLayout() { let exportVRMRotateButton = document.createElement("input"); exportVRMRotateButton.setAttribute("type", "button"); exportVRMRotateButton.setAttribute("value", getL("Export Pose & Expression")); - exportVRMRotateButton.onclick = function() { + exportVRMRotateButton.onclick = function () { let exportJSON = { "metaVersion": getMetaVersion(), "rotate": exportRotate(), @@ -649,7 +669,7 @@ function createLayout() { dlAnchorElem.click(); dlAnchorElem.remove(); } - extralogkey.onclick = function() { + extralogkey.onclick = function () { if (extraloggroup.className == "w3-margin w3-hide") { extralogkey.innerHTML = "ᐁ extra"; extraloggroup.className = "w3-margin"; @@ -730,8 +750,8 @@ function createMoodLayout() { handobj.src = "asset/hand/" + trackingmode + "-2.png"; handobj.style.width = "30px"; handobj.style.cursor = "pointer"; - handobj.style.marginLeft = "12px"; - handobj.onclick = function() { + // handobj.style.marginLeft = "12px"; // REMOVED: Causes alignment issues + handobj.onclick = function () { if (getCMV("IN_TRACKING_MODE_SELECT") || !getCMV("UI_TRACKING_MODE_COLLAPSE")) { setCMV("TRACKING_MODE", trackingmode); @@ -743,8 +763,8 @@ function createMoodLayout() { } } handdiv.appendChild(handobj); - handdiv.appendChild(document.createElement("br")); - handdiv.appendChild(document.createElement("br")); + // handdiv.appendChild(document.createElement("br")); // REMOVED: Causes layout issues + // handdiv.appendChild(document.createElement("br")); // REMOVED: Causes layout issues posebar.appendChild(handdiv); if (i == availableTrackingMode.length - 1) { @@ -767,8 +787,8 @@ function createMoodLayout() { moodobj.src = "asset/mood/" + mood + ".png"; moodobj.style.width = "30px"; moodobj.style.cursor = "pointer"; - moodobj.style.marginLeft = "12px"; - moodobj.onclick = function() { + // moodobj.style.marginLeft = "12px"; // REMOVED: Causes alignment issues + moodobj.onclick = function () { if (getCMV("IN_MOOD_SELECT") || !getCMV("UI_MOOD_COLLAPSE")) { setCMV("IN_MOOD_SELECT", false); @@ -780,8 +800,8 @@ function createMoodLayout() { } } mooddiv.appendChild(moodobj); - mooddiv.appendChild(document.createElement("br")); - mooddiv.appendChild(document.createElement("br")); + // mooddiv.appendChild(document.createElement("br")); // REMOVED: Causes layout issues + // mooddiv.appendChild(document.createElement("br")); // REMOVED: Causes layout issues moodbar.appendChild(mooddiv); } @@ -790,7 +810,7 @@ function createMoodLayout() { } } - moodbar.onmouseout = function(e) { + moodbar.onmouseout = function (e) { if (e.target && e.relatedTarget && !(e.target.id[7] == "_" && e.relatedTarget.id[7] == "_" && e.target.id.slice(0, 4) == e.relatedTarget.id.slice(0, 4))) { @@ -930,7 +950,7 @@ function drawLandmark(landmark) { } else { dbg.scale(getCMV('CANVAS_RATIO'), getCMV('CANVAS_RATIO')); } - Object.keys(landmark).forEach(function(key) { + Object.keys(landmark).forEach(function (key) { for (let i = 0; i < landmark[key].length; i++) { let p = landmark[key][i]; dbg.fillStyle = MARKCOLOR[key]; @@ -951,7 +971,7 @@ function printLog(keys) { let logbox = document.getElementById("logbox_" + ikey); logbox.innerHTML = ''; if (keys[ikey]) { - Object.keys(keys[ikey]).forEach(function(key) { + Object.keys(keys[ikey]).forEach(function (key) { let jsonItem = document.createElement('text'); jsonItem.innerHTML = getL(key) + ": " + Math.floor(keys[ikey][key] * 1000) / 1000 + "
"; jsonItem.style.color = "white"; @@ -1029,7 +1049,7 @@ function drawSafari() { let tmp1 = document.createElement('button'); tmp1.style.color = 'red'; tmp1.innerHTML = getL("Enable OpenLive3D Safari Version!"); - tmp1.onclick = function() { + tmp1.onclick = function () { console.log("Enable Safari Parameters!"); setCMV("MULTI_THREAD", false); setCMV("TEST_SAFARI_ENTRY", true); @@ -1105,3 +1125,15 @@ function displayObj(target) { obj.style.display = "none"; } } + +function updateTheme() { + let theme = getCMV("UI_THEME"); + let ghostkwebbTheme = document.getElementById("theme-ghostkwebb"); + if (ghostkwebbTheme) { + if (theme === "Ghostkwebb") { + ghostkwebbTheme.disabled = false; + } else { + ghostkwebbTheme.disabled = true; + } + } +}