From 4342ed8dc025622800c074c4bcacd0d63d0ed6e9 Mon Sep 17 00:00:00 2001 From: Cheezer1656 <118921295+Cheezer1656@users.noreply.github.com> Date: Sun, 21 Apr 2024 18:29:39 -0700 Subject: [PATCH 1/2] Allow staff visualizers to be split into multiple lines --- src/visualizer.ts | 52 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/src/visualizer.ts b/src/visualizer.ts index b65d87e..8bd075a 100644 --- a/src/visualizer.ts +++ b/src/visualizer.ts @@ -19,6 +19,7 @@ type Visualizer = mm.PianoRollSVGVisualizer | mm.WaterfallSVGVisualizer | mm.Sta * * @prop src - MIDI file URL * @prop type - Visualizer type + * @prop lines - Number of lines in the visualizer (Only for `staff` type) * @prop noteSequence - Magenta note sequence object representing the currently displayed content * @prop config - Magenta visualizer config object */ @@ -27,7 +28,8 @@ export class VisualizerElement extends HTMLElement { private initTimeout: number; protected wrapper: HTMLDivElement; - protected visualizer: Visualizer; + protected visualizers: Visualizer[]; + protected lastChunkIndex: number = 0; protected ns: INoteSequence = null; protected _config: mm.VisualizerConfig = {}; @@ -81,15 +83,24 @@ export class VisualizerElement extends HTMLElement { this.wrapper.classList.add('piano-roll-visualizer'); const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); this.wrapper.appendChild(svg); - this.visualizer = new mm.PianoRollSVGVisualizer(this.ns, svg, this._config); + this.visualizers = [new mm.PianoRollSVGVisualizer(this.ns, svg, this._config)]; } else if (this.type === 'waterfall') { this.wrapper.classList.add('waterfall-visualizer'); - this.visualizer = new mm.WaterfallSVGVisualizer(this.ns, this.wrapper, this._config); + this.visualizers = [new mm.WaterfallSVGVisualizer(this.ns, this.wrapper, this._config)]; } else if (this.type === 'staff') { this.wrapper.classList.add('staff-visualizer'); - const div = document.createElement('div'); - this.wrapper.appendChild(div); - this.visualizer = new mm.StaffSVGVisualizer(this.ns, div, this._config); + this.visualizers = []; + const chunkSize = Math.ceil(this.ns.notes.length / this.lines); + for (let i = 0; i < this.ns.notes.length; i += chunkSize) { + const chunk = structuredClone(this.ns.notes.slice(i, i + chunkSize)); + let startTime = chunk[0].startTime; + chunk.forEach(n => {n.startTime -= startTime;n.endTime -= startTime;}); + const div = document.createElement('div'); + this.wrapper.appendChild(div); + const new_ns = structuredClone(this.ns); + new_ns.notes = chunk; + this.visualizers.push(new mm.StaffSVGVisualizer(new_ns, div, this._config)); + } } } @@ -98,14 +109,26 @@ export class VisualizerElement extends HTMLElement { } redraw(activeNote?: NoteSequence.INote) { - if (this.visualizer) { - this.visualizer.redraw(activeNote, activeNote != null); + if (this.visualizers) { + if (this.type == "staff") { + let chunkIndex = Math.floor(this.ns.notes.indexOf(activeNote) / Math.ceil(this.ns.notes.length / this.lines)); + if (chunkIndex != this.lastChunkIndex) { + this.visualizers[this.lastChunkIndex].redraw(activeNote, false); // clearActiveNotes() doesn't work + this.lastChunkIndex = chunkIndex; + } + const note = structuredClone(activeNote); + note.startTime -= this.ns.notes[chunkIndex * Math.ceil(this.ns.notes.length / this.lines)].startTime; + this.visualizers[chunkIndex].redraw(note, activeNote != null); + } + else { + this.visualizers.forEach(visualizer => visualizer.redraw(activeNote, activeNote != null)); + } } } clearActiveNotes() { - if (this.visualizer) { - this.visualizer.clearActiveNotes(); + if (this.visualizers) { + this.visualizers.forEach(visualizer => visualizer.clearActiveNotes()); } } @@ -148,6 +171,15 @@ export class VisualizerElement extends HTMLElement { this.setOrRemoveAttribute('type', value); } + get lines() { + let lines = Number(this.getAttribute('lines')) + return lines == 0 ? 1 : lines; + } + + set lines(value: number) { + this.setOrRemoveAttribute('lines', value.toString() == '0' ? null : value.toString()); + } + get config() { return this._config; } From da3e8d3e45c1f2095e2bfda9a1edef509bb6f614 Mon Sep 17 00:00:00 2001 From: Cheezer1656 <118921295+Cheezer1656@users.noreply.github.com> Date: Sun, 21 Apr 2024 18:34:17 -0700 Subject: [PATCH 2/2] Add multi-lined visualizer to index.html --- index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/index.html b/index.html index ca1756e..50a620e 100644 --- a/index.html +++ b/index.html @@ -24,6 +24,7 @@