JS: Making a Color Picker from Scratch, part 2

Try it here.

The final product

Last time I went over the basic layout in HTML and CSS. Now I’ll go over creating the gradients and user interaction.

Let’s start by creating a Picker class and assigning all the buttons to associate with. target is the canvas we’ll be using for the main gradient area.

The Hue slider is the easiest part. In the HSL color space, Hue is a value represented in degrees, so it can range from 0 to 359. This is primarily an HSL color picker, so the hue slider is a range slider with those values as its minimum and maximum. To draw the rainbow gradient, it looks like this:

The only reason I’m drawing this in Javascript instead of just assigning the gradient background in CSS is to give me the option of changing the type of color picker later, which isn’t important for most use cases, so it’s up to you which you prefer.

The main area gradient however, is much easier to draw with JS by using a for loop.

Next draw the selector. I’m being stubborn about the pixel style and my code ends up being very verbose here so I’ll spare you, but you could shorten it by just drawing a circle:

To make the selector circle behave like any good color picker does, we can’t simply use event listeners on the canvas itself.

In the initial build function, add these event listeners:

One helper function to update the rest of the color picker according to coordinates we’ll get from these event listeners:

Technically the canvas area is only for choosing saturation and lightness, and the hue is selected using the hue slider.

Mousedown is simple enough. We just use the event offset coordinates. Things get more complicated on mousemove. To keep interacting with the canvas while outside of it, we set a variable to tell if the user is holding the mouse button, this.clicked. So if that variable is true, we can calculate the canvas offset coordinates from the window by calculating how far the canvas element is from the boundaries of the page, then subtracting that value from the page coordinates. Then we can constrain those values so that the selector circle doesn’t go beyond the bounds of the canvas when the mouse is outside the canvas. Instead, it will slide around the border, following the mouse.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store