We will be implementing a fairly simple HSL Color Picker and accompanying drawing board canvas for painting. The Color Picker will be composed of three ranged inputs (one for Hue, one for Saturation, and one for Luminance). These values can be composed easily to a string representation of an HSL value, which we can use to paint a canvas element displaying our currently selected color. We’ll also add another ranged selector for brush size. With the combination of brush size and color, we can then do some rudimentary painting activity on our other canvas.
A SPA Digression
Before we do any coding, let’s talk about Single Page Applications in general.
Like with most development topics there is probably some debate about the specific technical definition of a Single Page Application. Generally speaking, though, the “Single Page” being referred to is a web page. However, instead of the older server-side approach to navigating between many different server generated pages to accomplish tasks and obtain information, SPA navigation (and routing) takes place within the page itself, dynamically generating content from templates and AJAX-sourced state. Within the context of a SPA, URLs no longer map to HTML or PHP (or JSP, or what have you) files on the server, but rather to actions and application state as understood by the SPA itself.
We won’t really have any routing to speak of in any of our implementations. We will mostly be concerned with functionality of our proposed feature. However, be aware that routing is a very important topic when it comes to SPAs, and a partial basis for their evaluation when determining what framework to choose. Also note that you can do templated SPA routing in vanilla JS.
High-Level SPA Architecture
Since we are only implementing one feature, there are many SPA related topics that we will not broach:
- Routing (or route parameters, abstract routing, route resolution, etc.)
- Asynchrony (just use Promises)
- REST (or related pedantry)
- Build tools (unless absolutely necessary)
We will mostly be concerned with state: storing state, retrieving state, representing state, updating state, initializing state, etc.
Modeling Our State
We really only need two variables to accomplish what we want:
- A primitive integer representation of our brush size
- A more complex color object representing the individual HSL values
Any actions the user can perform will either use these values (directly or through derived calculations) or set these values. This will be true across all of our implementations, and serve as our jumping off point.
Now that we have a basis for our discussion, in the next article we will begin to unravel our vanilla JS implementation.