I wanted to use your library in React application (based on your: https://github.com/opensheetmusicdisplay/react-opensheetmusicdisplay ).
Is there a way to scroll to a given measure when the sheet is already rendered?
Is it possible to display cursor at given measure?
Measure the cursor is currently on:
const currentMeasure = this.osmd.cursor.VoicesUnderCursor()[0]
.parentSourceStaffEntry.VerticalContainerParent.ParentMeasure
.MeasureNumber;
One way is to iterate using osmd.cursor.next() till given measure.
Yes, as we discussed on gitter.
Of course disable graphic updates with osmd.cursor.hide() before you cycle through with cursor.next(), then call cursor.show() again, otherwise you'll probably get visual flicker.
Some functions to manage cursor.
goToPrevLine() {
const measuresInLine = this.getMeasuresInLine(
this.getCurrentMeasureNumber()
);
const firstMeasureOfLineNumber = measuresInLine[0].measureNumber;
const measuresInPreviousLine = this.getMeasuresInLine(
firstMeasureOfLineNumber - 2
);
if (!measuresInPreviousLine) return;
const firstMeasureOfPreviousLineNumber =
measuresInPreviousLine[0].measureNumber;
this.goToMeasure(firstMeasureOfPreviousLineNumber);
}
goToNextLine() {
const measuresInLine = this.getMeasuresInLine(
this.getCurrentMeasureNumber()
);
const lastMeasureOfLineNumber = measuresInLine.last().measureNumber;
const nextMeasure = lastMeasureOfLineNumber + 1;
if (nextMeasure > this.osmd.GraphicSheet.measureList.length) return;
this.goToMeasure(nextMeasure);
}
goToMeasure(measure) {
//in case we want to go back
this.osmd.cursor.reset();
while (
this.getCurrentCursorMeasure() &&
this.getCurrentCursorMeasure().MeasureNumber < measure
)
this.osmd.cursor.next();
this.scrollToCursor();
}
scrollToCursor() {
const diffToBar = this.osmd.cursor.cursorElement.getBoundingClientRect()
.top;
window.scrollBy(0, diffToBar - 100);
// OR
// this.osmd.cursor.cursorElement.scrollIntoView({
// behavior: diff < 1000 ? "smooth" : "auto",
// block: "start",
// });
//but it cuts upper part of music sheet
}
//no nullchecks
getCurrentCursorMeasure() {
return this.osmd.cursor.VoicesUnderCursor()[0].parentSourceStaffEntry
.VerticalContainerParent.ParentMeasure;
}
getCurrentMeasureNumber() {
return this.getCurrentCursorMeasure().MeasureNumber;
}
getMeasuresInLine(measureNumber) {
if (measureNumber < 0) return;
return this.osmd.GraphicSheet.measureList[measureNumber][0].parentStaffLine
.Measures;
}
Yes, as we discussed on gitter.
Of course disable graphic updates with osmd.cursor.hide() before you cycle through with cursor.next(), then call cursor.show() again, otherwise you'll probably get visual flicker.
It seems cursor.hide() is also resetting cursor and after show() it's on starting position. But it looks good without hiding.
Oh, right, maybe we shouldn't reset cursor in hide(). Good to know!
These helper functions are nice! I'd also write such functions if i were using the cursor (which is a pretty basic class right now) extensively in a project.
I'd probably add a GetCurrentCursorMeasure() method which returns cursor.VoicesUnderCursor()[0].parentSourceStaffEntry.VerticalContainerParent.ParentMeasure while checking that VoicesUnderCursor().length > 0, for convenience. Maybe we'll add that to the cursor class, as it seems quite useful and not quite straightforward.
Hi, I would also love to see this feature!
@mkuzmik hi, fkruzek posted working code two comments above yours. Or are you saying you would like to see these methods integrated into the Cursor class? Of course you can always write these methods into a helper class of your own.