Skip to content

Instantly share code, notes, and snippets.

@naturalkei
Forked from njvack/README.md
Created January 29, 2020 10:45
Show Gist options
  • Save naturalkei/082284e88b4e9de7cc7932f8423ee950 to your computer and use it in GitHub Desktop.
Save naturalkei/082284e88b4e9de7cc7932f8423ee950 to your computer and use it in GitHub Desktop.
Color to hex and rgba converter

Simple canvas-based color converter

To answer this StackOverflow question I wrote this — a small solution based on a never-rendered <canvas> element. It fills a 1-pixel canvas with the provided fill-style, and then reads the RGBA values of that pixel. It will work with any CSS color -- name, rgba(), hex, or even something more exotic like a gradient or pattern. Invalid colors are always returned as transparent black. Transparent colors are treated as painted on a newly-cleared canvas.

It's been tested in modern-ish versions of IE, Chrome, Safari, and Firefox. The API is:

color_convert.to_hex(color)   # Converts color to a hex-based RGB triple; to_hex('red') returns '#ff0000'
color_convert.to_rgba(color)  # Converts color to an rgba() string; to_rgba('red') returns 'rgba(255,0,0,1)'

And you'll probably never want it, but you can also
color_convert.to_rgba_array(color)  # Converts color to a 4-element Uint8ClampedArray: [R, G, B, A]

Totally open-source. Call it BSD-licensed or whatever. It's a toy.

color_convert = function() {
var pub = {}, canvas, context;
canvas = document.createElement('canvas');
canvas.height = 1;
canvas.width = 1;
context = canvas.getContext('2d');
function byte_to_hex(byte) {
// Turns a number (0-255) into a 2-character hex number (00-ff)
return ('0'+byte.toString(16)).slice(-2);
}
pub.to_rgba_array = function(color) {
/**
* Turns any valid canvas fillStyle into a 4-element Uint8ClampedArray with bytes
* for R, G, B, and A. Invalid styles will return [0, 0, 0, 0]. Examples:
* color_convert.to_rgb_array('red') # [255, 0, 0, 255]
* color_convert.to_rgb_array('#ff0000') # [255, 0, 0, 255]
* color_convert.to_rgb_array('garbagey') # [0, 0, 0, 0]
*/
// Setting an invalid fillStyle leaves this unchanged
context.fillStyle = 'rgba(0, 0, 0, 0)';
// We're reusing the canvas, so fill it with something predictable
context.clearRect(0, 0, 1, 1);
context.fillStyle = color;
context.fillRect(0, 0, 1, 1);
return context.getImageData(0, 0, 1, 1).data;
}
pub.to_rgba = function(color) {
/**
* Turns any valid canvas fill style into an rgba() string. Returns
* 'rgba(0,0,0,0)' for invalid colors. Examples:
* color_convert.to_rgba('red') # 'rgba(255,0,0,1)'
* color_convert.to_rgba('#f00') # 'rgba(255,0,0,1)'
* color_convert.to_rgba('garbagey') # 'rgba(0,0,0,0)'
* color_convert.to_rgba(some_pattern) # Depends on the pattern
*
* @param color A string, pattern, or gradient
* @return A valid rgba CSS color string
*/
var a = pub.to_rgba_array(color);
return 'rgba('+a[0]+','+a[1]+','+a[2]+','+(a[3]/255)+')';
}
pub.to_hex = function(color) {
/**
* Turns any valid canvas fill style into a hex triple. Returns
* '#000000' for invalid colors. Examples:
* color_convert.to_hex('red') # '#ff0000'
* color_convert.to_hex('rgba(255,0,0,1)') # '#ff0000'
* color_convert.to_hex('garbagey') # '#000000'
* color_convert.to_hex(some_pattern) # Depends on the pattern
*
* @param color A string, pattern, or gradient
* @return A valid rgba CSS color string
*/
var a = pub.to_rgba_array(color);
// Sigh, you can't map() typed arrays
var hex = [0,1,2].map(function(i) { return byte_to_hex(a[i]) }).join('');
return '#'+hex;
}
return pub;
}();
<!DOCTYPE html>
<html>
<head>
<title>Color to hex and rgba conversion</title>
<script type="text/javascript" src="color-convert.js"></script>
<script type="text/javascript">
function update_rgba_hex() {
var cname = document.getElementById('cname').value;
document.getElementById('rgba').innerHTML = color_convert.to_rgba(cname);
document.getElementById('hex').innerHTML = color_convert.to_hex(cname);
var canvas, context;
canvas = document.getElementById('swatch');
context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = cname;
context.fillRect(0, 0, canvas.width, canvas.height);
}
</script>
</head>
<body>
<p>Enter a color <input size="30" id="cname" oninput="update_rgba_hex();"/> <button onclick="update_rgba_hex();">Check it</button></p>
<p>rgba: <code id="rgba"></code></p>
<p>hex: <code id="hex"></code></p>
<div>
<canvas id="swatch" width="50" height="50"></canvas>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment