diff --git a/js/settings.js b/js/settings.js index 1f71e5a..c73e2e2 100644 --- a/js/settings.js +++ b/js/settings.js @@ -1228,6 +1228,9 @@ export function initializeSettings(scrobbler, player, api, ui) { const savedGains = equalizerSettings.getGains(currentBandCount); + // FL Studio-style absolute position drag state + let isDragging = false; + eqBands.forEach((bandEl) => { const bandIndex = parseInt(bandEl.dataset.band, 10); const slider = bandEl.querySelector('.eq-slider'); @@ -1266,6 +1269,63 @@ export function initializeSettings(scrobbler, player, api, ui) { updateBandValueDisplay(bandEl, 0); drawEQCurve(); }); + + // FL Studio-style absolute drag: mousedown starts drag mode + bandEl.addEventListener('mousedown', (e) => { + // Only handle left mouse button + if (e.button !== 0) return; + + isDragging = true; + document.body.style.cursor = 'ns-resize'; + e.preventDefault(); + }); + } + }); + + // Global mousemove: whichever band is under cursor, set slider to cursor Y position + document.addEventListener('mousemove', (e) => { + if (!isDragging) return; + + // Find which band is under the cursor + const elementUnderCursor = document.elementFromPoint(e.clientX, e.clientY); + const bandUnderCursor = elementUnderCursor?.closest('.eq-band'); + + if (bandUnderCursor) { + const slider = bandUnderCursor.querySelector('.eq-slider'); + + if (slider) { + const rect = slider.getBoundingClientRect(); + const min = parseFloat(slider.min); + const max = parseFloat(slider.max); + const step = parseFloat(slider.step) || 0.5; + + // Calculate relative Y position within slider (0 = bottom, 1 = top) + const relativeY = (rect.bottom - e.clientY) / rect.height; + const clampedY = Math.max(0, Math.min(1, relativeY)); + + // Map to slider value range + let newValue = min + clampedY * (max - min); + + // Round to step + newValue = Math.round(newValue / step) * step; + + // Only update if value changed + if (parseFloat(slider.value) !== newValue) { + slider.value = newValue; + const bandIndex = parseInt(bandUnderCursor.dataset.band, 10); + audioContextManager.setBandGain(bandIndex, newValue); + updateBandValueDisplay(bandUnderCursor, newValue); + drawEQCurve(); + } + } + } + }); + + // Global mouseup: stop dragging + document.addEventListener('mouseup', () => { + if (isDragging) { + isDragging = false; + document.body.style.cursor = ''; } }); diff --git a/styles.css b/styles.css index 14a3992..883de4b 100644 --- a/styles.css +++ b/styles.css @@ -6982,6 +6982,8 @@ textarea:focus { min-width: 0; position: relative; z-index: 1; + cursor: ns-resize; + user-select: none; } /* Vertical slider styling */ @@ -6993,6 +6995,7 @@ textarea:focus { height: 120px; background: transparent; cursor: pointer; + user-select: none; position: relative; }