UNPKG

@stringsync/vexml

Version:

MusicXML to Vexflow

74 lines (73 loc) 2.45 kB
import * as vexflow from 'vexflow'; import * as util from '../util'; import { Rect } from '../spatial'; export class OctaveShift { config; log; document; key; registry; constructor(config, log, document, key, registry) { this.config = config; this.log = log; this.document = document; this.key = key; this.registry = registry; } render() { const octaveShift = this.document.getOctaveShift(this.key); const renders = this.registry.get(octaveShift.id).filter((r) => r.type === 'note' || r.type === 'rest'); const vexflowTextBrackets = this.renderVexflowTextBrackets(renders); return { type: 'octaveshift', key: this.key, rect: Rect.empty(), vexflowTextBrackets, }; } renderVexflowTextBrackets(renders) { if (renders.length < 2) { this.log.warn('cannot render octave shift with less than 2 notes, skipping', { octaveShiftIndex: this.key.octaveShiftIndex, }); return []; } const vexflowTextBrackets = new Array(); const systemIndexes = util.unique(renders.map((n) => n.key.systemIndex)); for (const systemIndex of systemIndexes) { const systemNoteRenders = renders.filter((n) => n.key.systemIndex === systemIndex); if (systemNoteRenders.length > 1) { const vexflowTextBracket = this.renderVexflowTextBracket(systemNoteRenders); vexflowTextBrackets.push(vexflowTextBracket); } } return vexflowTextBrackets; } renderVexflowTextBracket(renders) { const octaveShift = this.document.getOctaveShift(this.key); const start = renders.at(0).vexflowNote; const stop = renders.at(-1).vexflowNote; const text = Math.abs(octaveShift.size).toString(); let position; if (octaveShift.size < 0) { position = vexflow.TextBracketPosition.TOP; } else { position = vexflow.TextBracketPosition.BOTTOM; } let superscript; if (octaveShift.size < 0) { superscript = 'va'; } else { superscript = 'mb'; } return new vexflow.TextBracket({ start, stop, text, superscript, position, }); } }