Last active
November 22, 2024 08:08
-
-
Save akingdom/0a0edd3ea37a9a331983cff3a69c4bee to your computer and use it in GitHub Desktop.
Converts colours between web hex color and an RGBA object.
This file contains 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
// Javascript | |
// Color from a web-style hex string -- for named colors, see https://gist.github.com/akingdom/0a0edd3ea37a9a331983cff3a69c4bee | |
// By Andrew Kingdom | |
// MIT license (use free and do not remove this author's name, etc) | |
// | |
// **Supported string formats**: | |
// - `"fff" // RGB` | |
// - `"#fff" // #RGB` | |
// - `"ffff" // RGBA` | |
// - `"#ffff" // #RGBA` | |
// - `"ffffff" // RRGGBB` | |
// - `"#ffffff" // #RRGGBB` | |
// - `"ffffffff" // RRGGBBAA` | |
// - `"#ffffffff" // #RRGGBBAA` | |
// | |
// The digits represent **R**ed, **G**reen, **B**lue and **A**lpha (like transparency). | |
// | |
function colorfromHex(hex) { | |
var r = 0, g = 0, b = 0, a = 255; | |
var offset = hex.startsWith("#") ? 1 : 0; | |
if (hex.length == 4 + offset) { | |
r = parseInt(hex[offset] + hex[offset], 16); | |
g = parseInt(hex[offset+1] + hex[offset+1], 16); | |
b = parseInt(hex[offset+2] + hex[offset+2], 16); | |
a = parseInt(hex[offset+3] + hex[offset+3], 16); | |
} else if (hex.length == 8 + offset) { | |
a = parseInt(hex[offset+6] + hex[offset+7], 16); | |
r = parseInt(hex[offset] + hex[offset+1], 16); | |
g = parseInt(hex[offset+2] + hex[offset+3], 16); | |
b = parseInt(hex[offset+4] + hex[offset+5], 16); | |
} else if (hex.length == 6 + offset) { | |
r = parseInt(hex[offset] + hex[offset+1], 16); | |
g = parseInt(hex[offset+2] + hex[offset+3], 16); | |
b = parseInt(hex[offset+4] + hex[offset+5], 16); | |
} else { | |
r = g = b = a = 0; | |
} | |
return { r: r, g: g, b: b, a: a }; | |
} | |
function RGBAToHex({r, g, b, a = 255}) { | |
const toHex = (n) => n.toString(16).padStart(2, '0'); | |
return `#${toHex(r)}${toHex(g)}${toHex(b)}${a < 255 ? toHex(a) : ''}`; | |
} | |
// Example usage: | |
console.log(colorfromHex("#ff00ff")); // { r: 255, g: 0, b: 255, a: 255 } | |
const color = { r: 255, g: 0, b: 255, a: 255 }; | |
console.log("Hex:", RGBAToHex(color)); // #ff00ff |
This file contains 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
// Javascript | |
// Color from a web-style hex string with named colors | |
// By Andrew Kingdom | |
// MIT license (use free and do not remove this author's name, etc) | |
// | |
// **Supported string formats**: | |
// - `"fff" // RGB` | |
// - `"#fff" // #RGB` | |
// - `"ffff" // RGBA` | |
// - `"#ffff" // #RGBA` | |
// - `"ffffff" // RRGGBB` | |
// - `"#ffffff" // #RRGGBB` | |
// - `"ffffffff" // RRGGBBAA` | |
// - `"#ffffffff" // #RRGGBBAA` | |
// | |
// The digits represent **R**ed, **G**reen, **B**lue and **A**lpha (like transparency). | |
// | |
// Javascript | |
// Color from a web-style hex string with named colors | |
// By Andrew Kingdom | |
// MIT license (use free and do not remove this author's name, etc) | |
// | |
// **Supported string formats**: | |
// - `"fff" // RGB` | |
// - `"#fff" // #RGB` | |
// - `"ffff" // RGBA` | |
// - `"#ffff" // #RGBA` | |
// - `"ffffff" // RRGGBB` | |
// - `"#ffffff" // #RRGGBB` | |
// - `"ffffffff" // RRGGBBAA` | |
// - `"#ffffffff" // #RRGGBBAA` | |
// | |
// The digits represent **R**ed, **G**reen, **B**lue and **A**lpha (like transparency). | |
// | |
const namedWebColors = { | |
black: "000000", | |
silver: "c0c0c0", | |
gray: "808080", | |
white: "ffffff", | |
maroon: "800000", | |
red: "ff0000", | |
purple: "800080", | |
fuchsia: "ff00ff", | |
green: "008000", | |
lime: "00ff00", | |
olive: "808000", | |
yellow: "ffff00", | |
navy: "000080", | |
blue: "0000ff", | |
teal: "008080", | |
aqua: "00ffff", | |
aliceblue: "f0f8ff", | |
antiquewhite: "faebd7", | |
aquamarine: "7fffd4", | |
azure: "f0ffff", | |
beige: "f5f5dc", | |
bisque: "ffe4c4", | |
blanchedalmond: "ffebcd", | |
blueviolet: "8a2be2", | |
brown: "a52a2a", | |
burlywood: "deb887", | |
cadetblue: "5f9ea0", | |
chartreuse: "7fff00", | |
chocolate: "d2691e", | |
coral: "ff7f50", | |
cornflowerblue: "6495ed", | |
cornsilk: "fff8dc", | |
crimson: "dc143c", | |
cyan: "00ffff", | |
darkblue: "00008b", | |
darkcyan: "008b8b", | |
darkgoldenrod: "b8860b", | |
darkgray: "a9a9a9", | |
darkgreen: "006400", | |
darkgrey: "a9a9a9", | |
darkkhaki: "bdb76b", | |
darkmagenta: "8b008b", | |
darkolivegreen: "556b2f", | |
darkorange: "ff8c00", | |
darkorchid: "9932cc", | |
darkred: "8b0000", | |
darksalmon: "e9967a", | |
darkseagreen: "8fbc8f", | |
darkslateblue: "483d8b", | |
darkslategray: "2f4f4f", | |
darkslategrey: "2f4f4f", | |
darkturquoise: "00ced1", | |
darkviolet: "9400d3", | |
deeppink: "ff1493", | |
deepskyblue: "00bfff", | |
dimgray: "696969", | |
dimgrey: "696969", | |
dodgerblue: "1e90ff", | |
firebrick: "b22222", | |
floralwhite: "fffaf0", | |
forestgreen: "228b22", | |
gainsboro: "dcdcdc", | |
ghostwhite: "f8f8ff", | |
gold: "ffd700", | |
goldenrod: "daa520", | |
greenyellow: "adff2f", | |
honeydew: "f0fff0", | |
hotpink: "ff69b4", | |
indianred: "cd5c5c", | |
indigo: "4b0082", | |
ivory: "fffff0", | |
khaki: "f0e68c", | |
lavender: "e6e6fa", | |
lavenderblush: "fff0f5", | |
lawngreen: "7cfc00", | |
lemonchiffon: "fffacd", | |
lightblue: "add8e6", | |
lightcoral: "f08080", | |
lightcyan: "e0ffff", | |
lightgoldenrodyellow: "fafad2", | |
lightgray: "d3d3d3", | |
lightgreen: "90ee90", | |
lightgrey: "d3d3d3", | |
lightpink: "ffb6c1", | |
lightsalmon: "ffa07a", | |
lightseagreen: "20b2aa", | |
lightskyblue: "87cefa", | |
lightslategray: "778899", | |
lightslategrey: "778899", | |
lightsteelblue: "b0c4de", | |
lightyellow: "ffffe0", | |
limegreen: "32cd32", | |
linen: "faf0e6", | |
magenta: "ff00ff", | |
mediumaquamarine: "66cdaa", | |
mediumblue: "0000cd", | |
mediumorchid: "ba55d3", | |
mediumpurple: "9370db", | |
mediumseagreen: "3cb371", | |
mediumslateblue: "7b68ee", | |
mediumspringgreen: "00fa9a", | |
mediumturquoise: "48d1cc", | |
mediumvioletred: "c71585", | |
midnightblue: "191970", | |
mintcream: "f5fffa", | |
mistyrose: "ffe4e1", | |
moccasin: "ffe4b5", | |
navajowhite: "ffdead", | |
oldlace: "fdf5e6", | |
olivedrab: "6b8e23", | |
orange: "ffa500", | |
orangered: "ff4500", | |
orchid: "da70d6", | |
palegoldenrod: "eee8aa", | |
palegreen: "98fb98", | |
paleturquoise: "afeeee", | |
palevioletred: "db7093", | |
papayawhip: "ffefd5", | |
peachpuff: "ffdab9", | |
peru: "cd853f", | |
pink: "ffc0cb", | |
plum: "dda0dd", | |
powderblue: "b0e0e6", | |
rebeccapurple: "663399", | |
rosybrown: "bc8f8f", | |
royalblue: "4169e1", | |
saddlebrown: "8b4513", | |
salmon: "fa8072", | |
sandybrown: "f4a460", | |
seagreen: "2e8b57", | |
seashell: "fff5ee", | |
sienna: "a0522d", | |
skyblue: "87ceeb", | |
slateblue: "6a5acd", | |
slategray: "708090", | |
slategrey: "708090", | |
snow: "fffafa", | |
springgreen: "00ff7f", | |
steelblue: "4682b4", | |
tan: "d2b48c", | |
thistle: "d8bfd8", | |
tomato: "ff6347", | |
transparent: "00000000", | |
turquoise: "40e0d0", | |
violet: "ee82ee", | |
wheat: "f5deb3", | |
whitesmoke: "f5f5f5", | |
yellowgreen: "9acd32" | |
}; | |
function colorfromHex(hex) { | |
if (namedWebColors[hex.toLowerCase()]) { | |
hex = namedWebColors[hex.toLowerCase()]; | |
} | |
var r = 0, g = 0, b = 0, a = 255; | |
var offset = hex.startsWith("#") ? 1 : 0; | |
if (hex.length == 4 + offset) { | |
r = parseInt(hex[offset] + hex[offset], 16); | |
g = parseInt(hex[offset+1] + hex[offset+1], 16); | |
b = parseInt(hex[offset+2] + hex[offset+2], 16); | |
a = parseInt(hex[offset+3] + hex[offset+3], 16); | |
} else if (hex.length == 8 + offset) { | |
a = parseInt(hex[offset+6] + hex[offset+7], 16); | |
r = parseInt(hex[offset] + hex[offset+1], 16); | |
g = parseInt(hex[offset+2] + hex[offset+3], 16); | |
b = parseInt(hex[offset+4] + hex[offset+5], 16); | |
} else if (hex.length == 6 + offset) { | |
r = parseInt(hex[offset] + hex[offset+1], 16); | |
g = parseInt(hex[offset+2] + hex[offset+3], 16); | |
b = parseInt(hex[offset+4] + hex[offset+5], 16); | |
} else { | |
r = g = b = a = 0; | |
} | |
return { r: r, g: g, b: b, a: a }; | |
} | |
function RGBAToHex({r, g, b, a = 255}) { | |
const toHex = (n) => n.toString(16).padStart(2, '0'); | |
return `#${toHex(r)}${toHex(g)}${toHex(b)}${a < 255 ? toHex(a) : ''}`; | |
} | |
function RGBAColorDifference(col1, col2) { | |
return Math.sqrt( | |
(Math.abs(col1.r - col2.r) + 0.64) ** 2 + | |
(Math.abs(col1.g - col2.g) + 0.32) ** 2 + | |
(Math.abs(col1.b - col2.b) + 0.02) ** 2 | |
); | |
} | |
function getClosestNamedColor({r, g, b, a = 255}) { | |
let closestColor = ''; | |
let smallestDiff = Infinity; | |
Object.keys(namedWebColors).forEach(name => { | |
const colorHex = namedWebColors[name]; | |
const color = colorfromHex(colorHex); | |
const diff = RGBAColorDifference({ r, g, b }, color); | |
if (diff < smallestDiff) { | |
smallestDiff = diff; | |
closestColor = name; | |
} | |
}); | |
return closestColor; | |
} | |
// Example usage: | |
console.log(colorfromHex("#ff00ff")); // { r: 255, g: 0, b: 255, a: 255 } | |
console.log(colorfromHex("blue")); // { r: 0, g: 0, b: 255, a: 255 } | |
const color = { r: 255, g: 0, b: 255, a: 255 }; | |
console.log("Hex:", RGBAToHex(color)); // #ff00ff | |
console.log("Closest Named Color:", getClosestNamedColor(color)); // fuchia |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment