1

Edit: I finally come up with a bit different, but working version. Leaving link here for anyone who may need it in the future: https://jsfiddle.net/qmgob1d5/27/


I'm trying to make a gradient creator, that runs across 16 boxes. (which color values later going to be sent trough POST for server)

I got it working, to a point, Where I can select first and last color and make gradient. However, i couldn't figure out for the life of me, how to add more gradient points. eg: change color of any box and calculate gradient values between 3..4..5..etc points. like on this site: http://www.colorzilla.com/gradient-editor/

Here is fiddle set up with code: https://jsfiddle.net/qmgob1d5/11/

//Fill the gradient array with gray color.
var PaletteColors = Array.apply(null, Array(16)).map(function () { return {red:128, green:128, blue:128}; });

var ActiveBox = 0;
MakeGradient(); //run gradient maker at start

//Remove marker
$('.ColorPreview').contextmenu(function() {
  $('#' +  $(this).attr('id') ).css('border-bottom','0px');
return false
});

//Add marker and snap sliders to rgb values.
$('.ColorPreview').on('click',function() {

    ActiveBox = $(this).attr('id');
    ActiveBox = Number(ActiveBox.split('_')[1]);
  $('#Color_' + ActiveBox).css('border-bottom','6px solid');

    $('#red').val( PaletteColors[ActiveBox].red );
        $('#green').val( PaletteColors[ActiveBox].green );
        $('#blue').val( PaletteColors[ActiveBox].blue );
});

//Read values from sldier write them to PaletteColors array.
$('.Paletteslider').on('change mousemove',function() {
    var red = ($('#red').val());
    var green = ($('#green').val());
    var blue = ($('#blue').val());

        PaletteColors[ActiveBox].red = Number(red);
        PaletteColors[ActiveBox].green = Number(green);
        PaletteColors[ActiveBox].blue = Number(blue);
    MakeGradient();
});

//Draw gradient based on PaletteColors array.
function MakeGradient() {
var FirstColor = PaletteColors[0];
var SecondColor = PaletteColors[15];
var end = 15;
var Count = 1/end;

        for (i = 0; i <= end; i++ ) {

        var Step = Count * i;
        var CurrentRed = SecondColor.red * Step + FirstColor.red * (1 - Step);
        var CurrentGreen = SecondColor.green * Step + FirstColor.green * (1 - Step);
        var CurrentBlue = SecondColor.blue * Step + FirstColor.blue * (1 - Step);

        PaletteColors[i].red = CurrentRed; PaletteColors[i].green = CurrentGreen; PaletteColors[i].blue = CurrentBlue;

    $('#Color_' + i ).css('background-color','rgb('+ Math.round(CurrentRed) +','+  Math.round(CurrentGreen) + ',' + Math.round(CurrentBlue) +')');
        }
 }

any help or direction is welcome!

1 Answer 1

1

You can add the functionality you seek by adding trackers to the items in the PaletteColors array (id and edited properties), modifying the functionality of makeGradient, and adding a corresponding modification of edited to the Paletteslider event.

In order for additional markers to be added, you find a way to assess which colors have been modified or are the first/last colors in PaletteColors. I chose to filter an array on conditions if edited is true or the element is the first/last in array. From there, you can assign the values of FirstColor and SecondColor to the first and second color of PaletteColors, respectively.

To change the value of the FirstColor and SecondColor: inside the for loop, check if the id isn't the first or last element and if the SecondColor id equals i, and change the values of FirstColor/SecondColor if so. When assigning the colors to the various elements and creating the gradient, you can check whether i is equal to the FirstColor or SecondColor id property. If it is, use the current color of FirstColor or SecondColor gradient to allow it to show up, otherwise apply your transitional formula. See code snippet below for full working example.

//Fill the gradient array with gray color.
var PaletteColors = Array.apply(null, Array(16)).map(function(item, i) {
    return { id: i, color: { red: 128, green: 128, blue: 128 }, edited: false }; });

var ActiveBox = 0;
MakeGradient(); //run gradient maker at start

//Remove marker
$('.ColorPreview').contextmenu(function() {
    $('#' + $(this).attr('id')).css('border-bottom', '0px');
    return false
});

//Add marker and snap sliders to rgb values.
$('.ColorPreview').on('click', function() {
    ActiveBox = Number($(this).data('col'));

    $('#Color_' + ActiveBox).css('border-bottom', '6px solid');

    $('#red').val(PaletteColors[ActiveBox].color.red);
    $('#green').val(PaletteColors[ActiveBox].color.green);
    $('#blue').val(PaletteColors[ActiveBox].color.blue);
    
    var a = PaletteColors.filter(function(col, i) {
        return col.edited || i === 0 || i === 15;
    }).map(function(item, i) {
        item.count = i;
        return item;
    });

});

//Read values from sldier write them to PaletteColors array.
$('.Paletteslider').on('change mousemove', function() {
    var red = Number($('#red').val());
    var green = Number($('#green').val());
    var blue = Number($('#blue').val());
    
    if (!PaletteColors[ActiveBox].edited) {
        PaletteColors[ActiveBox].edited = true;
    }
    PaletteColors[ActiveBox].color.red = red;
    PaletteColors[ActiveBox].color.green = green;
    PaletteColors[ActiveBox].color.blue = blue;
    MakeGradient();
});


//Draw gradient based on PaletteColors array.
function MakeGradient() {
    var colors = PaletteColors.filter(function(col, i) {
        return col.edited || i === 0 || i === 15;
    }).map(function(item, i) {
        item.count = i;
        return item;
    });

    var FirstColor = colors[0];
    var SecondColor = colors[1];
    var end = 15;
    var Count = 1 / end;

    for (i = 0; i <= end; i++) {
        if (colors.length > 2 && i !== 0 && i !== 15 && SecondColor.id === i) {
            FirstColor = SecondColor;
            SecondColor = colors[SecondColor.count + 1];
        }
     

        var Step = Count * i;
        var Current = {};
        var str;
        var match = FirstColor.id === i || SecondColor.id === i ? FirstColor.id === i ? 1 : 2 : false;
        if (match) {
        Current = match === 1 ? FirstColor.color : SecondColor.color;
        } else {
        Current.red = Math.round(SecondColor.color.red * Step + FirstColor.color.red * (1 - Step));
        Current.green = Math.round(SecondColor.color.green * Step + FirstColor.color.green * (1 - Step));
        Current.blue = Math.round(SecondColor.color.blue * Step + FirstColor.color.blue * (1 - Step));
         }
		
        PaletteColors[i].color.red = Current.red > 255 ? 255 : Current.red;
        PaletteColors[i].color.green = Current.green > 255 ? 255 : Current.green;
        PaletteColors[i].color.blue = Current.blue > 255 ? 255 : Current.blue;
        str = 'rgb(' + [Current.red, Current.blue, Current.green].join(',') + ')';
        $('#Color_' + i).css('background-color', str);

    }
}
body, html{
  background: #222222;
	font-family: 'Lato', sans-serif;
	color:white;
	}

.ColorPreview {
background: rgb(0,0,0); 
float: left;
height: 5em;
width: 6.25%;
border-bottom: 0px solid;
border-color: lightgrey;
}

#Color_0 {border-bottom: 0px solid;}
#Color_1 {border-bottom: 0px solid;}
#Color_2 {border-bottom: 0px solid;}
#Color_3 {border-bottom: 0px solid;}
#Color_4 {border-bottom: 0px solid;}
#Color_5 {border-bottom: 0px solid;}
#Color_6 {border-bottom: 0px solid;}
#Color_7 {border-bottom: 0px solid;}
#Color_8 {border-bottom: 0px solid;}
#Color_9 {border-bottom: 0px solid;}
#Color_10 {border-bottom: 0px solid;}
#Color_11 {border-bottom: 0px solid;}
#Color_12 {border-bottom: 0px solid;}
#Color_13 {border-bottom: 0px solid;}
#Color_14 {border-bottom: 0px solid;}
#Color_15 {border-bottom: 0px solid;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="PreviewTable" >
<div class="ColorPreview" id="Color_0" data-col="0">Color0</div>
<div class="ColorPreview" id="Color_1" data-col="1">Color1</div>
<div class="ColorPreview" id="Color_2" data-col="2">Color2</div>
<div class="ColorPreview" id="Color_3" data-col="3">Color3</div>
<div class="ColorPreview" id="Color_4" data-col="4">Color4</div>
<div class="ColorPreview" id="Color_5" data-col="5">Color5</div>
<div class="ColorPreview" id="Color_6" data-col="6">Color6</div>
<div class="ColorPreview" id="Color_7" data-col="7">Color7</div>
<div class="ColorPreview" id="Color_8" data-col="8">Color8</div>
<div class="ColorPreview" id="Color_9" data-col="9">Color9</div>
<div class="ColorPreview" id="Color_10" data-col="10">Color10</div>
<div class="ColorPreview" id="Color_11" data-col="11">Color11</div>
<div class="ColorPreview" id="Color_12" data-col="12">Color12</div>
<div class="ColorPreview" id="Color_13" data-col="13">Color13</div>
<div class="ColorPreview" id="Color_14" data-col="14">Color14</div>
<div class="ColorPreview" id="Color_15" data-col="15">Color15</div>
</div>
<div>
&nbsp;
</div>
<div>
<p>
right click to remove marker
</p>
</div>
<div>
<p>red</p>
<span id="spanHueIndex"></span>
<p> <input class="slider Paletteslider" id="red" type="range" step="1" min="0" max="255" value="0" /></p>
<p>green</p>
<span id="spanSaturationIndex"></span>
<p> <input class="slider Paletteslider" id="green" type="range" step="1" min="0" max="255" value="0" /></p>
<p>blue</p>
<span id="spanLightnessIndex"></span>
<p> <input class="slider Paletteslider" id="blue" type="range" step="1" min="0" max="255" value="0" /></p>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Okay, I worked on it a bit more. Decided to go with a different approach, and simply let user decide range. and use 2 sliders (tho maybe one could be enough) also makes the code simpler. But now, I've encountered a strange behavior. I want to add a copy color function via right click. But, if i copy the colors with right click, the second set of rgb slider wont update the second color anymore. No idea why. Here is the code: jsfiddle.net/qmgob1d5/23
Found the problem, apparently, If both elements are an object, somethings goes wrong if i try to do this: PaletteColors[i] = PaletteColors[CopyBox] Strangely enough there are no errors, but definitely not working right. however: replacing that code with: PaletteColors[i].red = PaletteColors[CopyBox].red works fine

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.