UNPKG

vexflow

Version:

A JavaScript library for rendering music notation and guitar tablature

342 lines (288 loc) 16.1 kB
/** * VexFlow - Articulation Tests * Copyright Mohit Muthanna 2010 <mohit@muthanna.com> */ var VF = Vex.Flow; VF.Test.Articulation = (function() { var Articulation = { Start: function() { QUnit.module('Articulation'); Articulation.runTests('Articulation - Staccato/Staccatissimo', 'a.', 'av', Articulation.drawArticulations); Articulation.runTests('Articulation - Accent/Tenuto', 'a>', 'a-', Articulation.drawArticulations); Articulation.runTests('Articulation - Marcato/L.H. Pizzicato', 'a^', 'a+', Articulation.drawArticulations); Articulation.runTests('Articulation - Snap Pizzicato/Fermata', 'ao', 'ao', Articulation.drawArticulations); Articulation.runTests('Articulation - Up-stroke/Down-Stroke', 'a|', 'am', Articulation.drawArticulations); Articulation.runTests('Articulation - Fermata Above/Below', 'a@a', 'a@u', Articulation.drawFermata); Articulation.runTests('Articulation - Inline/Multiple', 'a.', 'a.', Articulation.drawArticulations2); Articulation.runTests('TabNote Articulation', 'a.', 'a.', Articulation.tabNotes); }, runTests: function(name, sym1, sym2, func) { var params = { sym1: sym1, sym2: sym2, }; VF.Test.runTests(name, func, params); }, drawArticulations: function(options, contextBuilder) { var sym1 = options.params.sym1; var sym2 = options.params.sym2; expect(0); // Get the rendering context var ctx = contextBuilder(options.elementId, 625, 195); // bar 1 var staveBar1 = new VF.Stave(10, 30, 125); staveBar1.setContext(ctx).draw(); var notesBar1 = [ new VF.StaveNote({ keys: ['a/3'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/4'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/4'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/4'], duration: 'q', stem_direction: 1 }), ]; notesBar1[0].addArticulation(0, new VF.Articulation(sym1).setPosition(4)); notesBar1[1].addArticulation(0, new VF.Articulation(sym1).setPosition(4)); notesBar1[2].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar1[3].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar1, notesBar1); // bar 2 - juxtaposing second bar next to first bar var staveBar2 = new VF.Stave(staveBar1.width + staveBar1.x, staveBar1.y, 125); staveBar2.setEndBarType(VF.Barline.type.DOUBLE); staveBar2.setContext(ctx).draw(); var notesBar2 = [ new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), ]; notesBar2[0].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar2[1].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar2[2].addArticulation(0, new VF.Articulation(sym1).setPosition(4)); notesBar2[3].addArticulation(0, new VF.Articulation(sym1).setPosition(4)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar2, notesBar2); // bar 3 - juxtaposing second bar next to first bar var staveBar3 = new VF.Stave(staveBar2.width + staveBar2.x, staveBar2.y, 125); staveBar3.setContext(ctx).draw(); var notesBar3 = [ new VF.StaveNote({ keys: ['c/4'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/4'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/4'], duration: 'q', stem_direction: 1 }), ]; notesBar3[0].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); notesBar3[1].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); notesBar3[2].addArticulation(0, new VF.Articulation(sym2).setPosition(3)); notesBar3[3].addArticulation(0, new VF.Articulation(sym2).setPosition(3)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar3, notesBar3); // bar 4 - juxtaposing second bar next to first bar var staveBar4 = new VF.Stave(staveBar3.width + staveBar3.x, staveBar3.y, 125); staveBar4.setEndBarType(VF.Barline.type.END); staveBar4.setContext(ctx).draw(); var notesBar4 = [ new VF.StaveNote({ keys: ['a/4'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), ]; notesBar4[0].addArticulation(0, new VF.Articulation(sym2).setPosition(3)); notesBar4[1].addArticulation(0, new VF.Articulation(sym2).setPosition(3)); notesBar4[2].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); notesBar4[3].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar4, notesBar4); }, drawFermata: function(options, contextBuilder) { var sym1 = options.params.sym1; var sym2 = options.params.sym2; expect(0); // Get the rendering context var ctx = contextBuilder(options.elementId, 400, 200); // bar 1 var staveBar1 = new VF.Stave(50, 30, 150); staveBar1.setContext(ctx).draw(); var notesBar1 = [ new VF.StaveNote({ keys: ['c/4'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/4'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/4'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/4'], duration: 'q', stem_direction: -1 }), ]; notesBar1[0].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar1[1].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar1[2].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); notesBar1[3].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar1, notesBar1); // bar 2 - juxtaposing second bar next to first bar var staveBar2 = new VF.Stave(staveBar1.width + staveBar1.x, staveBar1.y, 150); staveBar2.setEndBarType(VF.Barline.type.DOUBLE); staveBar2.setContext(ctx).draw(); var notesBar2 = [ new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), ]; notesBar2[0].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar2[1].addArticulation(0, new VF.Articulation(sym1).setPosition(3)); notesBar2[2].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); notesBar2[3].addArticulation(0, new VF.Articulation(sym2).setPosition(4)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar2, notesBar2); }, drawArticulations2: function(options, contextBuilder) { expect(0); // Get the rendering context var ctx = contextBuilder(options.elementId, 1000, 200); // bar 1 var staveBar1 = new VF.Stave(10, 30, 350); staveBar1.setContext(ctx).draw(); var notesBar1 = [ new VF.StaveNote({ keys: ['c/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['d/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['e/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['f/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['g/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['b/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/5'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['d/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['e/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['f/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['g/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['b/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['c/6'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['d/6'], duration: '16', stem_direction: -1 }), ]; var i; for (i = 0; i < 16; i++) { notesBar1[i].addArticulation(0, new VF.Articulation('a.').setPosition(4)); notesBar1[i].addArticulation(0, new VF.Articulation('a>').setPosition(4)); if (i === 15) { notesBar1[i].addArticulation(0, new VF.Articulation('a@u').setPosition(4)); } } var beam1 = new VF.Beam(notesBar1.slice(0, 8)); var beam2 = new VF.Beam(notesBar1.slice(8, 16)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar1, notesBar1); beam1.setContext(ctx).draw(); beam2.setContext(ctx).draw(); // bar 2 - juxtaposing second bar next to first bar var staveBar2 = new VF.Stave(staveBar1.width + staveBar1.x, staveBar1.y, 350); staveBar2.setContext(ctx).draw(); var notesBar2 = [ new VF.StaveNote({ keys: ['f/3'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['g/3'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['a/3'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['b/3'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['c/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['d/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['e/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['f/4'], duration: '16', stem_direction: 1 }), new VF.StaveNote({ keys: ['g/4'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/4'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['b/4'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['c/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['d/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['e/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['f/5'], duration: '16', stem_direction: -1 }), new VF.StaveNote({ keys: ['g/5'], duration: '16', stem_direction: -1 }), ]; for (i = 0; i < 16; i++) { notesBar2[i].addArticulation(0, new VF.Articulation('a-').setPosition(3)); notesBar2[i].addArticulation(0, new VF.Articulation('a^').setPosition(3)); if (i === 15) { notesBar2[i].addArticulation(0, new VF.Articulation('a@u').setPosition(4)); } } var beam3 = new VF.Beam(notesBar2.slice(0, 8)); var beam4 = new VF.Beam(notesBar2.slice(8, 16)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar2, notesBar2); beam3.setContext(ctx).draw(); beam4.setContext(ctx).draw(); // bar 3 - juxtaposing second bar next to first bar var staveBar3 = new VF.Stave(staveBar2.width + staveBar2.x, staveBar2.y, 75); staveBar3.setContext(ctx).draw(); var notesBar3 = [ new VF.StaveNote({ keys: ['c/4'], duration: 'w', stem_direction: 1 }), ]; notesBar3[0].addArticulation(0, new VF.Articulation('a-').setPosition(3)); notesBar3[0].addArticulation(0, new VF.Articulation('a>').setPosition(3)); notesBar3[0].addArticulation(0, new VF.Articulation('a@a').setPosition(3)); // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar3, notesBar3); // bar 4 - juxtaposing second bar next to first bar var staveBar4 = new VF.Stave(staveBar3.width + staveBar3.x, staveBar3.y, 150); staveBar4.setEndBarType(VF.Barline.type.END); staveBar4.setContext(ctx).draw(); var notesBar4 = [ new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['c/5'], duration: 'q', stem_direction: -1 }), new VF.StaveNote({ keys: ['a/5'], duration: 'q', stem_direction: -1 }), ]; for (i = 0; i < 4; i++) { var position1 = 3; if (i > 1) { position1 = 4; } notesBar4[i].addArticulation(0, new VF.Articulation('a-').setPosition(position1)); } // Helper function to justify and draw a 4/4 voice VF.Formatter.FormatAndDraw(ctx, staveBar4, notesBar4); }, tabNotes: function(options, contextBuilder) { var ctx = new contextBuilder(options.elementId, 600, 200); ctx.font = '10pt Arial'; var stave = new VF.TabStave(10, 10, 550); stave.setContext(ctx); stave.draw(); var specs = [ { positions: [{ str: 3, fret: 6 }, { str: 4, fret: 25 }], duration: '8' }, { positions: [{ str: 2, fret: 10 }, { str: 5, fret: 12 }], duration: '8' }, { positions: [{ str: 1, fret: 6 }, { str: 3, fret: 5 }], duration: '8' }, { positions: [{ str: 1, fret: 6 }, { str: 3, fret: 5 }], duration: '8' }, ]; var notes = specs.map(function(noteSpec) { var tabNote = new VF.TabNote(noteSpec); tabNote.render_options.draw_stem = true; return tabNote; }); var notes2 = specs.map(function(noteSpec) { var tabNote = new VF.TabNote(noteSpec); tabNote.render_options.draw_stem = true; tabNote.setStemDirection(-1); return tabNote; }); var notes3 = specs.map(function(noteSpec) { var tabNote = new VF.TabNote(noteSpec); return tabNote; }); notes[0].addModifier(new VF.Articulation('a>').setPosition(3), 0); // U notes[1].addModifier(new VF.Articulation('a>').setPosition(4), 0); // D notes[2].addModifier(new VF.Articulation('a.').setPosition(3), 0); // U notes[3].addModifier(new VF.Articulation('a.').setPosition(4), 0); // D notes2[0].addModifier(new VF.Articulation('a>').setPosition(3), 0); notes2[1].addModifier(new VF.Articulation('a>').setPosition(4), 0); notes2[2].addModifier(new VF.Articulation('a.').setPosition(3), 0); notes2[3].addModifier(new VF.Articulation('a.').setPosition(4), 0); notes3[0].addModifier(new VF.Articulation('a>').setPosition(3), 0); notes3[1].addModifier(new VF.Articulation('a>').setPosition(4), 0); notes3[2].addModifier(new VF.Articulation('a.').setPosition(3), 0); notes3[3].addModifier(new VF.Articulation('a.').setPosition(4), 0); var voice = new VF.Voice(VF.Test.TIME4_4).setMode(VF.Voice.Mode.SOFT); voice.addTickables(notes); voice.addTickables(notes2); voice.addTickables(notes3); new VF.Formatter() .joinVoices([voice]) .formatToStave([voice], stave); voice.draw(ctx, stave); ok(true, 'TabNotes successfully drawn'); }, }; return Articulation; }());