From b2dbb4dbcf846d1ca63b399873640926b2cf1735 Mon Sep 17 00:00:00 2001 From: MellDa Date: Tue, 19 Aug 2025 16:55:11 +0900 Subject: [PATCH 1/2] feat: change disc image based on turn direction this may break original disc image setting --- iidxwidget-app/main.js | 4 +- .../renderer/settings/settings.html | 16 +++-- iidxwidget-app/renderer/settings/settings.js | 69 ++++++++++++++----- iidxwidget-app/renderer/widget/index.js | 39 ++++++++--- 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/iidxwidget-app/main.js b/iidxwidget-app/main.js index 9f4a909..7b85546 100644 --- a/iidxwidget-app/main.js +++ b/iidxwidget-app/main.js @@ -38,7 +38,8 @@ const defaultSettings = { widget: { infoPosition: "bottom", buttonLayout: "1P", - discImagePath: null, + upDiscImagePath: null, + downDiscImagePath: null, showPromoBox: false, GlobalReleaseMALength: 200, PerButtonMALength: 200, @@ -292,7 +293,6 @@ ipcMain.handle('save-user-image', async (event, sourcePath) => { const ip = require('ip'); const hostAddress = ip.address(); // 예: 192.168.0.13 const publicUrl = `http://${hostAddress}:${settings.serverPort}/userImages/${fileName}`; - settings.widget.discImagePath = publicUrl; fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2)); return publicUrl; // ✅ 여기 수정! diff --git a/iidxwidget-app/renderer/settings/settings.html b/iidxwidget-app/renderer/settings/settings.html index a38c013..c2b3c70 100644 --- a/iidxwidget-app/renderer/settings/settings.html +++ b/iidxwidget-app/renderer/settings/settings.html @@ -81,12 +81,20 @@
- +
- - + +
- + +
+
+ +
+ + +
+
diff --git a/iidxwidget-app/renderer/settings/settings.js b/iidxwidget-app/renderer/settings/settings.js index bb02462..c097659 100644 --- a/iidxwidget-app/renderer/settings/settings.js +++ b/iidxwidget-app/renderer/settings/settings.js @@ -1,5 +1,5 @@ -let uploadedDiscImagePath = null; -let removeDiscImage = false; +let uploadedUpDiscImagePath = null; +let uploadedDownDiscImagePath = null; document.getElementById('cancel-button').addEventListener('click', () => { window.close(); @@ -56,7 +56,8 @@ document.getElementById('save-button').addEventListener('click', async () => { widget: { infoPosition, buttonLayout, - discImagePath: uploadedDiscImagePath, + upDiscImagePath: uploadedUpDiscImagePath, + downDiscImagePath: uploadedDownDiscImagePath, showPromoBox, globalMALength, perButtonMALength, @@ -125,13 +126,19 @@ function toggleKeyMappingUI(profile) { document.getElementById('color-fontColor').value = mergedColors.fontColor; document.getElementById('color-activeColor').value = mergedColors.activeColor; - uploadedDiscImagePath = settings.widget?.discImagePath || null; - removeDiscImage = false; + uploadedUpDiscImagePath = settings.widget?.upDiscImagePath || null; + uploadedDownDiscImagePath = settings.widget?.downDiscImagePath || null; - if (uploadedDiscImagePath) { - const previewImg = document.getElementById('disc-preview'); - previewImg.src = uploadedDiscImagePath; - previewImg.style.display = 'block'; + if (uploadedUpDiscImagePath) { + const upDiscPreviewImg = document.getElementById('up-disc-preview'); + upDiscPreviewImg.src = uploadedUpDiscImagePath; + upDiscPreviewImg.style.display = 'block'; + } + + if (uploadedDownDiscImagePath) { + const downDiscPreviewImg = document.getElementById('down-disc-preview'); + downDiscPreviewImg.src = uploadedDownDiscImagePath; + downDiscPreviewImg.style.display = 'block'; } bindColorPreview('color-background', 'preview-background'); @@ -167,7 +174,7 @@ document.querySelectorAll('#key-mapping-table input').forEach(input => { }); }); -document.getElementById('disc-image-upload').addEventListener('change', async (e) => { +document.getElementById('up-disc-image-upload').addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; @@ -175,27 +182,53 @@ document.getElementById('disc-image-upload').addEventListener('change', async (e const savedPath = await window.electronAPI.saveUserImage(filePath); if (savedPath) { - uploadedDiscImagePath = savedPath; - removeDiscImage = false; + uploadedUpDiscImagePath = savedPath; - const previewImg = document.getElementById('disc-preview'); + const previewImg = document.getElementById('up-disc-preview'); previewImg.src = savedPath; previewImg.style.display = 'block'; } }); -document.getElementById('delete-disc-button').addEventListener('click', () => { - uploadedDiscImagePath = null; - removeDiscImage = true; +document.getElementById('delete-up-disc-button').addEventListener('click', () => { + uploadedUpDiscImagePath = null; - const previewImg = document.getElementById('disc-preview'); + const previewImg = document.getElementById('up-disc-preview'); previewImg.src = ''; previewImg.style.display = 'none'; // 파일 선택 input 초기화 - document.getElementById('disc-image-upload').value = ''; + document.getElementById('up-disc-image-upload').value = ''; }); +document.getElementById('down-disc-image-upload').addEventListener('change', async (e) => { + const file = e.target.files[0]; + if (!file) return; + + const filePath = file.path; + const savedPath = await window.electronAPI.saveUserImage(filePath); + + if (savedPath) { + uploadedDownDiscImagePath = savedPath; + + const previewImg = document.getElementById('down-disc-preview'); + previewImg.src = savedPath; + previewImg.style.display = 'block'; + } +}); + +document.getElementById('delete-down-disc-button').addEventListener('click', () => { + uploadedDownDiscImagePath = null; + + const previewImg = document.getElementById('down-disc-preview'); + previewImg.src = ''; + previewImg.style.display = 'none'; + + // 파일 선택 input 초기화 + document.getElementById('down-disc-image-upload').value = ''; +}); + + function bindColorPreview(inputId, previewId) { const input = document.getElementById(inputId); const preview = document.getElementById(previewId); diff --git a/iidxwidget-app/renderer/widget/index.js b/iidxwidget-app/renderer/widget/index.js index 15b3d45..d9ecfd3 100644 --- a/iidxwidget-app/renderer/widget/index.js +++ b/iidxwidget-app/renderer/widget/index.js @@ -15,6 +15,10 @@ let keyTimestamps = []; let globalMALength = 200; let perButtonMALength = 200; +let upDiscImagePath = null; +let downDiscImagePath = null; +let isLatestDiscDirectionUp = false; + const disc = document.getElementById("disc"); const upperIndicator = document.getElementById("upper-indicator"); const lowerIndicator = document.getElementById("lower-indicator"); @@ -39,7 +43,12 @@ function startUptimeTimer() { function rotateDisc(delta) { discRotation -= delta * 2.5; disc.style.transform = `translate(-50%, -50%) rotate(${discRotation}deg)`; - updateBorders(delta); +} + +function changeDiscImage(delta) { + if (delta === 0) return; + if (is2PMode) delta = -delta; + applyDiscImage(delta > 0); } function updateBorders(delta) { @@ -116,20 +125,29 @@ function updateKPSDisplay() { } setInterval(updateKPSDisplay, 100); -function applyDiscImage(imagePath) { +function applyDiscImage(isUp) { const img = document.getElementById('disc-image'); const needle = document.getElementById('disc-needle'); if (!img || !needle) return; + if (isUp == isLatestDiscDirectionUp) return; - if (!imagePath) { - img.src = ''; - img.style.display = 'none'; - needle.style.display = 'block'; // 기본 bar 보이기 - } else { - img.src = imagePath; + if (isUp) { + if (!upDiscImagePath) { + img.src = ''; + img.style.display = 'none'; + needle.style.display = 'block'; // 기본 bar 보이기 + } else { + img.src = upDiscImagePath; + img.style.display = 'block'; + needle.style.display = 'none'; // 이미지 있으면 bar 숨기기 + } + isLatestDiscDirectionUp = true; + } else if (downDiscImagePath) { + img.src = downDiscImagePath; img.style.display = 'block'; needle.style.display = 'none'; // 이미지 있으면 bar 숨기기 + isLatestDiscDirectionUp = false; } } @@ -142,6 +160,7 @@ function handleData(data) { let delta = (newValue - lastDiscValue + 256) % 256; if (delta > 127) delta -= 256; rotateDisc(delta); + changeDiscImage(delta); updateBorders(delta); } lastDiscValue = newValue; @@ -208,7 +227,9 @@ function applyButtonLayout(layout) { if (settings?.widget) { applyReleaseContainerSettings(settings.widget.infoPosition || 'bottom'); applyButtonLayout(settings.widget.buttonLayout || '1P'); - applyDiscImage(settings?.widget?.discImagePath); + upDiscImagePath = settings.widget.upDiscImagePath; + downDiscImagePath = settings.widget.downDiscImagePath; + applyDiscImage(true); applyPromoBox(settings); globalMALength = settings.widget.globalMALength || 200; perButtonMALength = settings.widget.perButtonMALength || 200; From 2cd6ededb7600efc30269f0e3de739f03dace5d0 Mon Sep 17 00:00:00 2001 From: MellDa Date: Tue, 19 Aug 2025 17:45:46 +0900 Subject: [PATCH 2/2] refactor: update disc image change logic using two disc elements instead of changing image src --- iidxwidget-app/renderer/widget/index.html | 3 +- iidxwidget-app/renderer/widget/index.js | 77 ++++++++++++++--------- iidxwidget-app/renderer/widget/style.css | 2 +- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/iidxwidget-app/renderer/widget/index.html b/iidxwidget-app/renderer/widget/index.html index 79c547c..2d04055 100644 --- a/iidxwidget-app/renderer/widget/index.html +++ b/iidxwidget-app/renderer/widget/index.html @@ -18,7 +18,8 @@
-  +  +
diff --git a/iidxwidget-app/renderer/widget/index.js b/iidxwidget-app/renderer/widget/index.js index d9ecfd3..aa6ae53 100644 --- a/iidxwidget-app/renderer/widget/index.js +++ b/iidxwidget-app/renderer/widget/index.js @@ -15,11 +15,12 @@ let keyTimestamps = []; let globalMALength = 200; let perButtonMALength = 200; -let upDiscImagePath = null; -let downDiscImagePath = null; -let isLatestDiscDirectionUp = false; +let isLatestDiscDirectionUp = true; const disc = document.getElementById("disc"); +const upImg = document.getElementById('up-disc-image'); +const downImg = document.getElementById('down-disc-image'); +const needle = document.getElementById('disc-needle'); const upperIndicator = document.getElementById("upper-indicator"); const lowerIndicator = document.getElementById("lower-indicator"); @@ -48,7 +49,28 @@ function rotateDisc(delta) { function changeDiscImage(delta) { if (delta === 0) return; if (is2PMode) delta = -delta; - applyDiscImage(delta > 0); + + const isUp = delta > 0; + if (isLatestDiscDirectionUp == isUp) return; + + if (isUp) { + downImg.style.display = 'none'; + if (upImg.classList.contains("img-available")) { + upImg.style.display = 'block'; + needle.style.display = 'none'; // 이미지 있으면 bar 숨기기 + } else { + upImg.style.display = 'none'; + needle.style.display = 'block'; // 기본 bar 보이기 + } + isLatestDiscDirectionUp = true; + } else { // Is down + if (downImg.classList.contains("img-available")) { + upImg.style.display = 'none'; // Remove the upDisc image only if the downDisc image is available + downImg.style.display = 'block'; + needle.style.display = 'none'; // 이미지 있으면 bar 숨기기 + isLatestDiscDirectionUp = false; + } + } } function updateBorders(delta) { @@ -125,29 +147,28 @@ function updateKPSDisplay() { } setInterval(updateKPSDisplay, 100); -function applyDiscImage(isUp) { - const img = document.getElementById('disc-image'); - const needle = document.getElementById('disc-needle'); - - if (!img || !needle) return; - if (isUp == isLatestDiscDirectionUp) return; - - if (isUp) { - if (!upDiscImagePath) { - img.src = ''; - img.style.display = 'none'; - needle.style.display = 'block'; // 기본 bar 보이기 - } else { - img.src = upDiscImagePath; - img.style.display = 'block'; - needle.style.display = 'none'; // 이미지 있으면 bar 숨기기 - } - isLatestDiscDirectionUp = true; - } else if (downDiscImagePath) { - img.src = downDiscImagePath; - img.style.display = 'block'; +function applyDiscImage(settings) { + let upDiscImagePath = settings.widget.upDiscImagePath; + let downDiscImagePath = settings.widget.downDiscImagePath; + + if (upDiscImagePath) { + upImg.classList.add("img-available"); + upImg.src = upDiscImagePath; + upImg.style.display = 'block'; needle.style.display = 'none'; // 이미지 있으면 bar 숨기기 - isLatestDiscDirectionUp = false; + } else { + upImg.classList.remove("img-available"); + upImg.src = ''; + upImg.style.display = 'none'; + needle.style.display = 'block'; // 기본 bar 보이기 + } + + if (downDiscImagePath) { + downImg.classList.add("img-available"); + downImg.src = downDiscImagePath; + downImg.style.display = 'none'; + } else { + downImg.classList.remove("img-available"); } } @@ -227,9 +248,7 @@ function applyButtonLayout(layout) { if (settings?.widget) { applyReleaseContainerSettings(settings.widget.infoPosition || 'bottom'); applyButtonLayout(settings.widget.buttonLayout || '1P'); - upDiscImagePath = settings.widget.upDiscImagePath; - downDiscImagePath = settings.widget.downDiscImagePath; - applyDiscImage(true); + applyDiscImage(settings); applyPromoBox(settings); globalMALength = settings.widget.globalMALength || 200; perButtonMALength = settings.widget.perButtonMALength || 200; diff --git a/iidxwidget-app/renderer/widget/style.css b/iidxwidget-app/renderer/widget/style.css index e64f436..c2ad19c 100644 --- a/iidxwidget-app/renderer/widget/style.css +++ b/iidxwidget-app/renderer/widget/style.css @@ -87,7 +87,7 @@ body { border-radius: 3px; } -#disc-image { +.disc-image { width: 100%; height: 100%; object-fit: cover; /* 정사각형 채움 */