summaryrefslogtreecommitdiff
path: root/tools/mq_editor/editor.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mq_editor/editor.js')
-rw-r--r--tools/mq_editor/editor.js85
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;