-
-
Save jed/983661 to your computer and use it in GitHub Desktop.
function( | |
a // take a "#xxxxxx" hex string, | |
){ | |
a = +( // turn it into a number by taking the | |
"0x" + // hexadecimal prefix and the | |
a.slice(1) // numerical portion, | |
.replace( // and | |
a.length > 4 // if the #xxxxxx form is used | |
&& /./g, // replace each character | |
'$&$&' // with itself twice. | |
) | |
); | |
return [ // return an array | |
a >> 16, // with red, | |
a >> 8 & 255, // blue, | |
a & 255 // and green components. | |
] | |
} |
function(a){a='0x'+a.slice(1).replace(a.length>4&&/./g,'$&$&');return[a>>16,a>>8&255,a&255]} |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 Jed Schmidt <http://jed.is> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "hex2rgb", | |
"description": "Converts a hex string to RGB.", | |
"keywords": [ | |
"hex", | |
"color", | |
"rgb" | |
] | |
} |
@kuvos Nice! Unfortunately it seems to return incorrect results for "#abc"
: [171,0,0]
instead of [170,187,204]
. Typo?
Here’s @kuvos’ solution, with added support for shorthand hex values:
function(h){h[4]||(h=h.replace(/./g,'$&$&').slice(1));return['0x'+h[1]+h[2]|0,'0x'+h[3]+h[4]|0,'0x'+h[5]+h[6]|0]}
113 bytes, so comment #32248 still wins for now.
ah, yes mine was meant to replace the original :p
Another variation of @kuvos’ solution (100 bytes):
function(h,b){b=h[4];return['0x'+h[1]+h[b?2:1]|0,'0x'+h[b?3:2]+h[b?4:2]|0,'0x'+h[b?5:3]+h[b?6:3]|0]}
Caching '0x'
doesn’t save any bytes:
function(h,b,x){x='0x';b=h[4];return[x+h[1]+h[b?2:1]|0,x+h[b?3:2]+h[b?4:2]|0,x+h[b?5:3]+h[b?6:3]|0]}
Comment #32248 still wins for now.
oh right, 'undefined' will be cut off anyways. nice. and yeah, caching '0x' or whatever doesnt matter
Here's a CoffeeScript version... I win (82 bytes)!
(a)->a=+("0x"+a[1..].replace(/^(.)(.)(.)$/,"$1$1$2$2$3$3"));[a>>16,a>>8&255,a&255]
88 bytes:
function(a){a='0x'+a.slice(1).replace(a[4]||/./g,'$&$&')|0;return[a>>16,a>>8&255,a&255]}
by the way, the @qfox trick of exploiting the low precedence of |
is genius.
@jed Chrome and Safari throw parse errors for that last one...
Nevermind.
<-- @kuvos ;)
<-- @JedSchmidt ;)
<-- #knews ;) guess i need to thank twitter for screwing up my nickname some day.
@jed Wouldn’t that 88-byte version break on #abcdef
strings? It would still duplicate a char, no?
94 bytes:
function(a){a='0x'+a.slice(1).replace(a[4]||/./g,a[4]||'$&$&')|0;return[a>>16,a>>8&255,a&255]}
i don't think so... if it's more than 3 digits, the regexp pattern magically turns to undefined
, which doesn't match.
.replace(a[4]||/./g,a[4]||'$&$&')
If a[4]
is undefined
it means it’s a shorthand, and in that case the ||
kicks in and the regex replace takes place.
If a[4]
is truthy it means it’s not a shorthand. The ||
will be ignored, and the replace would be similar to:
.replace(a[4],'$&$&')
In other words, the character at a[4]
would be repeated. No?
here's what i had before, one more byte but safer:
a[4]?a:/./g
is that okay?
a
wont match at this point because it still has the #
I’m confused as to how that would work… Wouldn’t that use the entire string a
if a[4]
is truthy (not a shorthand) and repeat it?
Oh, just saw your edit:
a
wont match at this point because it still has the#
.
Doh! Thanks for clarifying :)
// another path
function(h,b,c){b=.5*!!h[4];c=1;return['0x'+h[c+=b]+h[c+=b]|0,'0x'+h[c+=b]+h[c+=b]|0,'0x'+h[c+=b]+h[c+=b]|0]}
// kuvos's path
function(h,b){b=h[4];return['0x'+h[1]+h[b?2:1]|0,'0x'+h[b?3:2]+h[b?4:2]|0,'0x'+h[b?5:3]+h[b?6:3]|0]}
function(h,b){b=!!h[4];return['0x'+h[1]+h[b+1]|0,'0x'+h[b+2]+h[2*b+2]|0,'0x'+h[2*b+3]+h[3*b+3]|0]}
function(h,b){b=!!h[4];return['0x'+h[1]+h[b+1]|0,'0x'+h[b+2]+h[2*b+2]|0,'0x'+h[2*b+3]+h[3*b+3]|0]}
function(h,b){b=!!h[4]+1;return['0x'+h[1]+h[b]|0,'0x'+h[b+1]+h[2*b]|0,'0x'+h[2*b+1]+h[3*b]|0]}
// Asen's path
function(h){h='0x'+(h[4]?h:h.replace(/./g,'$&$&')).slice(1+!h[4])-0;return[h>>16,h>>8&255,h&255]}
function(h){h=h.slice(1);h[4]||(h=h.replace(/./g,'$&$&'));h='0x'+h-0;return[h>>16,h>>8&255,h&255]}
function(h,b){h='0x'+((b=h[4])?h:h.replace(/./g,'$&$&')).slice(1+!b)-0;return[h>>16,h>>8&255,h&255]}
// + jed's trick
function(h){h='0x'+h.replace(!h[4]&&/./g,'$&$&').slice(1+!h[4])-0;return[h>>16,h>>8&255,h&255]}
//var _fn =
_log(_fn('#abc'))
_log(_fn('#123456'))
@bga Great stuff!
!foo && bar
can be written as foo || bar
, so you could rewrite that last one as follows to save a byte (95→94 bytes):
function(h){h='0x'+h.replace(h[4]||/./g,'$&$&').slice(1+!h[4])-0;return[h>>16,h>>8&255,h&255]}
Edit: Actually, no — that would break it, of course, since it’s used for .replace()
so it needs to be false
. Ignore me! :)
@mathiasbynens no.
'#bbaacc'.replace('a', '$&$&')
I've tested the code in IE6, 8, and it returns a wrong result as a string doesn't act like an array in those IE versions. I think a[4] should be replaced by a.length>4
fixed. thanks again, @tsaniel!
I find it we can save another byte.
function(a){a='0x'+a.slice(1).replace(a.length>4&&/./g,'$&$&');return[a>>16,a>>8&255,a&255]}
relentless golfing, @tsaniel!
Wait, >4
? Doesn't it need to be the other way round, <4
?
@atk: Thanks for your carefulness! i just did it anyhow.
Both wrong with >4
and <4
Shound be a.length<5&&/./g
function hexToRgb(hex) {
var number = parseInt(hex, 16);
console.log(number)
var r = (number >> 16) & 255;
var g = (number >> 8) & 255;
var b = number & 255;
console.log(r,g,b)
return {red: r, green: g, blue: b};
}
let rgb = hexToRgb(0xFFFFFF)
Gives 119 114 21 , any ideas why
If you're assuming the arg is a proper hex with hash prefix, why not just this?
x=function(h){return['0x'+h[1]+h[2]|0,'0x'+h[3]+h[4]|0,'0x'+h[5]+h[6]|0]}