Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate color HEX having 2 colors and percent/position

Is it possible to calculate a color in a middle of a gradient?

var color1 = 'FF0000';
var color2 = '00FF00';

// 50% between the two colors, should return '808000'
var middle = gradient(color1, color2, 0.5); 

I only have two hex strings, and I want one in return.

like image 909
Kalamar Obliwy Avatar asked May 03 '13 13:05

Kalamar Obliwy


People also ask

How is hex color calculated?

Hex color codes start with a pound sign or hashtag (#) and are followed by six letters and/or numbers. The first two letters/numbers refer to red, the next two refer to green, and the last two refer to blue. The color values are defined in values between 00 and FF (instead of from 0 to 255 in RGB).

How many colors are possible in hex code?

By using a hexadecimal, or 16-bit number system, the maximum number of colors that can be displayed at any one time is 16 x 16, or 256 colors. These 256 colors are represented as the values 0 – 255. In order to convert an RGB color code to a hex color code, you will need to convert each of the values individually.


3 Answers

This should work:

It basically involves converting them to decimal, finding the halves, converting the results back to hex and then concatenating them.

var color1 = 'FF0000'; var color2 = '00FF00'; var ratio = 0.5; var hex = function(x) {     x = x.toString(16);     return (x.length == 1) ? '0' + x : x; };  var r = Math.ceil(parseInt(color1.substring(0,2), 16) * ratio + parseInt(color2.substring(0,2), 16) * (1-ratio)); var g = Math.ceil(parseInt(color1.substring(2,4), 16) * ratio + parseInt(color2.substring(2,4), 16) * (1-ratio)); var b = Math.ceil(parseInt(color1.substring(4,6), 16) * ratio + parseInt(color2.substring(4,6), 16) * (1-ratio));  var middle = hex(r) + hex(g) + hex(b); 
like image 122
techfoobar Avatar answered Sep 20 '22 10:09

techfoobar


I can't comment on the answer above, so I write it here:

I found out that in the Javascript substring method the to parameter index is not included in the returned string. That means:

var string = "test"; //index:      0123 alert(string.substring(1,3));  //will alert es and NOT est 

Edit: So it should be:

parseInt(color1.substring(0,2), 16); parseInt(color1.substring(2,4), 16); 

and

parseInt(color1.substring(4,6), 16); 
like image 39
Nilz11 Avatar answered Sep 20 '22 10:09

Nilz11


An ES6 version with comprehensions:

function interpolateColor(c0, c1, f){
    c0 = c0.match(/.{1,2}/g).map((oct)=>parseInt(oct, 16) * (1-f))
    c1 = c1.match(/.{1,2}/g).map((oct)=>parseInt(oct, 16) * f)
    let ci = [0,1,2].map(i => Math.min(Math.round(c0[i]+c1[i]), 255))
    return ci.reduce((a,v) => ((a << 8) + v), 0).toString(16).padStart(6, "0")
}

As in the accepted answer, c0,c1 are color codes (without the leading #) and f is "progress" between the two values. (At f=0 this ends up returning c0, at f=1 this returns c1).

  • The first two lines convert the color codes into arrays of scaled integers
  • The third line:
    • "zips" the two integer arrays
    • sums the corresponding values
    • rounds the sum and clamps it to 0-255
  • The fourth line:
    • converts the integer array into a single integer (reduce and bitshifting)
    • converts the integer into its hexadecimal string form
    • ensures the resulting string is 6 characters long and returns it
like image 34
jedwards Avatar answered Sep 23 '22 10:09

jedwards