The game plan
You have an introduction to what we're going to build, and you've thought through some of the features, so you have a pretty good idea of the goal. Let's get a game plan together for how we're going to tackle the task of building it.
Organizing the files
- musicbox.js: This file will contain the window.onload function, as well as some simple controller code. The controller code is what helps direct things to happen when you interact with the interface.
- View.js: This file will contain all the code related to the view. That means all the code to handle clicks on the canvas, drawing on the canvas, and animating the circles.
- BufferLoader.js: This file will contain the code to load the audio samples. We won't go into a huge amount of detail on this code, but just enough so you know how it works.
- Audio.js: And finally, this file will contain the code to play the audio samples. We'll coordinate playing a sample with animating a circle from the view code.
Notice that conceptual structure similar to a well-known design pattern: the model-view-controller (MVC for short). In this project, our model is an array holding audio samples, which is created and loaded by the code in BufferLoader.js, and then used by the code in Audio.js. The view is our HTML, CSS, and canvas, and primarily it's the canvas. All the code to manage the view is in View.js. Our controller is a bit more spread out: we'll have some code in musicbox.js to define how we'll handle clicks, but the rest of the controller code will be in a method in the View. We'll point out these components as we get to them.
Techniques for keeping code modular
We're going to use a couple of different techniques in this project for "modularizing" code. That just means we're going to build the code so that all the related functions are grouped together into objects. So, all the view code is grouped into a View object, all the sample loading code is grouped together into a BufferLoader object, and all the audio playing code is grouped together into an Audio object. As you can see these modules also correspond to the files we're creating.
We'll use two techniques to do this: one is to create an object using an object literal, with properties and methods in the object all related to a particular function of the code. The second technique is to use a constructor function that will create an object, again, with properties and methods related to a particular function of the code. We'll dig into the details of why we choose one or the other as we get to each object.
Okay, that's the plan! Let's get going.