vexflow
Version:
A JavaScript library for rendering music notation and guitar tablature
296 lines (240 loc) • 10.5 kB
JavaScript
/**
* VexFlow - NoteSubGroup Tests
* Copyright Mohit Muthanna 2010 <mohit@muthanna.com>
*
* Author Taehoon Moon 2016
*/
VF.Test.NoteSubGroup = (function() {
var NoteSubGroup = {
Start: function() {
var run = VF.Test.runTests;
QUnit.module('NoteSubGroup');
run('Basic - ClefNote, TimeSigNote and BarNote', VF.Test.NoteSubGroup.draw);
run('Multi Voice', VF.Test.NoteSubGroup.drawMultiVoice);
run('Multi Voice Multiple Draws', VF.Test.NoteSubGroup.drawMultiVoiceMultipleDraw);
run('Multi Staff', VF.Test.NoteSubGroup.drawMultiStaff);
},
draw: function(options) {
var vf = VF.Test.makeFactory(options, 750, 200);
var ctx = vf.getContext();
var stave = vf.Stave({ width: 600 }).addClef('treble');
var notes = [
{ keys: ['f/5'], stem_direction: -1, duration: '4' },
{ keys: ['d/4'], stem_direction: -1, duration: '4', clef: 'bass' },
{ keys: ['g/4'], stem_direction: -1, duration: '4', clef: 'alto' },
{ keys: ['a/4'], stem_direction: -1, duration: '4', clef: 'alto' },
{ keys: ['c/4'], stem_direction: -1, duration: '4', clef: 'tenor' },
{ keys: ['c/3'], stem_direction: +1, duration: '4', clef: 'tenor' },
{ keys: ['d/4'], stem_direction: -1, duration: '4', clef: 'tenor' },
{ keys: ['f/4'], stem_direction: -1, duration: '4', clef: 'tenor' },
].map(vf.StaveNote.bind(vf));
function addAccidental(note, acc) {
return note.addModifier(0, vf.Accidental({ type: acc }));
}
function addSubGroup(note, subNotes) {
return note.addModifier(0, vf.NoteSubGroup({ notes: subNotes }));
}
// {SubNotes} | {Accidental} | {StaveNote}
addAccidental(notes[1], '#');
addAccidental(notes[2], 'n');
addSubGroup(notes[1], [
vf.ClefNote({ type: 'bass', options: { size: 'small' } }),
]);
addSubGroup(notes[2], [
vf.ClefNote({ type: 'alto', options: { size: 'small' } }),
]);
addSubGroup(notes[4], [
vf.ClefNote({ type: 'tenor', options: { size: 'small' } }),
new VF.BarNote(),
]);
addSubGroup(notes[5], [
vf.TimeSigNote({ time: '6/8' }),
]);
addSubGroup(notes[6], [
new VF.BarNote(VF.Barline.type.REPEAT_BEGIN),
]);
addAccidental(notes[4], 'b');
addAccidental(notes[6], 'bb');
var voice = vf.Voice().setStrict(false).addTickables(notes);
vf.Formatter()
.joinVoices([voice])
.formatToStave([voice], stave);
vf.draw();
notes.forEach(function(note) {
Vex.Flow.Test.plotNoteWidth(ctx, note, 150);
});
Vex.Flow.Test.plotLegendForNoteWidth(ctx, 620, 120);
ok(true, 'all pass');
},
drawMultiVoice: function(options) {
var vf = VF.Test.makeFactory(options, 550, 200);
var ctx = vf.getContext();
var stave = vf.Stave().addClef('treble');
var notes1 = [
{ keys: ['f/5'], stem_direction: 1, duration: '4' },
{ keys: ['d/4'], stem_direction: 1, duration: '4', clef: 'bass' },
{ keys: ['c/5'], stem_direction: 1, duration: '4', clef: 'alto' },
{ keys: ['c/5'], stem_direction: 1, duration: '4', clef: 'soprano' },
].map(vf.StaveNote.bind(vf));
var notes2 = [
{ keys: ['c/4'], stem_direction: -1, duration: '4' },
{ keys: ['c/3'], stem_direction: -1, duration: '4', clef: 'bass' },
{ keys: ['d/4'], stem_direction: -1, duration: '4', clef: 'alto' },
{ keys: ['f/4'], stem_direction: -1, duration: '4', clef: 'soprano' },
].map(vf.StaveNote.bind(vf));
function addAccidental(note, accid) {
return note.addModifier(0, vf.Accidental({ type: accid }));
}
function addSubGroup(note, subNotes) {
return note.addModifier(0, vf.NoteSubGroup({ notes: subNotes }));
}
addAccidental(notes1[1], '#');
addSubGroup(notes1[1], [
vf.ClefNote({ type: 'bass', options: { size: 'small' } }),
new VF.BarNote(VF.Barline.type.REPEAT_BEGIN),
vf.TimeSigNote({ time: '3/4' }),
]);
addSubGroup(notes2[2], [
vf.ClefNote({ type: 'alto', options: { size: 'small' } }),
vf.TimeSigNote({ time: '9/8' }),
new VF.BarNote(VF.Barline.type.DOUBLE),
]);
addSubGroup(notes1[3], [
vf.ClefNote({ type: 'soprano', options: { size: 'small' } }),
]);
addAccidental(notes1[2], 'b');
addAccidental(notes2[3], '#');
var voices = [
vf.Voice().addTickables(notes1),
vf.Voice().addTickables(notes2),
];
vf.Formatter()
.joinVoices(voices)
.formatToStave(voices, stave);
vf.draw();
notes1.forEach(function(note) {
Vex.Flow.Test.plotNoteWidth(ctx, note, 150);
});
ok(true, 'all pass');
},
// draws multiple times. prevents incremental x-shift each draw.
drawMultiVoiceMultipleDraw: function(options) {
var vf = VF.Test.makeFactory(options, 550, 200);
var ctx = vf.getContext();
var stave = vf.Stave().addClef('treble');
var notes1 = [
{ keys: ['f/5'], stem_direction: 1, duration: '4' },
{ keys: ['d/4'], stem_direction: 1, duration: '4', clef: 'bass' },
{ keys: ['c/5'], stem_direction: 1, duration: '4', clef: 'alto' },
{ keys: ['c/5'], stem_direction: 1, duration: '4', clef: 'soprano' },
].map(vf.StaveNote.bind(vf));
var notes2 = [
{ keys: ['c/4'], stem_direction: -1, duration: '4' },
{ keys: ['c/3'], stem_direction: -1, duration: '4', clef: 'bass' },
{ keys: ['d/4'], stem_direction: -1, duration: '4', clef: 'alto' },
{ keys: ['f/4'], stem_direction: -1, duration: '4', clef: 'soprano' },
].map(vf.StaveNote.bind(vf));
function addAccidental(note, accid) {
return note.addModifier(0, vf.Accidental({ type: accid }));
}
function addSubGroup(note, subNotes) {
return note.addModifier(0, vf.NoteSubGroup({ notes: subNotes }));
}
addAccidental(notes1[1], '#');
addSubGroup(notes1[1], [
vf.ClefNote({ type: 'bass', options: { size: 'small' } }),
new VF.BarNote(VF.Barline.type.REPEAT_BEGIN),
vf.TimeSigNote({ time: '3/4' }),
]);
addSubGroup(notes2[2], [
vf.ClefNote({ type: 'alto', options: { size: 'small' } }),
vf.TimeSigNote({ time: '9/8' }),
new VF.BarNote(VF.Barline.type.DOUBLE),
]);
addSubGroup(notes1[3], [
vf.ClefNote({ type: 'soprano', options: { size: 'small' } }),
]);
addAccidental(notes1[2], 'b');
addAccidental(notes2[3], '#');
var voices = [
vf.Voice().addTickables(notes1),
vf.Voice().addTickables(notes2),
];
vf.Formatter()
.joinVoices(voices)
.formatToStave(voices, stave);
vf.draw();
vf.draw();
notes1.forEach(function(note) {
Vex.Flow.Test.plotNoteWidth(ctx, note, 150);
});
ok(true, 'all pass');
},
drawMultiStaff: function(options) {
var vf = VF.Test.makeFactory(options, 550, 400);
vf.StaveNote = vf.StaveNote.bind(vf);
var stave1 = vf.Stave({ x: 15, y: 30, width: 500 }).setClef('treble');
var notes1 = [
{ keys: ['f/5'], stem_direction: 1, duration: '4' },
{ keys: ['d/4'], stem_direction: 1, duration: '4', clef: 'bass' },
{ keys: ['c/5'], stem_direction: 1, duration: '4', clef: 'alto' },
{ keys: ['c/5'], stem_direction: 1, duration: '4', clef: 'soprano' },
].map(vf.StaveNote);
var notes2 = [
{ keys: ['c/4'], stem_direction: -1, duration: '4' },
{ keys: ['c/3'], stem_direction: -1, duration: '4', clef: 'bass' },
{ keys: ['d/4'], stem_direction: -1, duration: '4', clef: 'alto' },
{ keys: ['f/4'], stem_direction: -1, duration: '4', clef: 'soprano' },
].map(vf.StaveNote);
var stave2 = vf.Stave({ x: 15, y: 150, width: 500 }).setClef('bass');
var notes3 = [
{ keys: ['e/3'], duration: '8', stem_direction: -1, clef: 'bass' },
{ keys: ['g/4'], duration: '8', stem_direction: 1, clef: 'treble' },
{ keys: ['d/4'], duration: '8', stem_direction: 1, clef: 'treble' },
{ keys: ['f/4'], duration: '8', stem_direction: 1, clef: 'treble' },
{ keys: ['c/4'], duration: '8', stem_direction: 1, clef: 'treble' },
{ keys: ['g/3'], duration: '8', stem_direction: -1, clef: 'bass' },
{ keys: ['d/3'], duration: '8', stem_direction: -1, clef: 'bass' },
{ keys: ['f/3'], duration: '8', stem_direction: -1, clef: 'bass' },
].map(vf.StaveNote);
vf.StaveConnector({ top_stave: stave1, bottom_stave: stave2, type: 'brace' });
vf.StaveConnector({ top_stave: stave1, bottom_stave: stave2, type: 'singleLeft' });
vf.StaveConnector({ top_stave: stave1, bottom_stave: stave2, type: 'singleRight' });
function addAccidental(note, acc) {
return note.addModifier(0, vf.Accidental({ type: acc }));
}
function addSubGroup(note, subNotes) {
return note.addModifier(0, vf.NoteSubGroup({ notes: subNotes }));
}
vf.Beam({ notes: notes3.slice(1, 4) });
vf.Beam({ notes: notes3.slice(5) });
addAccidental(notes1[1], '#');
addSubGroup(notes1[1], [
vf.ClefNote({ type: 'bass', options: { size: 'small' } }),
vf.TimeSigNote({ time: '3/4' }),
]);
addSubGroup(notes2[2], [
vf.ClefNote({ type: 'alto', options: { size: 'small' } }),
vf.TimeSigNote({ time: '9/8' }),
]);
addSubGroup(notes1[3], [vf.ClefNote({ type: 'soprano', options: { size: 'small' } })]);
addSubGroup(notes3[1], [vf.ClefNote({ type: 'treble', options: { size: 'small' } })]);
addSubGroup(notes3[5], [vf.ClefNote({ type: 'bass', options: { size: 'small' } })]);
addAccidental(notes3[0], '#');
addAccidental(notes3[3], 'b');
addAccidental(notes3[5], '#');
addAccidental(notes1[2], 'b');
addAccidental(notes2[3], '#');
var voice = vf.Voice().addTickables(notes1);
var voice2 = vf.Voice().addTickables(notes2);
var voice3 = vf.Voice().addTickables(notes3);
vf.Formatter()
.joinVoices([voice, voice2])
.joinVoices([voice3])
.formatToStave([voice, voice2, voice3], stave1);
vf.draw();
ok(true, 'all pass');
},
};
return NoteSubGroup;
})();