February 6th, 2017. Tagged: JavaScript, Music, react, tools

Here's my new tool called intervals


Play with it here.

Learn about the theory behind it here.

The code for the tool.

What does it do?

Generates a random music interval, shows it on the musical staff. You try to guess it. Clicking on the staff reveals the answer. You can also play the interval.

How was it built?

It's a React app. What's React? Get the best React book and find out 🙂

But these days you don't need to start a React app from scratch (as described in the book), you have create-react-app which generates a new app and sets up all auxiliary tools you need. Furthermore, you don't need to start a new app from an empty canvas, you can start building off of a template, thanks to CRAFT.

The template used is flashcards.

So to get an app like this off the ground you go:

$ npm i -g create-react-app
$ npm i -g craftool
$ craft intervals
$ cd intervals
$ npm install .
$ npm start

Tada! Sudden flashcard app, ready to go. All you need to do is implement the functions getAnswer() and getQuestion().

This is a bit of a specialized app, so no need to go into the gory details of the Questions and Answers. But overall:

  1. generate a random first note. e.g. F♯ on the third octave
  2. generate a random interval, e.g. a perfect forth
  3. use teoria to give you the correct second note, given a start note and an interval
  4. draw the two on the staff using Vex
  5. play the notes
  6. random pretty-printing and conversion from my note conventions to teoria to vex

Weirdness and hacks


Vex wants to draw an SVG inside a DOM element. (AFAIK. There may be better APIs I did not uncover.)

So I draw the SVG in a hidden div then copy it over to React, like so:

  <div dangerouslySetInnerHTML={{__html: someSVG.outerHTML}} />

Ooooh, danger!


Sometimes (rarely!) in all this randomness either teoria or vex deserts me. I think I worked out most of the kinks but still... I have a try-catch that simply generates another random question. This is pretty bad as it can theoretically freeze the browser if it fails to generate a valid question but in my testing it hasn't happened. And sometimes you gotta do what you gotta do 🙂

Playing audio

No WebAudio, just the ole new Audio(url).play(). I play the first note, subscribe to its ended event, play the second, subscribe to its ended and play both. Awesome. Here it goes.

Except iPhone still refuses to play without human intervention, so I just play both together when iPhone is detected.

Thanks for reading!

I hope you learned a quick and easy way to create quiz apps. And also learned there's a place you can go to practice them intervals.

Tell your friends about this post on Facebook and Twitter

Sorry, comments disabled and hidden due to excessive spam.

Meanwhile, hit me up on twitter @stoyanstefanov