-
Notifications
You must be signed in to change notification settings - Fork 662
Chord Symbols and Chord Changes
In VexFlow, the ChordSymbol module can create chord change symbols, like you'd see in a jazz or pop fake book.
To do this, it formats musical symbols (glyphs) from the rendering engine alongside ordinary text, which requires information about the text font you're using. Chord symbols will work best if you use one of the fonts that VexFlow already knows about. Instructions for adding additional text fonts can be found later in this guide.
First we'll create a couple of chord symbols using the default browser-safe fonts. Note: this assumes you have read the VexFlow tutorial section on modifiers
To create a chord symbol and add it to a note:
const chord = new ChordSymbol()
.setFontSize(14)
.addText("B")
.addGlyph("b")
.addText("7", { symbolModifier: SymbolModifiers.SUPERSCRIPT })
.addGlyph("(", { symbolModifier: SymbolModifiers.SUPERSCRIPT })
.addGlyph("b", { symbolModifier: SymbolModifiers.SUPERSCRIPT })
.addText("5", { symbolModifier: SymbolModifiers.SUPERSCRIPT })
.addGlyph(")", { symbolModifier: SymbolModifiers.SUPERSCRIPT });
staveNote.addModifier(chord);
In the example above, we told VexFlow to create a chord with: the letter 'B' for the key, the glyph corresponding with the flat symbol, and the chord extension 7(♭5)
in superscript. See this example.
Instead of calling addText()
or addGlyph()
for every single character, we can let VexFlow automatically select between glyphs and text:
const chord = new ChordSymbol().setFontSize(10).addGlyphOrText("Bb").addGlyphOrText("7(b5)", { symbolModifier: SymbolModifiers.SUPERSCRIPT });
staveNote.addModifier(chord);
VexFlow automatically uses the flat symbol for 'b', the parentheses symbols ( and ), and text for the numbers and note names. ChordSymbol
currently supports 15 symbols:
+ - ( ) b # /
result in the expected symbols, and other symbols can be specified explicitly with addGlyph(...)
:
'diminished', 'halfDiminished', 'leftParenTall', 'rightParenTall', 'majorSeventh', 'leftBracket', 'rightBracket'
You can see the ChordSymbol unit tests for more details.
Using the built in browser fonts works, but there are some issues. For example, the spacing between symbols isn't correct. Using a supported web font will fix this.
The ChordSymbol
module supports two external web fonts for text (see: Font.loadWebFonts()
).
VexFlow chooses a text font to match the current music engraving font. If you use the music font Petaluma, the default text font is PetalumaScript. For Bravura and Gonville music fonts, VexFlow uses Roboto Slab. The music fonts are provided under the SIL Open Font License. Roboto Slab is licensed under the Apache License 2.0.
To use these web fonts, call:
await Vex.Flow.Font.loadWebFonts();
or with Promises:
Vex.Flow.Font.loadWebFonts().then(() => {
// Web fonts loaded.
});
Depending on the music engraving font, VexFlow uses either 'Roboto Slab' or 'PetalumaScript', and falls back to 'Times' or 'Arial' if necessary. You can also set the font explicitly for each chord:
const chord = new ChordSymbol().setFont("Roboto Slab", 15).addGlyphOrText("Bb7");
Take a look at this example:
We now have chord symbols with nicer formatting.
The last few examples show a superscript. As you'd expect, SymbolModifiers.SUBSCRIPT
gives you subscript. If you do superscript immediately followed by a subscript, the logic will align them stack them vertically. See this example.
You can put leftParenTall
and rightParenTall
on either side of the superscript/subscript to get parenthesis on the full vertical extent of the chord.
const chord = new ChordSymbol()
.addGlyphOrText("D")
.addGlyph("leftParenTall")
.addGlyphOrText("6", { symbolModifier: SymbolModifiers.SUPERSCRIPT })
.addGlyphOrText("9", { symbolModifier: SymbolModifiers.SUBSCRIPT })
.addGlyph("rightParenTall")
.setFontSize(14);
If you have a /
or csymDiagonalArrangementSlash
symbol in your chord, VexFlow will condense your chord by moving the left part up and to the right, and the right part down and to the left. This allows you to render slash chords, like C/G or C/E or D/F♯:
const slashChord = new ChordSymbol().addGlyphOrText("C").addGlyph("majorSeventh", { symbolModifier: SymbolModifiers.SUPERSCRIPT }).addGlyphOrText("/F");
Chords can be positioned: left/right/center of the note (horizontally) or above and below the note (vertically). Below may work nicely for notation such as figured bass. See this example:
chords.push(new ChordSymbol().setVertical("bottom").addText("I").addTextSuperscript("6").addTextSubscript("4"));
// ...
chords.push(new ChordSymbol().addLine(12).setVertical("bottom"));
You can also double stack on the top or the bottom. See the unit test cases for an example.
Try out these techniques in the ChordSymbol sandbox.
Just like with the browser default fonts, you can specify any font you want. But you might have issues with the formatting, because VexFlow will still be using metrics for the default fonts. Most English fonts have a similar vertical baseline, but the horizontal spacing between the letters might vary, especially for longer strings or more florid typefaces.
Here's an example of using a font called Concert One. The formatting is a bit uneven, but for this example, at least, it works.
Load the web font with CSS:
@import url("https://fonts.googleapis.com/css2?family=Concert+One&display=swap");
Create a chord symbol object and set the font:
const chord = new ChordSymbol().addGlyphOrText("Ab").addGlyph("dim", { symbolModifier: SymbolModifiers.SUPERSCRIPT }).setFont("Concert One", 14, "normal");
The same VexFlow tools that extract glyphs from the music fonts can be used to extract the metrics from any OpenType text font:
- Download the font you like, and use a utility such as Font Squirrel to create a .otf (OpenType font) file.
- Place the file in the project directory
vexflow/tools/fonts/
, and run thefontgen_text.js
script. This will produce a .ts file with the formatting you want. For example:
node fontgen_text.js MyFont.otf myfont_glyphs.ts
- Move the
myfont_glyphs.ts
file tosrc/fonts/
, next to the other font glyphs files (petalumascript_glyphs.ts and robotoslab_glyphs.ts). - Update
src/fonts/textfonts.ts
to load the new font. - Optionally update elements to use the new text font by default. For example,
chordsymbol.ts
has aTEXT_FONT
property that returns its default text font.
Note: advanceWidth
and leftSideBearing
are the only metrics used currently.
[ VexFlow.com ] [ API ] [ GitHub Repo ] [ Contributors ]