@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.
Vex.Flow.Stave
positioned at
0, 0
with a width of 500
pixels.
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.
StaveNote
is 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
StaveNote
instances have an associated duration.
These StaveNote
s 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 VoiceGroup
s. 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 VoiceGroup
must 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
Modifier
s are essentially decorators that are
attached to notes. They
include Accidental
s, Vibrato
s,
Dot
s, Annotation
s 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.
FormatAndDraw
helper 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 Interlude
We'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!
Beam
class, 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.
Tie
ing notes involves a similar set of operations. To render
a tie, you create a StaveTie
instance, and pass it the
two StaveNote
s to tie together. Since each
StaveNote
can 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
Stave
with TabStave
and
StaveNote
with 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 clearRect
is required to clear sections of the
canvas. This is not supported by SVG because it has no "clear" semantics.