UNPKG

museaikit

Version:

A powerful music-focused AI toolkit

106 lines 3.95 kB
import { BaseVisualizer } from './base_visualizer'; export class BaseSVGVisualizer extends BaseVisualizer { svg; drawn; constructor(sequence, config = {}) { super(sequence, config); this.drawn = false; } redraw(activeNote, scrollIntoView) { if (!this.drawn) { this.draw(); } if (!activeNote) { return null; } this.unfillActiveRect(this.svg); let activeNotePosition; for (let i = 0; i < this.noteSequence.notes.length; i++) { const note = this.noteSequence.notes[i]; const isActive = activeNote && this.isPaintingActiveNote(note, activeNote); if (!isActive) { continue; } const el = this.svg.querySelector(`rect[data-index="${i}"]`); this.fillActiveRect(el, note); if (note === activeNote) { activeNotePosition = parseFloat(el.getAttribute('x')); } } this.scrollIntoViewIfNeeded(scrollIntoView, activeNotePosition); return activeNotePosition; } fillActiveRect(el, note) { el.setAttribute('fill', this.getNoteFillColor(note, true)); el.classList.add('active'); } unfillActiveRect(svg) { const els = svg.querySelectorAll('rect.active'); for (let i = 0; i < els.length; ++i) { const el = els[i]; const fill = this.getNoteFillColor(this.noteSequence.notes[parseInt(el.getAttribute('data-index'), 10)], false); el.setAttribute('fill', fill); el.classList.remove('active'); } } draw() { for (let i = 0; i < this.noteSequence.notes.length; i++) { const note = this.noteSequence.notes[i]; const size = this.getNotePosition(note, i); const fill = this.getNoteFillColor(note, false); const dataAttributes = [ ['index', i], ['instrument', note.instrument], ['program', note.program], ['isDrum', note.isDrum === true], ['pitch', note.pitch], ]; const cssProperties = [ ['--midi-velocity', String(note.velocity !== undefined ? note.velocity : 127)] ]; this.drawNote(size.x, size.y, size.w, size.h, fill, dataAttributes, cssProperties); } this.drawn = true; } getNoteFillColor(note, isActive) { const opacityBaseline = 0.2; const opacity = note.velocity ? note.velocity / 100 + opacityBaseline : 1; const fill = `rgba(${isActive ? this.config.activeNoteRGB : this.config.noteRGB}, ${opacity})`; return fill; } drawNote(x, y, w, h, fill, dataAttributes, cssProperties) { if (!this.svg) { return; } const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); rect.classList.add('note'); rect.setAttribute('fill', fill); rect.setAttribute('x', `${Math.round(x)}`); rect.setAttribute('y', `${Math.round(y)}`); rect.setAttribute('width', `${Math.round(w)}`); rect.setAttribute('height', `${Math.round(h)}`); dataAttributes.forEach(([key, value]) => { if (value !== undefined) { rect.dataset[key] = `${value}`; } }); cssProperties.forEach(([key, value]) => { rect.style.setProperty(key, value); }); this.svg.appendChild(rect); } clear() { if (this.svg) { this.svg.innerHTML = ''; } this.drawn = false; } clearActiveNotes() { if (this.svg) { this.unfillActiveRect(this.svg); } } } //# sourceMappingURL=base_svg_visualizer.js.map