@stringsync/vexml
Version:
MusicXML to Vexflow
62 lines (61 loc) • 2.21 kB
JavaScript
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;
}
}