-
Notifications
You must be signed in to change notification settings - Fork 676
Chord Symbols and Chord Changes
In VexFlow, the chord change 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. To do that, it needs to know detailed information about the text font you're using. So chord changes will work best if you use one of the fonts that VexFlow knows about. Instructions for doing this, and 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 chord1 = 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 });
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 an example.
The example below shows how you can let VexFlow automatically select between glyphs and text:
const chord2 = new ChordSymbol().setFontSize(10).addGlyphOrText("Bb").addGlyphOrText("7(b5)", { symbolModifier: SymbolModifiers.SUPERSCRIPT });
staveNote.addModifier(chord2);
VexFlow automatically uses the flat symbol for 'b', the parentheses symbols ( and ), and text for the numbers and note names.
ChordSymbol
supports 15 symbols at present:
+ - ( ) 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.
What we've done so far looks kind of 'meh. The smaller image is a bit blurry, and the spacing between the notes isn't correct - this will cause problems for more complex formatting. Using a supported font will fix this.
The ChordSymbol
module supports two external text fonts. The default font used depends on the music engraving font. If you use the music font Petaluma, the default text font is 'PetalumaScript' (both provided by Steinburg Media). Bravura and Gonville music fonts default to RobotoSlab, one of the Roboto family of web fonts provided by Google Fonts [ read more]. The music fonts are provided under the SIL Open Font License [ read more]. Roboto Slab is licensed under the Apache License 2.0.
To use the fonts, the simplest way is to call:
await Vex.Flow.Font.loadWebFonts();
Depending on the music engraving font, VexFlow either use 'Roboto Slab' or 'PetalumaScript', and fall back to 'Times' or 'Arial' respectively. 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:
That looks better. Now that we have fonts with some good formatting, we can do some more practical applications.
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 vertically and stack them. See this example.
Try out the techniques in this sandbox.
You can put leftParenTall
and rightParenTall
on either side of the super/subscripts to get parenthesis on the full vertical extent of the chord.
var chord3 = new VF.ChordSymbol()
.addGlyphOrText("D")
.addGlyph("leftParenTall")
.addGlyphOrText("6", { symbolModifier: VF.ChordSymbol.symbolModifiers.SUPERSCRIPT })
.addGlyphOrText("9", { symbolModifier: VF.ChordSymbol.symbolModifiers.SUBSCRIPT })
.addGlyph("rightParenTall")
.setFontSize(14);
If you have a 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.
Just like with the browser default fonts, you can use any font you want. But you might have issues with the formatting, because VexFlow will still be using the metrics for the default fonts. Most English fonts will have a similar vertical baseline, but the 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 ]