UNPKG

@stringsync/vexml

Version:

MusicXML to Vexflow

53 lines (52 loc) 1.99 kB
import * as vexflow from 'vexflow'; import { Rect } from '../spatial'; import { Stave } from './stave'; import { Pen } from './pen'; export class Part { config; log; document; key; position; constructor(config, log, document, key, position) { this.config = config; this.log = log; this.document = document; this.key = key; this.position = position; } render() { const pen = new Pen(this.position); const staveRenders = this.renderStaves(pen); const vexflowBrace = this.renderVexflowBrace(staveRenders); return { type: 'part', key: this.key, rect: Rect.empty(), // placeholder staveRenders, vexflowBrace, }; } renderStaves(pen) { const staveRenders = new Array(); const staveCount = this.document.getStaveCount(this.key); for (let staveIndex = 0; staveIndex < staveCount; staveIndex++) { const key = { ...this.key, staveIndex }; const staveRender = new Stave(this.config, this.log, this.document, key, pen.position()).render(); staveRenders.push(staveRender); // TODO: Check <stave-layouts> first, which has a part+stave scoped margin. pen.moveBy({ dy: this.config.DEFAULT_STAVE_MARGIN_BOTTOM + staveRender.vexflowStave.getHeight() }); } return staveRenders; } renderVexflowBrace(staveRenders) { const isFirstMeasure = this.document.isFirstMeasure(this.key); const isFirstFragment = this.document.isFirstFragment(this.key); if (isFirstMeasure && isFirstFragment && staveRenders.length > 1) { const firstVexflowStave = staveRenders.at(0).vexflowStave; const lastVexflowStave = staveRenders.at(-1).vexflowStave; return new vexflow.StaveConnector(firstVexflowStave, lastVexflowStave).setType('brace'); } return null; } }