While working on a project for creative tools for musicians, I found myself in need of an easy way to allow users to input musical ideas into a vue application. Having a lot of experience with the piano-roll type of interface that you often find in a digital audio workstation (DAW), I decided to create a component that would allow users to create and edit musical ideas in a simple and intuitive way.
I also wanted to make sure that the component was highly customizable and flexible.
export interface PianoRollProps {
zoomX?: number;
zoomY?: number;
rangeBottom?: OctaveNote;
rangeTop?: OctaveNote;
currentBeat?: number;
currentTick?: number;
ticksPerBeat?: number;
defaultNoteLength?: number;
noteHeight?: number;
modelValue: PianoRollNote[];
length?: number | "infinite";
loop?: boolean;
noteColor?: string;
backgroundColor?: string;
incidentalColor?: string;
gridColor?: string;
labelColor?: string;
labelIncidentalColor?: string;
labelBackgroundColor?: string;
labelBorderColor?: string;
borderWidth?: number;
shadowColor?: string;
shadowMap?: ShadowMap[];
onNoteEvent?: (event: NoteEvent) => void;
}
The component uses the v-model
directive to allow two-way note-data binding between the component and its parent. Which means that the note values can be easily accessed to manipulate the data in the parent component or to be used for playback with any audio library or processed and exported to a file format such as MIDI.
// GMajor Triad
[
{
"id": 3,
"start": 0,
"length": 1,
"note": "D3",
"velocity": 100,
"color": "#f43f5f",
"selected": false
},
{
"id": 2,
"start": 0,
"length": 1,
"note": "B2",
"velocity": 100,
"color": "#f43f5f",
"selected": true
},
{
"id": 1,
"start": 0,
"length": 1,
"note": "G2",
"velocity": 100,
"color": "#f43f5f",
"selected": false
}
]
The example above is interactive, so, you can try it out by dragging existing notes, clicking to add notes, right-clicking to delete existing notes, or dragging the edges of notes to resize them. You can also have a look at the Demo hosted on Netlify where you can change the tempo, the instrument, and inspect the component's output.