Backstory: I have a kid learning to play the clarinet in a music conservatory, which involves compulsory sight reading classes. Teaching for sight reading is done on books. The idea for this app is to port the method online, so that it's easier to practice and follow one's progress. It should also be more fun, and, for those so inclined, competitive.
The learning method is based on landmarks: for each clef one first learns the position of 2-3 landmarks, and then each note is in relation to a landmark. So for example, if you know where the middle G is on the treble clef, then you can learn fast that 2 positions up (next line) is B, and two positions down is E. (Anecdotally, in an earlier iteration of the app, landmark notes were displayed using specific colors; but users learned colors instead of the note position on the staff, and when they moved to a level without colors (or an actual score) they were completely lost.)
The app doesn't try to teach keyboard playing, or fingering for any other instrument for that matter. It only helps associate the position of a note on the staff with a name, in a given clef. It doesn't deal with octaves: a C3 is a C4 is a C; or accidentals: a sharp G is a flat G is a G. It also doesn't wait for user input, as other apps do. Music doesn't work that way; but more importantly, the point is to learn to recognize intervals instantly, not count them.
No account is necessary to use the app, only to participate in the leaderboard, and save one's score in case of device reset (or to use more than one device). When an account is created, the data is stored on the server in SQLite; I'm curious to see how far it can go. (Without an account, no data leaves the device.)
It's still a little rough around the edges but should work ok in reasonably recent browsers. On the client side, it uses VexFlow to display notes, staff and clefs, but animations are done using CSS transitions (not JS), to be mobile friendly. Tone.js helps provide a more accurate timing than a simple setInterval. Icons are coded in SVG by hand; for simple shapes, this is surprisingly fun and straightforward to do.
I’m working on a WebMIDI based wait-for-input piano/keyboard app, like Flowkey, but bring your own music with MusicXML files.
Works amazingly well, using OpenSheetMusicDisplay lib for parsing MusicXML, rendering it to SVG (OSMD uses VexFlow under the covers) & using OSMD to map the music data into my own data model (I track everything I need for timing and visual x,y coordinates inside the SVG).
From there it’s pretty simple, just refactoring my hacky PoC I’ve been using for myself for the last year into something solid based on React + XState.
Anyways, OSMD would let you import arbitrary music as input to this, opening up the possibility of learning specific pieces