summaryrefslogtreecommitdiff
path: root/tools/mq_editor
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-18 21:47:27 +0100
committerskal <pascal.massimino@gmail.com>2026-02-18 21:47:27 +0100
commit8f069fc08a123b1544c2a978586046e1ebb2173a (patch)
treed05b59ac439b3d93b3ed23df0110ddf29d39a4a7 /tools/mq_editor
parentf48397c58248ca338c258b1de762314926fe681f (diff)
fix(mq_editor): destroy old viewer listeners on WAV reload
Each loadAudioBuffer() was creating a new SpectrogramViewer without removing the previous one's canvas event listeners. Old viewers would fire on every mouse event, rendering stale spectrogram data and calling editor.onPartialSelect() with out-of-range indices (hiding the amp panel). Fix: store handlers as named instance properties, add destroy() to remove them, and call destroy() before creating a new viewer. handoff(Claude): bug fix only, no behaviour change Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'tools/mq_editor')
-rw-r--r--tools/mq_editor/app.js1
-rw-r--r--tools/mq_editor/viewer.js34
2 files changed, 25 insertions, 10 deletions
diff --git a/tools/mq_editor/app.js b/tools/mq_editor/app.js
index dd0a24f..d53af37 100644
--- a/tools/mq_editor/app.js
+++ b/tools/mq_editor/app.js
@@ -189,6 +189,7 @@ function loadAudioBuffer(buffer, label) {
});
}
+ if (viewer) viewer.destroy();
viewer = new SpectrogramViewer(canvas, audioBuffer, stftCache);
viewer.setFrames(peakFrames);
document.getElementById('exploreBtn').disabled = false;
diff --git a/tools/mq_editor/viewer.js b/tools/mq_editor/viewer.js
index 1bc5fc9..923edcc 100644
--- a/tools/mq_editor/viewer.js
+++ b/tools/mq_editor/viewer.js
@@ -608,10 +608,19 @@ class SpectrogramViewer {
this.t_center = (this.t_view_min + this.t_view_max) / 2;
}
+ destroy() {
+ const {canvas} = this;
+ canvas.removeEventListener('mousedown', this._onMousedown);
+ canvas.removeEventListener('mousemove', this._onMousemove);
+ canvas.removeEventListener('mouseleave', this._onMouseleave);
+ canvas.removeEventListener('mouseup', this._onMouseup);
+ canvas.removeEventListener('wheel', this._onWheel);
+ }
+
setupMouseHandlers() {
const {canvas, tooltip} = this;
- canvas.addEventListener('mousedown', (e) => {
+ this._onMousedown = (e) => {
const {x, y} = getCanvasCoords(e, canvas);
// Explore mode: commit preview on click
@@ -637,9 +646,10 @@ class SpectrogramViewer {
// Otherwise: select partial by click
const idx = this.hitTestPartial(x, y);
this.selectPartial(idx);
- });
+ };
+ canvas.addEventListener('mousedown', this._onMousedown);
- canvas.addEventListener('mousemove', (e) => {
+ this._onMousemove = (e) => {
const {x, y} = getCanvasCoords(e, canvas);
if (this.dragState) {
@@ -685,23 +695,26 @@ class SpectrogramViewer {
tooltip.style.top = (e.clientY + 10) + 'px';
tooltip.style.display = 'block';
tooltip.textContent = `${time.toFixed(3)}s, ${freq.toFixed(1)}Hz, ${intensity.toFixed(1)}dB`;
- });
+ };
+ canvas.addEventListener('mousemove', this._onMousemove);
- canvas.addEventListener('mouseleave', () => {
+ this._onMouseleave = () => {
this.mouseX = -1;
this.drawMouseCursor(-1);
tooltip.style.display = 'none';
- });
+ };
+ canvas.addEventListener('mouseleave', this._onMouseleave);
- canvas.addEventListener('mouseup', () => {
+ this._onMouseup = () => {
if (this.dragState) {
this.dragState = null;
canvas.style.cursor = 'crosshair';
if (this.onPartialSelect) this.onPartialSelect(this.selectedPartial);
}
- });
+ };
+ canvas.addEventListener('mouseup', this._onMouseup);
- canvas.addEventListener('wheel', (e) => {
+ this._onWheel = (e) => {
e.preventDefault();
const delta = e.deltaY !== 0 ? e.deltaY : e.deltaX;
@@ -726,7 +739,8 @@ class SpectrogramViewer {
this.updateViewBounds();
this.render();
- });
+ };
+ canvas.addEventListener('wheel', this._onWheel);
}
// --- Utilities ---