How to mix two colors using Javascript?

Asked

Viewed 480 times

8

There are two fields where the user reports a hexadecimal color. By clicking on mix colors, a calculation shall be made in JavaScript and this will have to present a picture painted with mixed color and hexadecimal result.

Structure in jsfiddle

Javascript

$('button').click(function(){
    var cor1 = $('#cor1').val(); //exemplo: #FF0000
    var cor2 = $('#cor2').val(); //exemplo: #00FF00
    // realiza a mistura
    var mistura_em_hexadecimal;
    $('#cor_misturada').css('background-color', mistura_em_hexadecimal);
    $('h2 span').text(mistura_em_hexadecimal);    
});

How to perform this calculation to mix two hexadecimal colors?

Note: the result should be accurate and can not use any plugin.

1 answer

9


I think what you’re looking for is an average of each color.

Take a look here: http://jsfiddle.net/XdQ88/1/

function tratarInput(arr, degraus) {
    arr = arr.toLowerCase();
    if (arr.length == 3) {
        var partes = arr.split('');
        for (var i = 0; i < arr.length; i++) {
            if (!~degraus.indexOf(arr[i])) {
                alert('formato errado!')
                return false;
            }
        }
        arr = [partes[0], partes[0], partes[1], partes[1], partes[2], partes[2]].join('');
    } else if (arr.length == 6) {} else {
        alert('formato errado!')
        return false;
    }
    return arr;
}

$('button').click(function () {
    var degraus = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
    var cor1 = $('#cor1').val().replace('#', '');
    var cor2 = $('#cor2').val().replace('#', '');

    cor1 = tratarInput(cor1, degraus);
    cor2 = tratarInput(cor2, degraus);

    // realiza a mistura
    var mistura = [];
     for (var i = 0; i < 6; i+=2) {
        mistura[i] = Math.round((parseInt(cor1[i] + cor1[i + 1], 16) + parseInt(cor2[i] + cor2[i + 1], 16)) / 2);
        mistura[i] = (0x1000000 | mistura[i]).toString(16).substring(5);
    }

    mistura = '#' + mistura.join('');
    $('#cor_misturada').css('background-color', mistura);
    $('h2 span').text(mistura);

});

This code may need some adjustments but explaining a little the steps it does:

  • define variables. Here I have created an array for all color steps, this will be useful later. I also take away the character # to facilitate, but I will insert it again later. An advantage here is that if not use it corrects in the same.
  • I created a function to handle the input. Here the function converts all colors into 6 characters (in case the input has been 3), checks for non-valid characters and if inputs have 3 or 6 characters as expected
  • then in the for makes the mixture itself. Calculates the position of that color in the step array and averages. When making the average also makes a rounding and uses the absolute value (to correct negative values). This value is a reference and is then used to fetch the real value in the step array.
  • finally, before your code continues, I put the character again # for the value to be correct
  • @Paulomaciel: where you are guiding yourself to the results you want?

  • @Sergio I am doing testing through a software and it is accurate, in the transition between yellow and blue can not get absolute gray, this only occurs between black and white. But I will not reuse the mixture for new calculations, so it will not affect the final result, this in my case.

  • @Bacco I am stating based on tests I did, as I said, the result is approximate, not exact, which ends up making the color turn absolute gray. To our eyes the result is the same, but in the hexadecimal code have 'residues' of color (blue+red for example). The result should be #80807F and I affirm with conviction, 7F is residue of the colors that were mixed. The proof of this is you let the 7F at the end change the previous code, example: #00007F ("dark blue") #FFFF7F ("light yellow"). Do the tests and see.

  • 1

    @Paulomaciel I’m just trying to share a technical knowledge I’ve needed. There are several ways to convert colors, and just the RGB does not suit you. There is no one more certain than another, it goes from use. In RGB, always complementary color is nullified, and turns gray. This 7f or 80 is a mere rounding problem. If you make 404000 with 000040, it will give 202020, in RGB, there is no other way. Only this model, although correct, is not what suits you. That’s it, it’s not right and wrong.

  • 1

    @Bacco I still think the problem is one more limitation in the conversion (method as it is done), but anyway the current solution suits me well

  • @Paulomaciel, just to complement, 80 is the same as 128, and 7F is the same as 127. rgb(128,128,127) and rgb(128,128,128) is practically the same gray, with a 1 bit difference in blue, by rounding. (Equivalent to #80807F and #808080 respectively). A curiosity of mine: in this soft you did the test, how does the result if reverse the position of the two colors? And how much to mix #FEFE00 with #0000FE?

  • @Bacco the mix of #FEFE00 with #0000FE equals #7F7F7F

  • @Bacco this yes gave gray (127, 127, 127). Apparently I was wrong when I said that only with white and black is it possible to make gray. But relative to the hexadecimal value of the mix of #FFF00 with #0000FF result in #808080, it may be "pretty much the same gray", but this minimum difference may affect certain software that reuses color mixing.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.