Intro
I recently designed a color utility application using Electron. Electron is a JavaScript framework for building cross-platform desktop apps. I learned that when it comes to coding, color and math are joined at the hip. This article summarizes some of my takeaways.
benjaminadk / color-tool-remix
Color Tool Remix 🎨 A cross platform color utility app
Color Tool Remix
An HSL color picker, dropper, color analyzer and palette generator. The do it all color tool.
🧐 Looking for a contributor to help testing on macOS
.
Contents
Installation
Platform | Auto Updates | Exexutable |
---|---|---|
Windows | yes | electron-picker-remix-setup-[VERSION].exe |
macOS | no | electron-picker-remix-setup-[VERSION].dmg |
Linux | N/A | N/A |
System warnings are normal due to lack of Code Signing
Usage
Picker
Create a color quickly, via a variety of input methods
-
Color Bars
- Adjust Hue, Saturation, Lightness and Alpha Color Bars
-
Fine Tuning
- Adjust Hue, Saturation, Lightness and Alpha Input Values
-
Color String Parser
- Parses
hsl
,rgb
,hex
andcss named
colors
- Parses
-
Random Color
- Generates a random color excluding white, blacks and greys
-
Dropper
- Select any pixel from the screen
-
Generators
- Mathematically generate colors from one base color
Dropper
Select a single pixel from…
Formats
There is no shortage of color formats floating around. In CSS alone we can chose between 4 formats. Note that 3 of these formats also have an optional alpha
, or opacity setting. To learn about the touching story of rebeccapurple, checkout this short article.
Format | Abbreviation | Example |
---|---|---|
Named Colors | n/a | rebeccapurple |
Hexadecimal | HEX | #663498 |
Red, Green, Blue | RGB | rgb(102,52,152) |
Hue, Saturation, Lightness | HSL | hsl(270,49%,40%) |
In my day-to-day work I tend to favor HEX or RGB over the others. However, when designing Color Tool I used HSL as my base format.
HSL Benefits
I found that HSL was the most human-understandable color format. Why? Take a closer look at each component of this format. Hue is a number between 0 and 360, and represents degrees on a color wheel. In no other format does one value give us some much information about what the final color might look like. Red is at 0/360. Saturation is the amount of color vs grey, with 100% being all color and no grey and 0% being all grey and no color. Lightness is another scale between 0 and 100. 0 is totally black and 100 is totally white, therefore 50 is the happy medium.
Parsing HSL String
In order to work with HSL values we need to be able to take an initial string value, such as hsl(270, 49%, 40%)
, and break it down into individual H, S, L, and/or A pieces.
function parseHSL(str) {
var hsl, h, s, l
hsl = str.replace(/[^\d,]/g, '').split(',') // strip non digits ('%')
h = Number(hsl[0]) // convert to number
s = Number(hsl[1])
l = Number(hsl[2])
return [h, s, l] // return parts
}
Color Harmonies
Color Harmonies are combinations of colors that relate to each other mathematically. Some of the more commonly used harmonies include Complementary
, Split Complementary
, Triadic
, Tetradic
and Analogous
. Lets take it back to rebeccapurple
to see what these look like.
Harmony | Colors | Wheel |
---|---|---|
complementary | ||
split complementary | ||
triadic | ||
tetradic | ||
analogous |
Finding all of these values boils down to math. Using HSL is handy here. We are mostly concerned with the Hue in these calculations. When finding harmonies is these cases we will leave the Saturation and Lightness unchanged. To gain a visual understanding of where on the color wheel harmonies lie take a look at the small icons in the table. These are set patterns and if we know the Hue of our base color and that a circle has 360 degrees we can find our harmonies. For example, a colors complement is directly on the opposite side, or 180 degrees away.
const complementaryHue = (baseHue + 180) % 360
Split complementary produces two colors from the complement +- 30 degrees. At this point I start to think about a function that can work in real life. This function needs to take an actual color string e.g. hsl(34, 100%, 50%)
and return an array with all colors in the harmony. We won't deal with other color formats that require conversion since that is another article itself. We already have our parseHSL
function above so we are off to a good start. The key to this function is that we can look at the split complement as the baseHue + 150
and the baseHue + 210
. In fact all the multiple color harmonies start at a base value(in this case 150) and make x
more colors (in this case 1) at a set interval (in this case 60..gets us to 210😱).
So here we go.
const rp = 'hsl(270, 49%, 40%)'
function harmonize(color, start, end, interval) {
const colors = [color]
const [h, s, l] = parseHSL(color)
for(let i = start; i <= end; i += interval) {
const h1 = (h + i) % 360
const c1 = `hsl(${h1}, ${s}%, ${l}%)`
colors.push(c1)
}
return colors
}
const complement = harmonize(rp, 180, 180, 1)
const split = harmonize(rp, 150, 210, 60)
const triad = harmonize(rp, 120, 240, 120)
const tetrad = harmonize(rp, 90, 270, 90)
const analogous = harmonize(rp, 30, 90, 30)
Now that we armed with some code we can adapt it as an extra feature to spruce up a color picker app.
There are all kinds of interesting functionality combining math and color. A lot of it isn't as complicated as it might seem. I have been playing around with the app in the GIF and I am looking to attract contributors to help with testing and improving the macOS
version and improve the product overall. Thanks.👌
Top comments (2)
Nice share, thank you
ERROR
hsl = str.replace(/[^\d,]/g, '').split(',');
No recoignize decimals