Last active
October 13, 2021 21:10
-
-
Save trezy/be8058b6a9c3e21c71d57a0b7c83e877 to your computer and use it in GitHub Desktop.
Uses the first character of a string to choose a color within a range. Can take a color pair, otherwise defaults to to full color spectrum.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const strings = [ | |
'Fruit', // #0002ee | |
'Blorp', // #0000a2 | |
'Fig', // #0002ee | |
'Bridge', // #0000a2 | |
'Macintosh', // #0006f3 | |
'Apple', // #00000f | |
'Speakers', // #000a65 | |
'Stream', // #000a65 | |
] | |
const colorRange = [ | |
'#f00', // red | |
'#00f', // blue | |
] | |
strings.forEach(string => { | |
// Generates a color for {string} within {colorRange} | |
getColorForString(string, colorRange) | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Constants | |
const POSSIBLE_HEX_LENGTHS = [3, 6] | |
/** | |
* Uses the first character of a string to choose a color within a range. Can | |
* take a color pair, otherwise defaults to to full color spectrum. | |
* | |
* @param {string} string The input string | |
* @param {[string, string]} [colorRange=[0x000000, 0xffffff]] The range within which colors should be generated. This will be broken into 26 steps (one for each letter of the alphabet) | |
* | |
* @returns {string} A hex color string within the specified range | |
*/ | |
export function getColorForString (string, colorRange = [0x000000, 0xffffff]) { | |
if (!Array.isArray(colorRange)) { | |
throw new TypeError(`colorRange must be an array with at least 2 items; received ${typeof colorRange}`) | |
} | |
if (colorRange.length !== 2) { | |
throw new RangeError(`colorRange must be a pair; received an array with ${colorRange.length} items`) | |
} | |
// Lowercase the string (upper vs lowercase letters have different char | |
// codes), then get the charcode of the first character | |
const charCode = string.toLowerCase().charCodeAt(0) | |
// Offset the index by 97 (which is the char code for lowercase a) | |
const index = charCode - 97 | |
// Ensure the color range is a hex literal | |
const colorValues = colorRange.map(value => { | |
let parsedValue = value | |
if (typeof parsedValue === 'string') { | |
const hexValue = parsedValue.trim().replace(/^#/, '') | |
if (!POSSIBLE_HEX_LENGTHS.includes(hexValue.length)) { | |
throw new TypeError(`${value} is not a valid color code`) | |
} | |
parsedValue = parseInt(hexValue, 16) | |
} | |
if (typeof parsedValue === 'number') { | |
if ((parsedValue <= 0x000000) && (parsedValue >= 0xffffff)) { | |
throw new RangeError(`${value} is not within range; must be between 0x000000 and 0xffffff`) | |
} | |
return parsedValue | |
} | |
throw new TypeError(`Can't parse ${value} into a color code`) | |
}) | |
// Convert the color range to a mathematical upper limit | |
const highValue = Math.max(colorValues[0]) | |
const lowValue = Math.min(colorValues[1]) | |
const range = highValue - lowValue | |
// Determine the increment between color values | |
const increment = Math.round(range / 26) | |
// Calculate where the string sits within the specified range | |
const rangeValue = index * increment | |
const resultValue = lowValue + rangeValue | |
// Convert the resulting integer to a hex string, then pad with 0 in case | |
// it's not a full 6 digits | |
const resultHexValue = resultValue.toString(16).padStart(6, '0') | |
// Add an octothorpe to the front of the string for use in CSS | |
return `#${resultHexValue}` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment