Skip to content

Instantly share code, notes, and snippets.

@akingdom
Last active November 22, 2024 08:08
Show Gist options
  • Save akingdom/0a0edd3ea37a9a331983cff3a69c4bee to your computer and use it in GitHub Desktop.
Save akingdom/0a0edd3ea37a9a331983cff3a69c4bee to your computer and use it in GitHub Desktop.
Converts colours between web hex color and an RGBA object.
// 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
// 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