diff options
Diffstat (limited to 'tools/mq_editor/editor.js')
| -rw-r--r-- | tools/mq_editor/editor.js | 85 |
1 files changed, 32 insertions, 53 deletions
diff --git a/tools/mq_editor/editor.js b/tools/mq_editor/editor.js index 97d8a7a..301dcc5 100644 --- a/tools/mq_editor/editor.js +++ b/tools/mq_editor/editor.js @@ -181,7 +181,15 @@ class PartialEditor { }); sinInputs[p.key] = inp; - const jog = this._makeJogSlider(inp, partial, index, p, repDefaults); + const jog = this._makeJogSlider(inp, { + step: parseFloat(p.step), + onUpdate: (newVal) => { + if (!this.partials || !this.partials[index]) return; + if (!this.partials[index].replicas) this.partials[index].replicas = { ...repDefaults }; + this.partials[index].replicas[p.key] = newVal; + if (this.viewer) this.viewer.render(); + } + }); const wrap = document.createElement('div'); wrap.className = 'synth-field-wrap'; wrap.appendChild(inp); @@ -245,45 +253,15 @@ class PartialEditor { if (this.viewer) this.viewer.render(); }); - // Inline jog slider for resonator params - const step = parseFloat(p.step); - const sensitivity = step * 5; - const jog = document.createElement('div'); - jog.className = 'jog-slider'; - const thumb = document.createElement('div'); - thumb.className = 'jog-thumb'; - jog.appendChild(thumb); - let dragging = false, startX = 0, startVal = 0; - const onMove = (ev) => { - if (!dragging) return; - const dx = ev.clientX - startX; - const half = jog.offsetWidth / 2; - const clamped = Math.max(-half, Math.min(half, dx)); - thumb.style.transition = 'none'; - thumb.style.left = `calc(50% - 3px + ${clamped}px)`; - const newVal = Math.max(parseFloat(inp.min) || 0, - Math.min(parseFloat(inp.max) || 1e9, startVal + dx * sensitivity)); - inp.value = newVal.toFixed(4); - if (!this.partials || !this.partials[index]) return; - if (!this.partials[index].resonator) this.partials[index].resonator = { ...resDefaults }; - this.partials[index].resonator[p.key] = newVal; - if (this.viewer) this.viewer.render(); - }; - const onUp = () => { - if (!dragging) return; - dragging = false; - thumb.style.transition = ''; - thumb.style.left = 'calc(50% - 3px)'; - document.removeEventListener('mousemove', onMove); - document.removeEventListener('mouseup', onUp); - }; - jog.addEventListener('mousedown', (ev) => { - dragging = true; - startX = ev.clientX; - startVal = parseFloat(inp.value) || 0; - document.addEventListener('mousemove', onMove); - document.addEventListener('mouseup', onUp); - ev.preventDefault(); + const jog = this._makeJogSlider(inp, { + step: parseFloat(p.step), + decimals: 4, + onUpdate: (newVal) => { + if (!this.partials || !this.partials[index]) return; + if (!this.partials[index].resonator) this.partials[index].resonator = { ...resDefaults }; + this.partials[index].resonator[p.key] = newVal; + if (this.viewer) this.viewer.render(); + } }); const wrap = document.createElement('div'); @@ -322,14 +300,20 @@ class PartialEditor { }); } - _makeJogSlider(inp, partial, index, p, defaults) { + _makeJogSlider(inp, options) { + const {step, onUpdate, decimals = 3} = options; + const min = options.min != null ? options.min : + (inp.min !== '' && !isNaN(parseFloat(inp.min)) ? parseFloat(inp.min) : 0); + const max = options.max != null ? options.max : + (inp.max !== '' && !isNaN(parseFloat(inp.max)) ? parseFloat(inp.max) : Infinity); + const sensitivity = step * 5; + const slider = document.createElement('div'); slider.className = 'jog-slider'; const thumb = document.createElement('div'); thumb.className = 'jog-thumb'; slider.appendChild(thumb); - const sensitivity = parseFloat(p.step) * 5; let startX = 0, startVal = 0, dragging = false; const onMove = (e) => { @@ -339,12 +323,9 @@ class PartialEditor { const clamped = Math.max(-half, Math.min(half, dx)); thumb.style.transition = 'none'; thumb.style.left = `calc(50% - 3px + ${clamped}px)`; - const newVal = Math.max(0, startVal + dx * sensitivity); - inp.value = newVal.toFixed(3); - if (!this.partials || !this.partials[index]) return; - if (!this.partials[index].replicas) this.partials[index].replicas = { ...defaults }; - this.partials[index].replicas[p.key] = newVal; - if (this.viewer) this.viewer.render(); + const newVal = Math.max(min, Math.min(max, startVal + dx * sensitivity)); + inp.value = newVal.toFixed(decimals); + onUpdate(newVal); }; const onUp = () => { @@ -359,7 +340,7 @@ class PartialEditor { slider.addEventListener('mousedown', (e) => { dragging = true; startX = e.clientX; - startVal = Math.max(0, parseFloat(inp.value) || 0); + startVal = Math.max(min, parseFloat(inp.value) || 0); document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp); e.preventDefault(); @@ -504,8 +485,7 @@ class PartialEditor { if (this._selectedIndex < 0 || !this.partials) return; const partial = this.partials[this._selectedIndex]; if (!partial || !partial.ampCurve) return; - const rect = canvas.getBoundingClientRect(); - const x = e.clientX - rect.left, y = e.clientY - rect.top; + const {x, y} = getCanvasCoords(e, canvas); const curve = partial.ampCurve; for (let i = 0; i < 4; ++i) { if (Math.hypot(this._tToX(curve['t' + i]) - x, this._ampToY(curve['v' + i]) - y) <= 8) { @@ -518,8 +498,7 @@ class PartialEditor { }); canvas.addEventListener('mousemove', (e) => { - const rect = canvas.getBoundingClientRect(); - const x = e.clientX - rect.left, y = e.clientY - rect.top; + const {x, y} = getCanvasCoords(e, canvas); if (this._dragPointIndex >= 0) { const curve = this.partials[this._selectedIndex].ampCurve; |
