vexflow
Version:
A JavaScript library for rendering music notation and guitar tablature.
568 lines (567 loc) • 27.5 kB
JavaScript
import { VexFlowTests } from './vexflow_test_helpers.js';
import { Accidental } from '../src/accidental.js';
import { Beam } from '../src/beam.js';
import { Clef } from '../src/clef.js';
import { Formatter } from '../src/formatter.js';
import { KeySignature } from '../src/keysignature.js';
import { Modifier } from '../src/modifier.js';
import { Stave } from '../src/stave.js';
import { Barline, BarlineType } from '../src/stavebarline.js';
import { StaveNote } from '../src/stavenote.js';
import { Repetition } from '../src/staverepetition.js';
import { StaveSection } from '../src/stavesection.js';
import { VoltaType } from '../src/stavevolta.js';
import { TextJustification } from '../src/textnote.js';
import { TimeSignature } from '../src/timesignature.js';
const StaveTests = {
Start() {
QUnit.module('Stave');
QUnit.test('StaveModifiers SortByCategory', sortByCategory);
const run = VexFlowTests.runTests;
run('Stave Draw Test', draw);
run('Open Stave Draw Test', drawOpenStave);
run('Multiple Stave Barline Test', drawMultipleMeasures);
run('Multiple Stave Barline Test (14pt Section)', drawMultipleMeasures, { fontSize: 14 });
run('Multiple Stave Repeats Test', drawRepeats);
run('Stave End Modifiers Test', drawEndModifiers);
run('Stave Repetition (CODA) Positioning', drawStaveRepetition, { yShift: 0 });
run('Stave Repetition (CODA) Positioning (-20)', drawStaveRepetition, { yShift: -20 });
run('Stave Repetition (CODA) Positioning (+10)', drawStaveRepetition, { yShift: +10 });
run('Multiple Staves Volta Test', drawVolta);
run('Volta + Modifier Measure Test', drawVoltaModifier);
run('Tempo Test', drawTempo);
run('Single Line Configuration Test', configureSingleLine);
run('Batch Line Configuration Test', configureAllLines);
run('Stave Text Test', drawStaveText);
run('Multiple Line Stave Text Test', drawStaveTextMultiLine);
run('Factory API', factoryAPI);
},
};
function sortByCategory(assert) {
const stave = new Stave(0, 0, 300);
const clef0 = new Clef('treble');
const clef1 = new Clef('alto');
const clef2 = new Clef('bass');
const time0 = new TimeSignature('C');
const time1 = new TimeSignature('C|');
const time2 = new TimeSignature('9/8');
const key0 = new KeySignature('G');
const key1 = new KeySignature('F');
const key2 = new KeySignature('D');
const bar0 = new Barline(BarlineType.SINGLE);
const bar1 = new Barline(BarlineType.DOUBLE);
const bar2 = new Barline(BarlineType.NONE);
const order0 = { Barline: 0, Clef: 1, KeySignature: 2, TimeSignature: 3 };
const order1 = { TimeSignature: 0, KeySignature: 1, Barline: 2, Clef: 3 };
const sortAndCompare = (title, a, b, order) => {
stave.sortByCategory(a, order);
let isSame = true;
if (a.length !== b.length)
isSame = false;
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i])
isSame = false;
}
assert.ok(isSame, title);
};
sortAndCompare('Keep the original order 1', [bar0, bar1, clef0, clef1, key0, key1, time0, time1], [bar0, bar1, clef0, clef1, key0, key1, time0, time1], order0);
sortAndCompare('Keep the original order 2', [time0, time1, key0, key1, bar0, bar1, clef0, clef1], [time0, time1, key0, key1, bar0, bar1, clef0, clef1], order1);
sortAndCompare('Sort and keep 1', [bar0, bar1, clef0, clef1, key0, key1, time0, time1], [time0, time1, key0, key1, bar0, bar1, clef0, clef1], order1);
sortAndCompare('Sort and keep 2', [bar0, clef0, key0, time0, key1, time1, clef1, bar1, time2, clef2, bar2, key2], [bar0, bar1, bar2, clef0, clef1, clef2, key0, key1, key2, time0, time1, time2], order0);
sortAndCompare('Sort and keep 3', [bar2, clef2, key2, time0, key0, time2, clef1, bar1, time1, clef0, bar0, key1], [time0, time2, time1, key2, key0, key1, bar2, bar1, bar0, clef2, clef1, clef0], order1);
}
function draw(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 400, 150);
const stave = new Stave(10, 10, 300);
stave.setContext(ctx);
stave.drawWithStyle();
options.assert.equal(stave.getYForNote(0), 100, 'getYForNote(0)');
options.assert.equal(stave.getYForLine(5), 100, 'getYForLine(5)');
options.assert.equal(stave.getYForLine(0), 50, 'getYForLine(0) - Top Line');
options.assert.equal(stave.getYForLine(4), 90, 'getYForLine(4) - Bottom Line');
options.assert.ok(true, 'all pass');
}
function drawOpenStave(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 400, 350);
let stave = new Stave(10, 10, 300, { leftBar: false });
stave.setContext(ctx);
stave.drawWithStyle();
stave = new Stave(10, 150, 300, { rightBar: false });
stave.setContext(ctx);
stave.drawWithStyle();
options.assert.ok(true, 'all pass');
}
function drawMultipleMeasures(options, contextBuilder) {
var _a, _b;
options.assert.expect(0);
const ctx = contextBuilder(options.elementId, 550, 200);
const staveBar1 = new Stave(10, 50, 200);
staveBar1.setBegBarType(BarlineType.REPEAT_BEGIN);
staveBar1.setEndBarType(BarlineType.DOUBLE);
staveBar1.setSection('A', 0, 0, (_a = options.params) === null || _a === void 0 ? void 0 : _a.fontSize, false);
staveBar1.addClef('treble').setContext(ctx).drawWithStyle();
const notesBar1 = [
new StaveNote({ keys: ['c/4'], duration: 'q' }),
new StaveNote({ keys: ['d/4'], duration: 'q' }),
new StaveNote({ keys: ['b/4'], duration: 'qr' }),
new StaveNote({ keys: ['c/4', 'e/4', 'g/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, staveBar1, notesBar1);
const staveBar2 = new Stave(staveBar1.getWidth() + staveBar1.getX(), staveBar1.getY(), 300);
staveBar2.addModifier(new StaveSection('B').setFontSize((_b = options.params) === null || _b === void 0 ? void 0 : _b.fontSize));
staveBar2.setEndBarType(BarlineType.END);
staveBar2.setContext(ctx).drawWithStyle();
const notesBar2Part1 = [
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
];
const notesBar2Part2 = [
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
];
const beam1 = new Beam(notesBar2Part1);
const beam2 = new Beam(notesBar2Part2);
const notesBar2 = notesBar2Part1.concat(notesBar2Part2);
Formatter.FormatAndDraw(ctx, staveBar2, notesBar2);
beam1.setContext(ctx).drawWithStyle();
beam2.setContext(ctx).drawWithStyle();
}
function drawRepeats(options, contextBuilder) {
options.assert.expect(0);
const ctx = contextBuilder(options.elementId, 750, 120);
const staveBar1 = new Stave(10, 0, 250);
staveBar1.setBegBarType(BarlineType.REPEAT_BEGIN);
staveBar1.setEndBarType(BarlineType.REPEAT_END);
staveBar1.addClef('treble');
staveBar1.addKeySignature('A');
staveBar1.setContext(ctx).drawWithStyle();
const notesBar1 = [
new StaveNote({ keys: ['c/4'], duration: 'q' }),
new StaveNote({ keys: ['d/4'], duration: 'q' }),
new StaveNote({ keys: ['b/4'], duration: 'qr' }),
new StaveNote({ keys: ['c/4', 'e/4', 'g/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, staveBar1, notesBar1);
const staveBar2 = new Stave(staveBar1.getWidth() + staveBar1.getX(), staveBar1.getY(), 250);
staveBar2.setBegBarType(BarlineType.REPEAT_BEGIN);
staveBar2.setEndBarType(BarlineType.REPEAT_END);
staveBar2.setContext(ctx).drawWithStyle();
const notesBar2Part1 = [
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
];
const notesBar2Part2 = [
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
];
notesBar2Part2[0].addModifier(new Accidental('#'), 0);
notesBar2Part2[1].addModifier(new Accidental('#'), 0);
notesBar2Part2[3].addModifier(new Accidental('b'), 0);
const beam1 = new Beam(notesBar2Part1);
const beam2 = new Beam(notesBar2Part2);
const notesBar2 = notesBar2Part1.concat(notesBar2Part2);
Formatter.FormatAndDraw(ctx, staveBar2, notesBar2);
beam1.setContext(ctx).drawWithStyle();
beam2.setContext(ctx).drawWithStyle();
const staveBar3 = new Stave(staveBar2.getWidth() + staveBar2.getX(), staveBar2.getY(), 50);
staveBar3.setContext(ctx).drawWithStyle();
const notesBar3 = [new StaveNote({ keys: ['d/5'], duration: 'wr' })];
Formatter.FormatAndDraw(ctx, staveBar3, notesBar3);
const staveBar4 = new Stave(staveBar3.getWidth() + staveBar3.getX(), staveBar3.getY(), 250 - staveBar1.getModifierXShift());
staveBar4.setBegBarType(BarlineType.REPEAT_BEGIN);
staveBar4.setEndBarType(BarlineType.REPEAT_END);
staveBar4.setContext(ctx).drawWithStyle();
const notesBar4 = [
new StaveNote({ keys: ['c/4'], duration: 'q' }),
new StaveNote({ keys: ['d/4'], duration: 'q' }),
new StaveNote({ keys: ['b/4'], duration: 'qr' }),
new StaveNote({ keys: ['c/4', 'e/4', 'g/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, staveBar4, notesBar4);
}
function drawEndModifiers(options, contextBuilder) {
options.assert.expect(0);
const staveWidth = 230;
const blockHeight = 80;
let x = 10;
let y = 0;
const ctx = contextBuilder(options.elementId, 800, 700);
function drawStavesInTwoLines(endBarLine) {
function drawStave(x, y, width, begMods, endMods) {
const staveBar = new Stave(x, y, width - 10);
if (begMods) {
if (begMods.barLine !== undefined) {
staveBar.setBegBarType(begMods.barLine);
}
if (begMods.clef !== undefined) {
staveBar.addClef(begMods.clef);
}
if (begMods.keySig !== undefined) {
staveBar.addKeySignature(begMods.keySig);
}
if (begMods.timeSig !== undefined) {
staveBar.setTimeSignature(begMods.timeSig);
}
}
if (endMods) {
if (endMods.barLine !== undefined) {
staveBar.setEndBarType(endMods.barLine);
}
if (endMods.clef !== undefined) {
staveBar.addEndClef(endMods.clef);
}
if (endMods.keySig !== undefined) {
staveBar.setEndKeySignature(endMods.keySig);
}
if (endMods.timeSig !== undefined) {
staveBar.setEndTimeSignature(endMods.timeSig);
}
}
staveBar.setContext(ctx).drawWithStyle();
const notesBar = [
new StaveNote({ keys: ['c/4'], duration: 'q' }),
new StaveNote({ keys: ['d/4'], duration: 'q' }),
new StaveNote({ keys: ['b/4'], duration: 'qr' }),
new StaveNote({ keys: ['c/4', 'e/4', 'g/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, staveBar, notesBar);
}
drawStave(x, y, staveWidth + 50, { barLine: BarlineType.REPEAT_BEGIN, clef: 'treble', keySig: 'A' }, { barLine: endBarLine, clef: 'bass' });
x += staveWidth + 50;
drawStave(x, y, staveWidth, { barLine: BarlineType.REPEAT_BEGIN }, { barLine: endBarLine, keySig: 'E' });
x += staveWidth;
drawStave(x, y, staveWidth, { barLine: BarlineType.REPEAT_BEGIN }, { barLine: endBarLine, timeSig: '2/4' });
x += staveWidth;
x = 10;
y += blockHeight;
drawStave(x, y, staveWidth, { barLine: BarlineType.REPEAT_BEGIN }, { barLine: endBarLine, clef: 'bass', timeSig: '2/4' });
x += staveWidth;
drawStave(x, y, staveWidth, { barLine: BarlineType.REPEAT_BEGIN }, { barLine: endBarLine, clef: 'treble', keySig: 'Ab' });
x += staveWidth;
drawStave(x, y, staveWidth, { barLine: BarlineType.REPEAT_BEGIN }, { barLine: endBarLine, clef: 'bass', keySig: 'Ab', timeSig: '2/4' });
x += staveWidth;
}
y = 0;
x = 10;
drawStavesInTwoLines(BarlineType.SINGLE);
y += blockHeight + 10;
x = 10;
drawStavesInTwoLines(BarlineType.DOUBLE);
y += blockHeight + 10;
x = 10;
drawStavesInTwoLines(BarlineType.REPEAT_END);
y += blockHeight + 10;
x = 10;
drawStavesInTwoLines(BarlineType.REPEAT_BOTH);
}
function drawStaveRepetition(options, contextBuilder) {
options.assert.expect(0);
const ctx = contextBuilder(options.elementId, 725, 200);
const mm1 = new Stave(10, 50, 150);
mm1.addClef('treble');
mm1.setRepetitionType(Repetition.type.DS_AL_FINE, options.params.yShift);
mm1.setMeasure(1);
mm1.setContext(ctx).drawWithStyle();
const notesmm1 = [
new StaveNote({ keys: ['a/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['a/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, mm1, notesmm1);
const mm2 = new Stave(mm1.getWidth() + mm1.getX(), mm1.getY(), 150);
mm2.setRepetitionType(Repetition.type.TO_CODA, options.params.yShift);
mm2.setMeasure(2);
mm2.setContext(ctx).drawWithStyle();
const notesmm2 = [
new StaveNote({ keys: ['a/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['a/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, mm2, notesmm2);
const mm3 = new Stave(mm2.getWidth() + mm2.getX(), mm1.getY(), 150);
mm3.setRepetitionType(Repetition.type.DS_AL_CODA, options.params.yShift);
mm3.setMeasure(3);
mm3.setContext(ctx).drawWithStyle();
const notesmm3 = [
new StaveNote({ keys: ['a/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['a/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, mm3, notesmm3);
const mm4 = new Stave(mm3.getWidth() + mm3.getX(), mm1.getY(), 150);
mm4.setRepetitionType(Repetition.type.CODA_LEFT, options.params.yShift);
mm4.setMeasure(4);
mm4.setContext(ctx).drawWithStyle();
const notesmm4 = [
new StaveNote({ keys: ['a/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['f/4'], duration: 'q' }),
new StaveNote({ keys: ['a/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, mm4, notesmm4);
}
function drawVolta(options, contextBuilder) {
options.assert.expect(0);
const ctx = contextBuilder(options.elementId, 725, 200);
const mm1 = new Stave(10, 50, 125);
mm1.setBegBarType(BarlineType.REPEAT_BEGIN);
mm1.setRepetitionType(Repetition.type.SEGNO_LEFT);
mm1.addClef('treble');
mm1.addKeySignature('A');
mm1.setMeasure(1);
mm1.addModifier(new StaveSection('A'));
mm1.setContext(ctx).drawWithStyle();
const notesmm1 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm1, notesmm1);
const mm2 = new Stave(mm1.getWidth() + mm1.getX(), mm1.getY(), 60);
mm2.setRepetitionType(Repetition.type.CODA_RIGHT);
mm2.setMeasure(2);
mm2.setContext(ctx).drawWithStyle();
const notesmm2 = [new StaveNote({ keys: ['d/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm2, notesmm2);
const mm3 = new Stave(mm2.getWidth() + mm2.getX(), mm1.getY(), 60);
mm3.setVoltaType(VoltaType.BEGIN, '1.', -5);
mm3.setMeasure(3);
mm3.setContext(ctx).drawWithStyle();
const notesmm3 = [new StaveNote({ keys: ['e/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm3, notesmm3);
const mm4 = new Stave(mm3.getWidth() + mm3.getX(), mm1.getY(), 60);
mm4.setVoltaType(VoltaType.MID, '', -5);
mm4.setMeasure(4);
mm4.setContext(ctx).drawWithStyle();
const notesmm4 = [new StaveNote({ keys: ['f/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm4, notesmm4);
const mm5 = new Stave(mm4.getWidth() + mm4.getX(), mm1.getY(), 60);
mm5.setEndBarType(BarlineType.REPEAT_END);
mm5.setVoltaType(VoltaType.END, '', -5);
mm5.setMeasure(5);
mm5.setContext(ctx).drawWithStyle();
const notesmm5 = [new StaveNote({ keys: ['g/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm5, notesmm5);
const mm6 = new Stave(mm5.getWidth() + mm5.getX(), mm1.getY(), 60);
mm6.setVoltaType(VoltaType.BEGIN_END, '2.', -5);
mm6.setEndBarType(BarlineType.DOUBLE);
mm6.setMeasure(6);
mm6.setContext(ctx).drawWithStyle();
const notesmm6 = [new StaveNote({ keys: ['a/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm6, notesmm6);
const mm7 = new Stave(mm6.getWidth() + mm6.getX(), mm1.getY(), 60);
mm7.setMeasure(7);
mm7.addModifier(new StaveSection('B').setPadding(4));
mm7.setContext(ctx).drawWithStyle();
const notesmm7 = [new StaveNote({ keys: ['b/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm7, notesmm7);
const mm8 = new Stave(mm7.getWidth() + mm7.getX(), mm1.getY(), 60);
mm8.setEndBarType(BarlineType.DOUBLE);
mm8.setRepetitionType(Repetition.type.DS_AL_CODA);
mm8.setMeasure(8);
mm8.setContext(ctx).drawWithStyle();
const notesmm8 = [new StaveNote({ keys: ['c/5'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm8, notesmm8);
const mm9 = new Stave(mm8.getWidth() + mm8.getX() + 20, mm1.getY(), 125);
mm9.setEndBarType(BarlineType.END);
mm9.setRepetitionType(Repetition.type.CODA_LEFT);
mm9.addClef('treble');
mm9.addKeySignature('A');
mm9.setMeasure(9);
mm9.setContext(ctx).drawWithStyle();
const notesmm9 = [new StaveNote({ keys: ['d/5'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm9, notesmm9);
}
function drawVoltaModifier(options, contextBuilder) {
options.assert.expect(0);
const ctx = contextBuilder(options.elementId, 1100, 200);
const mm1 = new Stave(10, 50, 175);
mm1.setBegBarType(BarlineType.REPEAT_BEGIN);
mm1.setVoltaType(VoltaType.BEGIN_END, '1.', -5);
mm1.addClef('treble');
mm1.addKeySignature('A');
mm1.setMeasure(1);
mm1.setSection('A', 0);
mm1.setContext(ctx).drawWithStyle();
const notesmm1 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm1, notesmm1);
const mm2 = new Stave(mm1.getX() + mm1.getWidth(), mm1.getY(), 175);
mm2.setBegBarType(BarlineType.REPEAT_BEGIN);
mm2.setRepetitionType(Repetition.type.DS);
mm2.setVoltaType(VoltaType.BEGIN, '2.', -5);
mm2.addClef('treble');
mm2.addKeySignature('A');
mm2.setMeasure(2);
mm2.setContext(ctx).drawWithStyle();
const notesmm2 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm2, notesmm2);
const mm3 = new Stave(mm2.getX() + mm2.getWidth(), mm2.getY(), 175);
mm3.setVoltaType(VoltaType.MID, '', -5);
mm3.setRepetitionType(Repetition.type.DS);
mm3.addClef('treble');
mm3.addKeySignature('B');
mm3.setMeasure(3);
mm3.setSection('B', 0);
mm3.setContext(ctx).drawWithStyle();
const notesmm3 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm3, notesmm3);
const mm4 = new Stave(mm3.getX() + mm3.getWidth(), mm3.getY(), 175);
mm4.setVoltaType(VoltaType.END, '1.', -5);
mm4.setRepetitionType(Repetition.type.DS);
mm4.addClef('treble');
mm4.addKeySignature('A');
mm4.setMeasure(4);
mm4.setSection('C', 0);
mm4.setContext(ctx).drawWithStyle();
const notesmm4 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm4, notesmm4);
const mm5 = new Stave(mm4.getX() + mm4.getWidth(), mm4.getY(), 175);
mm5.setEndBarType(BarlineType.DOUBLE);
mm5.setRepetitionType(Repetition.type.DS);
mm5.addClef('treble');
mm5.addKeySignature('A');
mm5.setMeasure(5);
mm5.addModifier(new StaveSection('D'));
mm5.setContext(ctx).drawWithStyle();
const notesmm5 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm5, notesmm5);
const mm6 = new Stave(mm5.getX() + mm5.getWidth(), mm5.getY(), 175);
mm6.setRepetitionType(Repetition.type.DS);
mm6.setMeasure(6);
mm6.addModifier(new StaveSection('E'));
mm6.setContext(ctx).drawWithStyle();
const notesmm6 = [new StaveNote({ keys: ['c/4'], duration: 'w' })];
Formatter.FormatAndDraw(ctx, mm6, notesmm6);
}
function drawTempo(options, contextBuilder) {
options.assert.expect(0);
const ctx = contextBuilder(options.elementId, 725, 350);
const padding = 10;
let x = 0;
let y = 50;
function drawTempoStaveBar(width, tempo, tempoY, notes) {
const staveBar = new Stave(padding + x, y, width);
if (x === 0)
staveBar.addClef('treble');
staveBar.setTempo(tempo, tempoY);
staveBar.setContext(ctx).drawWithStyle();
const notesBar = notes || [
new StaveNote({ keys: ['c/4'], duration: 'q' }),
new StaveNote({ keys: ['d/4'], duration: 'q' }),
new StaveNote({ keys: ['b/4'], duration: 'q' }),
new StaveNote({ keys: ['c/4'], duration: 'q' }),
];
Formatter.FormatAndDraw(ctx, staveBar, notesBar);
x += width;
}
drawTempoStaveBar(120, { duration: 'q', dots: 1, bpm: '80-90' }, 0);
drawTempoStaveBar(100, { duration: '8', dots: 2, bpm: 90 }, 0);
drawTempoStaveBar(100, { duration: '16', dots: 1, bpm: 96 }, 0);
drawTempoStaveBar(100, { duration: '32', bpm: 70 }, 0);
drawTempoStaveBar(250, { name: 'Andante', duration: 'q', bpm: 120 }, -20, [
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/5'], duration: '8' }),
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
]);
x = 0;
y += 150;
drawTempoStaveBar(120, { duration: 'w', bpm: 80 }, 0);
drawTempoStaveBar(100, { duration: 'h', duration2: 'q', dots2: 1 }, 0);
drawTempoStaveBar(100, { duration: 'q', dots: 1, duration2: 'h', parenthesis: true }, 0);
drawTempoStaveBar(100, { duration: '8', bpm: 70 }, 0);
drawTempoStaveBar(250, { name: 'Andante grazioso' }, 0, [
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
new StaveNote({ keys: ['c/4'], duration: '8' }),
new StaveNote({ keys: ['d/4'], duration: '8' }),
new StaveNote({ keys: ['g/4'], duration: '8' }),
new StaveNote({ keys: ['e/4'], duration: '8' }),
]);
}
function configureSingleLine(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 400, 120);
const stave = new Stave(10, 10, 300);
stave
.setConfigForLine(0, { visible: true })
.setConfigForLine(1, { visible: false })
.setConfigForLine(2, { visible: true })
.setConfigForLine(3, { visible: false })
.setConfigForLine(4, { visible: true });
stave.setContext(ctx).drawWithStyle();
const config = stave.getConfigForLines();
options.assert.equal(config[0].visible, true, 'getLinesConfiguration() - Line 0');
options.assert.equal(config[1].visible, false, 'getLinesConfiguration() - Line 1');
options.assert.equal(config[2].visible, true, 'getLinesConfiguration() - Line 2');
options.assert.equal(config[3].visible, false, 'getLinesConfiguration() - Line 3');
options.assert.equal(config[4].visible, true, 'getLinesConfiguration() - Line 4');
options.assert.ok(true, 'all pass');
}
function configureAllLines(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 400, 120);
const stave = new Stave(10, 10, 300);
stave
.setConfigForLines([{ visible: false }, {}, { visible: false }, { visible: true }, { visible: false }])
.setContext(ctx)
.drawWithStyle();
const config = stave.getConfigForLines();
options.assert.equal(config[0].visible, false, 'getLinesConfiguration() - Line 0');
options.assert.equal(config[1].visible, true, 'getLinesConfiguration() - Line 1');
options.assert.equal(config[2].visible, false, 'getLinesConfiguration() - Line 2');
options.assert.equal(config[3].visible, true, 'getLinesConfiguration() - Line 3');
options.assert.equal(config[4].visible, false, 'getLinesConfiguration() - Line 4');
options.assert.ok(true, 'all pass');
}
function drawStaveText(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 900, 140);
const stave = new Stave(300, 10, 300);
stave.setStaveText('Violin', Modifier.Position.LEFT);
stave.setStaveText('Right Text', Modifier.Position.RIGHT);
stave.setStaveText('Above Text', Modifier.Position.ABOVE);
stave.setStaveText('Below Text', Modifier.Position.BELOW);
stave.setContext(ctx).drawWithStyle();
options.assert.ok(true, 'all pass');
}
function drawStaveTextMultiLine(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 900, 200);
const stave = new Stave(300, 40, 300);
stave.setStaveText('Violin', Modifier.Position.LEFT, { shiftY: -10 });
stave.setStaveText('2nd line', Modifier.Position.LEFT, { shiftY: 10 });
stave.setStaveText('Right Text', Modifier.Position.RIGHT, { shiftY: -10 });
stave.setStaveText('2nd line', Modifier.Position.RIGHT, { shiftY: 10 });
stave.setStaveText('Above Text', Modifier.Position.ABOVE, { shiftY: -10 });
stave.setStaveText('2nd line', Modifier.Position.ABOVE, { shiftY: 10 });
stave.setStaveText('Left Below Text', Modifier.Position.BELOW, {
shiftY: -10,
justification: TextJustification.LEFT,
});
stave.setStaveText('Right Below Text', Modifier.Position.BELOW, {
shiftY: 10,
justification: TextJustification.RIGHT,
});
stave.setContext(ctx).drawWithStyle();
options.assert.ok(true, 'all pass');
}
function factoryAPI(options) {
const f = VexFlowTests.makeFactory(options, 900, 200);
const stave = f.Stave({ x: 300, y: 40, width: 300 });
stave.setStaveText('Violin', Modifier.Position.LEFT, { shiftY: -10 });
stave.setStaveText('2nd line', Modifier.Position.LEFT, { shiftY: 10 });
f.draw();
options.assert.ok(true, 'all pass');
}
VexFlowTests.register(StaveTests);
export { StaveTests };