From 4395e0227cf253ca4391f0e9b6578aa37a6882d8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 05:04:03 +0000 Subject: [PATCH 1/2] Feat: Update mixer layout and add master volume dial - Move deck volume controls and crossfader below the automix button. - Change the master volume control from a slider to a dial. --- index.html | 36 +++++++++++++++---------------- js/main.js | 63 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/index.html b/index.html index cf4f80c..b75ad4f 100644 --- a/index.html +++ b/index.html @@ -92,25 +92,9 @@

🎧 DJ Toolkit Pro

-
+
+
- -
- -
-
- - -
-
- - -
-
- -
- -
@@ -129,6 +113,22 @@

🎧 DJ Toolkit Pro

+ +
+
+ + +
+
+ + +
+
+ +
+ + +
diff --git a/js/main.js b/js/main.js index 8370048..96930aa 100644 --- a/js/main.js +++ b/js/main.js @@ -727,9 +727,18 @@ class Deck { function setMasterVolume(value) { masterGain.gain.value = value / 100; + updateMasterVolumeKnobUI(value / 100); saveSettings(); } + function updateMasterVolumeKnobUI(value) { + const knob = document.getElementById('masterVolumeKnob'); + if (knob) { + const rotation = -135 + (value * 270); // -135 to 135 degrees + knob.style.transform = `rotate(${rotation}deg)`; + } + } + function setCrossfader(value) { crossfaderValue = parseFloat(value); const x = crossfaderValue / 100; @@ -774,6 +783,7 @@ class Deck { // Knob turning logic let activeKnob = { + type: null, // 'effect' or 'master' deck: null, effect: null, element: null, @@ -781,26 +791,32 @@ class Deck { initialValue: 0, }; - function startKnobTurn(event, deckId, effect) { + function startKnobTurn(event, type, parameter) { event.preventDefault(); - const deck = deckId === 'A' ? deckA : deckB; - - activeKnob.deck = deck; - activeKnob.effect = effect; activeKnob.element = event.target; activeKnob.initialY = event.clientY; - activeKnob.initialValue = deck.effects[effect].value; - - // Toggle active state on simple click without drag - if (event.detail === 1) { - const wasActive = deck.effects[effect].active; - // A small timeout to differentiate from a drag - setTimeout(() => { - if (activeKnob.element && Math.abs(event.clientY - activeKnob.initialY) < 5) { - deck.effects[effect].active = !wasActive; - deck.toggleEffect(effect); - } - }, 200); + + if (type === 'master') { + activeKnob.type = 'master'; + activeKnob.initialValue = masterGain.gain.value; + } else { + const deck = type === 'A' ? deckA : deckB; + activeKnob.type = 'effect'; + activeKnob.deck = deck; + activeKnob.effect = parameter; + activeKnob.initialValue = deck.effects[parameter].value; + + // Toggle active state on simple click without drag + if (event.detail === 1) { + const wasActive = deck.effects[parameter].active; + // A small timeout to differentiate from a drag + setTimeout(() => { + if (activeKnob.element && Math.abs(event.clientY - activeKnob.initialY) < 5) { + deck.effects[parameter].active = !wasActive; + deck.toggleEffect(parameter); + } + }, 200); + } } window.addEventListener('mousemove', handleKnobTurn); @@ -815,11 +831,16 @@ class Deck { let value = activeKnob.initialValue + dy * sensitivity; value = Math.max(0, Math.min(1, value)); // clamp between 0 and 1 - activeKnob.deck.toggleEffect(activeKnob.effect, value); + if (activeKnob.type === 'master') { + setMasterVolume(value * 100); + } else { + activeKnob.deck.toggleEffect(activeKnob.effect, value); + } } function endKnobTurn(event) { activeKnob.element = null; + activeKnob.type = null; window.removeEventListener('mousemove', handleKnobTurn); window.removeEventListener('mouseup', endKnobTurn); } @@ -1011,7 +1032,7 @@ class Deck { keylock: deckB.keylock, effects: deckB.effects }, - masterVolume: document.getElementById('masterVolume').value, + masterVolume: masterGain.gain.value * 100, crossfader: document.getElementById('crossfader').value, playlist: playlist.map(item => ({ name: item.name })) }; @@ -1038,7 +1059,6 @@ class Deck { document.getElementById('volumeB').value = session.deckB.volume; document.getElementById('tempoA').value = session.deckA.tempo; document.getElementById('tempoB').value = session.deckB.tempo; - document.getElementById('masterVolume').value = session.masterVolume; document.getElementById('crossfader').value = session.crossfader; setVolume('A', session.deckA.volume); @@ -1095,7 +1115,7 @@ class Deck { keylock: deckB.keylock, effects: deckB.effects }, - masterVolume: document.getElementById('masterVolume').value, + masterVolume: masterGain.gain.value * 100, crossfader: document.getElementById('crossfader').value, crossfaderCurve: document.getElementById('crossfaderCurve').value, theme: document.getElementById('theme').value, @@ -1111,7 +1131,6 @@ class Deck { // Restore Mixer setMasterVolume(settings.masterVolume); - document.getElementById('masterVolume').value = settings.masterVolume; setCrossfader(settings.crossfader); document.getElementById('crossfader').value = settings.crossfader; From 914662fdb8936b39ae6a99a565da5f93a6d1cbe0 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 05:13:37 +0000 Subject: [PATCH 2/2] Feat: Refine volume control labels - Add a single "Volume" label above the deck volume sliders. - Change the individual slider labels to "A" and "B" and move them below the sliders. - Fix a bug where the master volume knob's UI was not updated when loading settings. --- css/style.css | 8 ++++++++ index.html | 17 ++++++++++------- js/main.js | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/css/style.css b/css/style.css index ba96f59..2e35103 100644 --- a/css/style.css +++ b/css/style.css @@ -253,6 +253,14 @@ } .deck-volume-controls { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + width: 100%; + } + + .deck-volume-sliders { display: flex; gap: 40px; justify-content: center; diff --git a/index.html b/index.html index b75ad4f..3bd1a3a 100644 --- a/index.html +++ b/index.html @@ -115,13 +115,16 @@

🎧 DJ Toolkit Pro

-
- - -
-
- - + +
+
+ + +
+
+ + +
diff --git a/js/main.js b/js/main.js index 96930aa..76fb5c3 100644 --- a/js/main.js +++ b/js/main.js @@ -728,7 +728,6 @@ class Deck { function setMasterVolume(value) { masterGain.gain.value = value / 100; updateMasterVolumeKnobUI(value / 100); - saveSettings(); } function updateMasterVolumeKnobUI(value) { @@ -833,6 +832,7 @@ class Deck { if (activeKnob.type === 'master') { setMasterVolume(value * 100); + saveSettings(); } else { activeKnob.deck.toggleEffect(activeKnob.effect, value); }