The last couple of years, we’ve been working on mobile applications on the IoT department. In one of those cases, we had a task to provide a way for the users to control their smart bulbs through the application. What we noticed is the lack of packages that allow you to use a colour wheel/ picker.

Fast forward a year, I thought about showing you how you can create a colour wheel component in react that allows you to select a colour from the wheel and returns the rgb value of that colour.

Without further ado, let’s get started.

The first thing we have to create is the component class and its constructor.
Inside the constructor, we have to add the three options our colour wheel will feature, which are:

  • width: the width of our colour wheel
  • height: same as width, but on height
  • img: the colour wheel image for the picker

We want to be able to pass these options as props in our ColourWheel component, but in case we don’t we have to define the default options for our component to fall back to.

In order to be able to select a colour from an image, we have to put it inside a canvas. Let’s go ahead and create a canvas element inside the render function of our component.

Set the dimensions of the canvas, by leveraging the width and height options we defined earlier. Furthermore, since it’s going to be a colour wheel, need to set the border radius to 100%. Also, let’s make it more interesting by changing the cursor to a crosshair when we hover above it.

Last but not least, we need to add a way to reference the canvas in our component methods, same thing as we query DOM elements by their class of id, but in react, we use the ref prop. Go ahead and set the ref prop to “canvas”.

Next, we need a way to show the colour wheel image inside the canvas. To do that, we need to create a new HTMLImageElement, require the image we want to show and draw it inside the canvas.

Since we want this to happen when our component loads, we will invoke this function inside the componentDidMount lifecycle hook.

If everything went well, you should see colour wheel when you refresh the page. With that in place, we can add a way to get the selected colour when the user clicks and drags their mouse inside the image.

The first step here is to add three more event listener props to our canvas component inside the render function. Those are:

  • onMouseDown: will register when the user clicks and holds inside the canvas and will set a flag that the user is dragging the mouse
  • onMouseMove: will pass the event object inside the function that will get the colour. It will run only if the flag set previously is true
  • onMouseUp: Will set the dragging flag to false.

As mentioned, we want to get the selected colour only if the user clicks and drags their mouse inside the colour wheel image, for this reason, we set a flag to true/ false inside the onMouseDown and onMouseUp event listeners. We do this by setting the `dragging` property of the state when those events happen.

The last step that remains is the most important one. We will create a function that will get the colour of the pixel at the position our mouse pointer is.

The first thing to check before running this function, is if the `dragging` flag is set to true in the state. If it is, we access the nativeEvent object from the event, and get the offsetX and offsetY properties.

Now that we know where our mouse pointer is in relation to the image, we can invoke the getImageData function from the canvas context and pass the x, y attributes that we just got. This function will return a data array that contains the values we need in order to construct the RGB colour. Specifically, it holds 4 values, [red, green, blue, opacity], with the first three being numbers between 0 and 255 and the fourth one being between 0 and 1. We will use only the first three to construct a string that will give us the complete RGB colour.

When we have the colour, we can pass it in a callback function in order to return it to the parent component and use it.

This concludes our ColourWheel component. Below you can find the complete code.

You can import it in your project and use it like below:

<ColourWheel
  width={250}
  callback={color=>this.setState({ color })}
/>
Lefteris

Lefteris

Lefteris is a frontend developer. He spends most of his day writing code in react native for our mobile applications while drinking coffee and telling bad jokes that only he laughs to. He also feels weird writing about himself in third person.

Leave a Reply

We are a software house!

A place that we gather all together to build, test and ship software for high demanding clients.

Our headquarters

Ipirou 16
Drama, 66100
Greece

T: +30 2521 105247
E: [email protected]