1 2 3 4 5 6 7 8 9 10 11 12
function calc_color(value, start, end, min, max) { var n = (value - min) / (max - min); var s = parseInt(start.replace("#", ""), 16); var e = parseInt(end.replace("#", ""), 16); var r = Math.round(((e >> 16) - (s >> 16)) * n) + (s >> 16); var g = Math.round((((e >> 8) & 0xFF) - ((s >> 8) & 0xFF)) * n) + ((s >> 8) & 0xFF); var b = Math.round(((e & 0xFF) - (s & 0xFF)) * n) + (s & 0xFF); b |= (r << 16) | (g << 8); return "#" + ("000000" + b.toString(16)).slice(-6); }
Refactorings
No refactoring yet !
Andre Steenveld
April 25, 2008, April 25, 2008 19:30, permalink
It's twice as fast in FF and 1.5 times as fast in IE. I am quite sure it can be tweaked a little more though...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
function calc_color( value, start, end, min, max ){ var n = ( value - min ) / ( max - min ); end = parseInt( end.substring( 1, 7 ), 16 ); start = parseInt( start.substring( 1, 7 ), 16 ); var result = start + ( ( ( Math.round( ( ( ( ( end & 0xFF0000 ) >> 16 ) - ( ( start & 0xFF0000 ) >> 16 ) ) * n ) ) ) << 16 ) + ( ( Math.round( ( ( ( ( end & 0x00FF00 ) >> 8 ) - ( ( start & 0x00FF00 ) >> 8 ) ) * n ) ) ) << 8 ) + ( ( Math.round( ( ( ( end & 0x0000FF ) - ( start & 0x0000FF ) ) * n ) ) ) ) ) ; return "#" + ( ( result >= 0x100000 ) ? "" : ( result >= 0x010000 ) ? "0" : ( result >= 0x001000 ) ? "00" : ( result >= 0x000100 ) ? "000" : ( result >= 0x000010 ) ? "0000" : "00000" ) + result.toString( 16 ); }
Lucent
April 30, 2008, April 30, 2008 23:10, permalink
Beautiful! I noticed the substring() was a _significant_ bottleneck and retooled to only pass in hex numbers with no beginning #. That gave me an additional 20%. Can I offer a donation?
Andre Steenveld
May 6, 2008, May 06, 2008 10:28, permalink
You are welcome. And thanks for the offer of a donation but i don't need it, thank you.
Watch out for edge cases, like calculating and returning a single 0 when 00 is necessary. A lot more interested in speed than simplicity, obviously.