UNPKG

@stringsync/vexml

Version:

MusicXML to Vexflow

62 lines (61 loc) 2.21 kB
import { Part } from './part'; import { Fraction } from '../util'; export class Fragment { config; log; document; fragmentRender; parts; constructor(config, log, document, fragmentRender, parts) { this.config = config; this.log = log; this.document = document; this.fragmentRender = fragmentRender; this.parts = parts; } static create(config, log, document, fragmentRender) { const parts = fragmentRender.partRenders.map((partRender) => Part.create(config, log, document, partRender)); return new Fragment(config, log, document, fragmentRender, parts); } /** The name of the element, which can be used as a type discriminant. */ name = 'fragment'; /** Returns the bounding box of the element. */ rect() { return this.fragmentRender.rect; } /** Returns the parts of the fragment. */ getParts() { return this.parts; } /** Returns the system index for the fragment. */ getSystemIndex() { return this.fragmentRender.key.systemIndex; } /** Returns the absolute measure index for the fragment. */ getAbsoluteMeasureIndex() { return this.document.getAbsoluteMeasureIndex(this.fragmentRender.key); } /** Returns the start measure beat for the fragment. */ getStartMeasureBeat() { return (this.parts .map((part) => part.getStartMeasureBeat()) .sort((a, b) => a.toDecimal() - b.toDecimal()) .at(0) ?? Fraction.zero()); } /** Returns the bpm of the fragment. */ getBpm() { return this.document.getFragment(this.fragmentRender.key).signature.metronome.playbackBpm || 1; // disallow 0; } /** Returns the max number of parts in this score. */ getPartCount() { return this.parts.length; } /** Returns whether the fragment is a non-musical gap. */ isNonMusicalGap() { return this.document.getFragment(this.fragmentRender.key).kind === 'nonmusical'; } /** Returns the non-musical duration of the gap. */ getNonMusicalDurationMs() { return this.document.getNonMusicalFragment(this.fragmentRender.key).durationMs; } }