@11111110b. Enjoy the show!
Step 1: The Basics
Lets start with a quick example. Below, we have a canvas created with the following code:
Here's what it looks like.In the above code first create a rendering context from the canvas element. This rendering context gives VexFlow a consistent 2D drawing interface, which is modeled on HTML5 Canvas. We then create a new
<canvas width=700 height=100"></canvas>Let's draw an empty treble stave on this canvas with VexFlow.
Here's what it looks like.
0, 0with a width of
500pixels. We pass the context to the stave and call
draw, which renders the stave on the context. Notice that the stave is not exactly drawn in position
0, 0. This is because it reserves some head-room for higher notes.
Step 2: Add Some Notes
Adding notes to the stave is a slightly more involved process. To understand the code, you need to understand the data model of the renderer. A
Notice how the notes are justified evenly on the stave based on the duration of each note? This is the formatter in action - keeping voices aligned, while balancing the spacing between the notes. Lets add another voice to this tune.
StaveNoteis a set of notes that belong on a stem. It can be a single note, or a chord. Its stem can be up, or down. All
StaveNoteinstances have an associated duration. These
StaveNotes are grouped into a
Voice. Voices have a time signature, and the set of notes in the voice (including the rests) must utilize all beats in the voice. So, a 4/4 voice with only three quarter-notes is invalid - you'll need to add another quarter note or rest. Voices are grouped into
VoiceGroups. This is particularly useful when you have multi-voice music. Upon rendering, the notes in each voice of the group aligned on the stave. A
VoiceGroupmust contain at least one voice. Finally, you have a
Formatter, which takes a voice group and justifies the voices based on configurable rules, so that all the voices in the group look pretty on the stave. In the code below, we create a voice with two notes and a chord, and render it on the stave.
Step 3: All About Modifiers
Modifiers are essentially decorators that are attached to notes. They include
Annotations etc. Modifiers for a single group of notes live inside a
ModifierContext. This allows them to intelligently juxtapose themselves based on other modifiers in the context. For example, a chord consisting of two close-by notes, each having accidentals, needs to position the accidentals such that they don't clash. Let's add some accidentals and dots.
- We don't want to couple rendering logic with notational logic.
- The API user has the final say for what should and should not be displayed.
FormatAndDrawhelper function to create a 4/4 voice out of the notes, justify it to the stave, and render all of it. Lets add a few more modifiers and see how they position themselves.
Step 3.5: An InterludeWe've covered a bit of ground here, and you're probably asking for lists of valid note names, accidentals, durations, etc., that you can use with the API. Fortunately for you, there's a canonical location where this stuff is kept.
Vex.Flow.keyProperties.note_values- The list of valid note names.
Vex.Flow.accidentalCodes.accidentals- The list of valid accidental names.
Vex.Flow.keySignatures.keySpecs- The list of valid keys.
Vex.Flow.durationToTicks- The list of valid duration codes.
Step 4: Beams and Ties
VexFlow can beam your notes for you, but only if you ask it to. The
In the above example, we created three groups of notes with beams. The slope of the beams is a function of the direction of the music, and the number of beams for each group is dependent on the duration of the notes underneath.
And there you have ties and beams!
Beamclass, when passed a set of contiguous notes (in a shared voice), is responsible for rendering beams based on the durations of each contained note. Let's create a melody.
Tieing notes involves a similar set of operations. To render a tie, you create a
StaveTieinstance, and pass it the two
StaveNotes to tie together. Since each
StaveNotecan be a chord, you also need to pass in the indices of the specific notes you want to tie. For example:
Step 5: Guitar Tablature
VexFlow can also render guitar tablature. The mechanics for displaying tabs are the same as those for standard notation, except that you use different classes for staves and notes. Let's write some tab.
Above, we replaced
TabNote. We also added some bend and vibrato modifiers. There are two things we have to manually specify here -- the font style, and the background fill color. The former is used to display fret numbers, annotations, and other text. The latter is only required for the SVG backend (although using it with Canvas is harmless), and is used to create an internal implementation of
clearRect. A custom
clearRectis required to clear sections of the canvas. This is not supported by SVG because it has no "clear" semantics.