Friday Fork: Colorful Language

/Friday Fork /Code /Javascript /PHP

I’m currently working on little project which will require unique colors for various points of data. Since the data points can be anything from “bran flakes” to “Yahtzee” I decided that it would be better to have the words themselves act as the generators of the color which would represent them. I figured that in ASCII all letters are just numbers so I could come up with a system which would conver the words into HSL CSS values. I wrote through my ideas quickly in PHP so I could easily script their output for testing. I then translated the function to Javascript, which I have published as a Gist called “Colorful Language”.

Check out the demo on Codepen.

Here are some examples:
The world's first 3D-printed kayak is adorably colorful. An article from Gizmodo.

I’m not completely happy with it but for the first attempt at executing something that popped into my head at 4am, I’m pretty happy with it. I would like to see greater variation in the saturation levels and luminosity, though, so I’ll have to keep tweaking it.

Algorithms

As you can see in the embedded Gist below, I invented three calculations based on the mix of letters in the word. I use each of these algorithms to calculate each of the attributes of the color. Below are simplified versions of the algorithms. I use pseudo-Javascript syntax in the examples. If you want to see the actual function scroll down to the Gist below.

Hue

If you’re unfamiliar, the hue value is based on a 360 rainbow. 0° is red, 120° is green, 240° is blue, and 360° is back to red. I start my calculation of the hue by changing the starting point from 0°. I do this by taking just the first letter of the word, calculating what percentage “through” the alphabet that letter is, and multiplying that by 360°. An example with the letter “F” (the 6th letter in the alphabet):

Math.floor(6/26*360) = 83;

83° is lime green. We then start spinning the wheel from there. For this I use the ASCII value of the letter. Since the ASCII alphabet starts at 65 (for uppercase letters), I simply add the ASCII value of each letter, minus 64, to the hue rotation value. Let’s say we type the word “flying”:

//hue = 83 see example above
hue += 102-64; //121
hue += 108-64; //165
hue += 121-64; //222
hue += 105-64; //263
hue += 110-64; //309
hue += 103-64; //348

I then perform a modulo on the hue variable to ensure that our final value is between 0-359.

hue = hue % 360;

This doesn’t affect our result in this case so for the word “flying” we end up with a hue value of 348°.

Saturation

Consonants are the meat of a word. Without consonants Theodore Roosevelt would be reduced to “Eooe Ooee”. (Old McDonald had a farm…) Since saturation is what gives colors their kick, I thought it would be a natural fit to use the percentage of consonant saturation to calculate the percentage of color saturation. But, English doesn’t really have words that are all consonants, so we would almost never end up with full saturation, so I had to weight the results. I decided that 95% saturation would be a fine weight. In hindsight, that was probably too high of a bar.

Continuing with our “flying” example:

//"flying" has 5 consonants and 1 vowel
saturation = 5 / 6 / 0.95 * 100; //87.72

Luminosity

I really struggled to come up with a third algorithm for luminosity. I then got thinking about letterforms and had the term “sparkle” come to mind. It’s a phrase that my typography professor at BYU-Idaho used a lot when talking about setting blocks of text. He taught me that different typeface (especially serif typefaces) had a shimmer, or “sparkle”, when viewed from 3 steps back. A lot of that has to do with the shape of the serifs, counters, ascenders, and descenders. (For more info on letterform anatomy, here’s a PDF that has some of the basics.)

In thinking about how they affect the sparkle, I decided that I would treat ascenders as turning up the dimmer, and descenders as turning it down. Luminosity is a little confusing because it is a continuous gradient with three points: black, the hue, and white. So a color with an hsl value of (0, 100%, 50%) is a fully saturated, fully bright red. Adding luminosity to it actually tints it pink. For this reason the starting point of our luminosity calculation isn’t 0% or 100%, it’s 50%. We start with the fully un-tinted color.

I didn’t want to set a fixed value on the increments by which I would be changing the luminosity, so I made it a function of how many letters were in the word. So, for our “flying” example:

increment = 1 / 6 * 50 //8.333

The 1 is because then each letter in the word has an opportunity to increment the value of the luminosity: one letter is worth 8.333% of the luminosity. 50 is used because it takes 50% in either direction (increase or decrease) to reach the limits of the value (0-100%).

Then for every ascender (t, d, b, l, f, h, k) I add the increment to the luminosity value. For every descender (q, y, p, g, j) I subtract the increment x2 from the luminosity value. I did this simply because I was seeing about twice as many ascenders in the words I was using to test (which was a non-scientific keyboard-pounding free-association exercise).

Back to the example:
//"flying" has 2 ascenders ('f' & 'l')
//and 2 descenders ('y' & 'g')
luminosity = 50;
luminosity += increment * 2; //66.667
luminosity -= increment * 2 * 2; //33.333

Conclusion

So, with the current algorithms, for the word “flying” we get the color hsl(348, 87.72%, 33.333%). My Javascript implementation is likely missing some opportunities for streamlining, and my algorithms need tweaking for greater variation in final colors. In order to do this I’ll use a list of the 1,000 most-used English words (or similar) and run an analysis on the variation I get using those 1,000 words, rather than the first 30 that pop into my head.

Gist

Share on: /facebook /twitter /google+

comments powered by Disqus