5

I am trying to blend any combination of colors using colored buttons which output a specific hex number in combination with a slider bar from bootstrap that allows the user to indicate the percentage of color they want to use.

I couldn't get the slider to properly run and I'm not sure why.

I do need some help combining the pieces of code into a working algorithm that I can use for my art class. The full code can be found here:

https://jsfiddle.net/mw7optL5/289/

//Hex blending algorithm
var mix = function(color_1, color_2, weight) {
  function d2h(d) { return d.toString(16); }  // convert a decimal value to hex
  function h2d(h) { return parseInt(h, 16); } // convert a hex value to decimal 

  weight = (typeof(weight) !== 'undefined') ? weight : 50; // set the weight to 50%, if that argument is omitted

  var color = "#";

  for(var i = 0; i <= 5; i += 2) { // loop through each of the 3 hex pairs—red, green, and blue
    var v1 = h2d(color_1.substr(i, 2)), // extract the current pairs
        v2 = h2d(color_2.substr(i, 2)),

        // combine the current pairs from each source color, according to the specified weight
        val = d2h(Math.floor(v2 + (v1 - v2) * (weight / 100.0))); 

    while(val.length < 2) { val = '0' + val; } // prepend a '0' if val results in a single digit

    color += val; // concatenate val to our new color string
  }

  return color; // PROFIT!
  };

//buttons
 <button class="Yellow" onclick="mix('#ffff00')">Yellow</button>
 <button class="Magenta" onclick="mix('#D9017A')">Magenta</button>
 <button class="Cyan" onclick="mix('#009FDF')">Cyan</button>
 <button class="Black" onclick="mix('#2D2926')">Black</button>
 <button class="Orange021" onclick="mix('#FE5000')">Orange</button>

//slider bar
<input id="ex1" data-slider-id='ex1Slider' type="text" data-slider-min="0" data-slider-max="20" data-slider-step="1" data-slider-value="14"/>

var slider = new Slider('#ex1', {
    formatter: function(value) {
        return 'Current value: ' + value;
    }
});
ssj3goku878
  • 745
  • 3
  • 14
  • 43
  • 1
    You're calling `mix` always with one parameter, but it should be called with at least 2 parameters. I don't see any variable that will store current value of slider (even scale from 0 to 20 is not clear ). – barbsan Aug 03 '18 at 11:32
  • 1
    I fixed your jsfiddle to display at least that slider https://jsfiddle.net/mw7optL5/298/ . You need to load jquery **before** bootstrap's sources. I moved also document background color assignment to function. `color` is defined is scope of `mix` function you can't access it outside in this way. – barbsan Aug 03 '18 at 11:40

1 Answers1

3

This just solves the mechanics I think you want (run and save the slider value properly), and it could be used as starter point. This doesn't solve the formula of any combination of colors as you want.

  • Create an object based in the buttons with all percentages (0 default) like { Yellow: 0, Magenta: 0, Cyan: 0, Black: 0 }
  • Add an event listener to each button .click (jquery) or .addEventListener (pure js)
  • In the callback of each button, save the color and percentage into the object, like colorPercentages[colors[i].getAttribute("id")] = $("#ex1").val(); where $("#ex1").val() is the slider's value.
  • Draw the color based in some formula, like $("body").css('background-color', 'rgb(' + r + ', ' + g + ', ' + b + ')');

In this case I've used this formula:

Red = 255 x ( 1 - Cyan / 100 ) x ( 1 - Black / 100 )

Green = 255 x ( 1 - Magenta / 100 ) x ( 1 - Black / 100 )

Blue = 255 x ( 1 - Yellow / 100 ) x ( 1 - Black / 100 )

Here a full functional example based on @barbsan modifications: https://jsfiddle.net/5dsgbne9/

That example is using the color button click event, but you could use the inverse logic as well, changing the color when user moves the slider with something like:

$("#ex1").slider().on('slideStop', function(ev){
    //code
});

As I understand, a blending algorithm it's pretty difficult to achieve, this question and the answers give some good approaches: Mixing two colors "naturally" in javascript, but you still need to mix n colors, not just 2, which is even more complex. Fortunately it seems to be not impossible.

Emeeus
  • 5,072
  • 2
  • 25
  • 37
  • Heres one example that does something similar. https://www.goldenpaints.com/mixer – ssj3goku878 Aug 04 '18 at 00:16
  • 1
    @ssj3goku878 I found this https://stackoverflow.com/questions/14819058/mixing-two-colors-naturally-in-javascript that is a good approach I think. I've made some test in goldenpaints and they use an API, the good new is that its backend have Access-Control-Allow-Origin:* header so we can use it. The bad is that they pass the color as paintId and thats is not n color. – Emeeus Aug 04 '18 at 23:18