Development case study

Vue Piano Roll

Vue Piano Roll is a flexible piano roll component for creating and editing musical notes.

Role
Creator & maintainer
Timeframe
2022—present
Status
Published open-source component

Challenge

Make a familiar DAW interaction feel immediate in the browser while keeping its API flexible for other applications.

Outcome

A configurable Vue piano-roll component, published on npm with a live, editable demonstration.

Disciplines

Music tooling · Component design · Developer experience

Tools & materials

Vue · Nuxt · TypeScript · Web Audio

Overview

While working on a project of 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.

Component API

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 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,
  },
];

Try it

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.