seperate Red Green Blue value of rgba Colur value - javascript

I'hv rgba value in this format RGBA(205,31,31,1) and I want to separate each red, green, blue and alpha value for further processing how can I achieve it using jQuery;
so the output looks like
red = 205
green = 31
blue = 31
alpha =1

To get these values from a string variable is easy with the following answer so you don't need jQuery
With the help of regex, you can easily achieve it like
var color = "RGBA(205,31,31,1)";
var regExp = /\(([^)]+)\)/; // get the values within ()
var matches = regExp.exec(color);
var splits = matches[1].split(',');
alert("red: " + splits[0] + "green: " + splits[1]+ "blue: "+ splits[2]+ "alpha: " +splits[3] );
JSFiddle
However to get the rgba value from an element you can use jQuery's css method.

Without Regular Expression:
var colorString = "rgba(111,222,333,0.5)",
colorsOnly = colorString.substring(colorString.indexOf('(') + 1, colorString.lastIndexOf(')')).split(/,\s*/),
red = colorsOnly[0],
green = colorsOnly[1],
blue = colorsOnly[2],
opacity = colorsOnly[3];

var string = "RGBA(205,31,31,1)";
var colors = [];
string = string.replace(/[rgba\(\)]/gi, ''); // remove unnecessary characters
string = string.split(","); // split by comma
for(var i = 0;i < string.length; i++){
colors.push(parseFloat(string[i], 10)); // parse the integer and push in colors array
}
console.log(colors); // [ 205, 31, 31, 1 ] the values are in RGBA order

a simple modern approach:
"RGBA(205,31,31,1)".match(/[\d\.]+/g).map(Number); //==[205, 31, 31, 1]
or if you want an object, it's a bit more work:
"RGBA(205,31,31,1)".match(/[\d\.]+/g).map(Number)
.reduce(function(a,b,i){
a[["red","blue","green","alpha"][i]]=b;
return a;
}, {}); // == {red: 205, blue: 31, green: 31, alpha: 1}
using "".match() is nice because it ignores spaces in-between the numbers and the case of the "rgba" text as well.

Related

Can not complete codewar task: "Which color is the brightest?"

DESCRIPTION for a task:
One of the common ways of representing color is the RGB color model, in which the Red, Green, and Blue primary colors of light are added together in various ways to reproduce a broad array of colors.
One of the ways to determine brightness of a color is to find the value V of the alternative HSV (Hue, Saturation, Value) color model. Value is defined as the largest component of a color:
V = max(R,G,B)
You are given a list of colors in 6-digit hexidecimal notation #RRGGBB. Return the brightest of these colors!
For example,
brightest(["#001000", "#000000"]) == "#001000"
brightest(["#ABCDEF", "#123456"]) == "#ABCDEF"
If there are multiple brightest colors, return the first one:
brightest(["#00FF00", "#FFFF00", "#01130F"]) == "#00FF00"
Note that both input and output should use upper case for characters A, B, C, D, E, F.
My solution:
function brightest(colors){
let colorIndex = 0,
maxValue = 0
for (let i = 0; i < colors.lenght; i++) {
let color = colors[i],
r = ParseInt(color.slise(1,3), 16),
g = ParseInt(color.slise(3,5), 16),
b = ParseInt(color.slise(5,7), 16),
value = Math.max(r,g,b)
if (value > maxValue) {
maxValue = value
colorIndex = i
}
}
return colors [colorIndex]
}
Result:
Test failed with colors = #CAA365,#1861D3,#E8E2C6,#3D3548,#F19BBF,#BF12C3: expected '#CAA365' to deeply equal '#F19BBF'
What is wrong? And how can I fix this?
declare a variable
let value = Math.max(r,g,b)
length not lenght
let/var to variables
parseInt not ParseInt
slice not slise
And all will working

Regex to extract RGB(r,g,b) from RGBA(r,g,b,a)

I am running the following regex in JS to extract 3 R/G/B items from the string below which is rgba(r,g,b,a), but it's not working. I am getting the original string back.
var str = 'rgba(14, 48, 71, 0.3)';
/* Goal: rgb(14,48,71) */
console.log (str.replace(/^rgba\((\d+),\s*(\d+),\s*(\d+),(\d+.\d+)\)$/, 'rgb($1,$2,$3)'));
You could also write a more consolidated version of the regex like this:
var str = 'rgba(14, 48, 71, 0.3)';
/* Goal: rgb(14,48,71) */
var rgx = /^rgba\(((,?\s*\d+){3}).+$/
console.log (str.replace(rgx, 'rgb($1)'));
It's much easier to extract the numbers and rebuild the string rather than trying to remove all the parts you don't want.
var str = 'rgba(14, 48, 71, 0.3)';
var [r,g,b] = str.match(/[\d\.]+/g);
var rgb = `rgb(${r}, ${g}, ${b})`;
console.log(rgb)
You had errors in your expression:
You weren't considerin spaces before the alpha value
You weren't escaping the . character
var str = 'rgba(14, 48, 71, 0.3)';
/* Goal: rgb(14,48,71) */
var regex = /^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+\.\d+)\)$/;
console.log (str.replace(regex, 'rgb($1,$2,$3)'));
Alternative solution:
var answer = "rgb(" + str.split(",")[0].match(/\d+/)[0] + "," + str.split(",")[1] + "," + str.split(",")[2] + ")";
If you want to match a wider range of color and alpha values (e.g. 30%, .0, .5e10, all of which are valid), you'll need to be a bit looser with your regular expression. Consider:
/\brgba\((.+?),[^,]+?\)/g
This will match any rgba(R, G, B, A) expression and capture all of the argument except the last. The JavaScript replace call would look like this:
str.replace(/\brgba\((.+?),[^,]+?\)/g, 'rgb($1)')
You can see it in action in the below snippet:
const MATCH_CSS_RGBA = /\brgba\((.+?),[^,]+?\)/g;
const MATCH_CSS_RGBA_REPLACEMENT = 'rgb($1)';
function replaceRgbaWithRgb(input) {
return input.replace(MATCH_CSS_RGBA, MATCH_CSS_RGBA_REPLACEMENT);
}
/*** the below is just for demonstration purposes ***/
const [input, output] = document.querySelectorAll('textarea');
function testReplace() {
output.value = replaceRgbaWithRgb(input.value);
}
input.addEventListener('input', testReplace);
testReplace(input);
textarea{display:block;font-family:monospace;width:80%;height:80px;white-space:pre}
In (edit me!):
<textarea>i.cat1{background:rgb(249, 115, 0);} /* RGB with 3 params */
i.cat2{background:rgba(14, 48, 71, 0.99);} /* RGBA with 4 params */
i.cat3{background:rgba(1e2, .5e1, .5e0, +.25e2%);} /* ~exotic numbers~ */</textarea>
Out:
<textarea disabled></textarea>
...or on Regex101: https://regex101.com/r/6mZDuC/1

How to subtract a color from another

Is it possible to subtract a color from another one ?
Example (correct me if i'm wrong):
If i subtract red and green from white, i am expecting the
result to be blue.
var white = 0xFFFFFF,
red = 0xFF0000,
result = white - red;
console.log(result); //65535 <-- what is that ? can it be converted to 0x00FFFF ?
[update]
Thanks to Rocket's answer, it turned out i needed a function() to convert my results into an actual color.
Here is the final working example:
var toColor = function ( d ) {
var c = Number(d).toString(16);
return "#" + ( "000000".substr( 0, 6 - c.length ) + c.toUpperCase() );
},
white = 0xFFFFFF,
red = 0xFF0000,
green = 0x00FF00,
result = toColor( white - red - green );
console.log( result ); // logs the expected result: "#0000FF"
Your white-red works fine, it's just that JavaScript represents the values as base 10 values. You need to convert them back to base 16 (hex). Check out this answer, to convert the value back to hex.
var white = 0xFFFFFF, // Stored as 16777215
red = 0xFF0000, // Stored as 16711680
result = white - red; // 16777215 - 16711680 = 65535
console.log(result); // It's stored as base 10, so it prints 65535
var resultHex = result.toString(16); // 'ffff', converted back to hex
I'm just assuming you are using RGB, because there are plenty of other ways to mix colors. You have to represent a color into 3* different parts, R G and B.
// R G B
var white = [ 1, 1, 1];
var red = [ 0, 0, 0 ];
var result = [ white[0] - red[0], white[1] - red[1], white[2] - red[2] ;
To substract the color you have to substract each component of the color, and perhaps convert it back to hex later on.
* You might want to add Alpha later on

In JSColor, how do I get the hex of the color?

Using JSColor, after the user picks a color, how do I get the "hex"?
$("input#colorpicker").css('background-color') => this returns background-color: rgb(107, 132, 255);
But not a hex.
I assume that jQuery.css returns the value that was set.
Try the following function to convert RGB to HEX:
function colorToHex(color) {
if (color.substr(0, 1) === '#') {
return color;
}
var digits = /(.*?)rgb\((\d+), (\d+), (\d+)\)/.exec(color);
var red = parseInt(digits[2]);
var green = parseInt(digits[3]);
var blue = parseInt(digits[4]);
var rgb = blue | (green << 8) | (red << 16);
return digits[1] + '#' + rgb.toString(16);
};
colorToHex('rgb(120, 120, 240)')
Actually upto an extent this depends on browser that it returns in rgb or hex, anyway check out this threads there are nice discussions about it and there are many solutions as well.
Background-color hex to JavaScript variable
and
How to get hex color value rather than RGB value?
and
Can I force jQuery.css("backgroundColor") returns on hexadecimal format?
and
jquery css color value returns RGB?
There is onchange event available:
$("input#colorpicker").change(function() {
console.log(this.color);
});

Average 2 hex colors together in javascript

Alright thought I would throw this one out there for the crowd to think over.
Given a function (written in javascript) that expects two strings formated like a hex color (ex #FF0000)
return a hex color that is the average of both of the colors passed.
function averageColors(firstColor,secondColor)
{
...
return avgColor;
}
--edit--
average would be defined as
if the color passed was yellow and the second was light purple the returned color would be a medium orange
I hate sounding like the oh-so-broken jQuery record, but there is a jQuery plugin for this already.
A quick/dirty/convenient/ES6 way to blend two hex colors by a specified perecentage:
// blend two hex colors together by an amount
function blendColors(colorA, colorB, amount) {
const [rA, gA, bA] = colorA.match(/\w\w/g).map((c) => parseInt(c, 16));
const [rB, gB, bB] = colorB.match(/\w\w/g).map((c) => parseInt(c, 16));
const r = Math.round(rA + (rB - rA) * amount).toString(16).padStart(2, '0');
const g = Math.round(gA + (gB - gA) * amount).toString(16).padStart(2, '0');
const b = Math.round(bA + (bB - bA) * amount).toString(16).padStart(2, '0');
return '#' + r + g + b;
}
console.log(blendColors('#00FF66', '#443456', 0.5));
Where amount should be 0 to 1, with 0 being exactly colorA, 1 being exactly colorB, and 0.5 being the "midpoint".
Only requires a few lines of POJS if you don't want to bother with lots of unnecessary stuff:
// Expects input as 'nnnnnn' where each nn is a
// 2 character hex number for an RGB color value
// e.g. #3f33c6
// Returns the average as a hex number without leading #
var averageRGB = (function () {
// Keep helper stuff in closures
var reSegment = /[\da-z]{2}/gi;
// If speed matters, put these in for loop below
function dec2hex(v) {return v.toString(16);}
function hex2dec(v) {return parseInt(v,16);}
return function (c1, c2) {
// Split into parts
var b1 = c1.match(reSegment);
var b2 = c2.match(reSegment);
var t, c = [];
// Average each set of hex numbers going via dec
// always rounds down
for (var i=b1.length; i;) {
t = dec2hex( (hex2dec(b1[--i]) + hex2dec(b2[i])) >> 1 );
// Add leading zero if only one character
c[i] = t.length == 2? '' + t : '0' + t;
}
return c.join('');
}
}());
Smells like homework to me, but here's my clue.
Take each hex value for R, G, and B, and average each of them. If necessary convert to Decimal to do the math.
function d2h(d) {return d.toString(16).padStart(2,'0');}
function h2d(h) {return parseInt(h,16);}
Then return a string containing the concatenated values of the three elements.
Here's a compact set of relevant (interdependent) functions:
Hex ⟷ RGB Color Conversion:
function hexToRgb(h){return['0x'+h[1]+h[2]|0,'0x'+h[3]+h[4]|0,'0x'+h[5]+h[6]|0]}
function rgbToHex(r,g,b){return"#"+((1<<24)+(r<<16)+(g<<8)+ b).toString(16).slice(1);}
Calculate Average of 2 Hex Colors: Requires conversion functions (above)
function avgHex(h1,h2){a=hexToRgb(h1);b=hexToRgb(h2); return rgbToHex(~~((a[0]+b[0])/2),~~((a[1]+b[1])/2),~~((a[2]+b[2])/2));}
Generate Random Hex Color:
function rndHex(){return'#'+('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6);}
Run snippet for demo:
// color functions (average/random/conversion)
function hexToRgb(h){return['0x'+h[1]+h[2]|0,'0x'+h[3]+h[4]|0,'0x'+h[5]+h[6]|0]}
function rgbToHex(r,g,b){return"#"+((1<<24)+(r<<16)+(g<<8)+ b).toString(16).slice(1);}
function rndHex(){return'#'+('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6);}
function avgHex(h1,h2){a=hexToRgb(h1);b=hexToRgb(h2);return rgbToHex(~~((a[0]+b[0])/2),~~((a[1]+b[1])/2),~~((a[2]+b[2])/2));}
//code below is just for the demo
function auto(){if(chk.checked){tmr=setInterval(rnd,1000)}else{clearTimeout(tmr)}}auto();
function rnd(go){for(h of[h1,h2]){h.value=rndHex();}avgInput();}
addEventListener('input',avgInput);
function avgInput(){ // get avg & colorize
ha.value=avgHex(h1.value,h2.value);
for(h of [h1,h2,ha])h.style.background=h.value;
}
*{font-family:monospace;font-size:5vw; }
<label>Color 1 → <input id='h1'></label><br>
<label>Average → <input id='ha'></label><br>
<label>Color 2 → <input id='h2'></label><br>
<label>Type hex colors or <input type='checkbox' id='chk' onclick='auto()' style=' transform: scale(1.5)'checked>Autorandom</label>
Here is my function, hope it helps.
function averageColors( colorArray ){
var red = 0, green = 0, blue = 0;
for ( var i = 0; i < colorArray.length; i++ ){
red += hexToR( "" + colorArray[ i ] + "" );
green += hexToG( "" + colorArray[ i ] + "" );
blue += hexToB( "" + colorArray[ i ] + "" );
}
//Average RGB
red = (red/colorArray.length);
green = (green/colorArray.length);
blue = (blue/colorArray.length);
console.log(red + ", " + green + ", " + blue);
return new THREE.Color( "rgb("+ red +","+ green +","+ blue +")" );
}
//get the red of RGB from a hex value
function hexToR(h) {return parseInt((cutHex( h )).substring( 0, 2 ), 16 )}
//get the green of RGB from a hex value
function hexToG(h) {return parseInt((cutHex( h )).substring( 2, 4 ), 16 )}
//get the blue of RGB from a hex value
function hexToB(h) {return parseInt((cutHex( h )).substring( 4, 6 ), 16 )}
//cut the hex into pieces
function cutHex(h) {if(h.charAt(1) == "x"){return h.substring( 2, 8 );} else {return h.substring(1,7);}}
Very late to this party, but I was personally looking for a way to average an undefined amount of HEX values. Based on the answer #RobG, I came up with this. Granted, the more colors you add the more brown/greyish they get, but, perhaps it helps!
/**
* Averages an array of hex colors. Returns one hex value (with leading #)
*
* #param {Array} colors - An array of hex strings, e.g. ["#001122", "#001133", ...]
*/
function averageHex(colors) {
// transform all hex codes to integer arrays, e.g. [[R, G, B], [R,G,B], ...]
let numbers = colors.map(function(hex) {
// split in seperate R, G and B
let split = hex.match(/[\da-z]{2}/gi);
// transform to integer values
return split.map(function(toInt) {
return parseInt(toInt, 16);
});
});
// reduce the array by averaging all values, resulting in an average [R, G, B]
let averages = numbers.reduce(function(total, amount, index, array) {
return total.map(function(subtotal, subindex) {
// if we reached the last color, average it out and return the hex value
if (index == array.length - 1) {
let result = Math.round((subtotal + amount[subindex]) / array.length).toString(16);
// add a leading 0 if it is only one character
return result.length == 2 ? '' + result : '0' + result;
} else {
return subtotal + amount[subindex];
}
});
});
// return them as a single hex string
return "#" + averages.join('');
}
console.log(averageHex(["#FF110C", "#0000AA", "#55063d", "#06551e"]));
// expected: #571b44, see also https://www.colorhexa.com/ and enter "#FF110C+#0000AA+#55063d+#06551e"
Here is the function
function avgColor(color1, color2) {
//separate each color alone (red, green, blue) from the first parameter (color1)
//then convert to decimal
let color1Decimal = {
red: parseInt(color1.slice(0, 2), 16),
green: parseInt(color1.slice(2, 4), 16),
blue: parseInt(color1.slice(4, 6), 16)
}
//separate each color alone (red, green, blue) from the second parameter (color2)
//then convert to decimal
let color2Decimal = {
red: parseInt(color2.slice(0, 2), 16),
green: parseInt(color2.slice(2, 4), 16),
blue: parseInt(color2.slice(4, 6), 16),
}
// calculate the average of each color (red, green, blue) from each parameter (color1,color2)
let color3Decimal = {
red: Math.ceil((color1Decimal.red + color2Decimal.red) / 2),
green: Math.ceil((color1Decimal.green + color2Decimal.green) / 2),
blue: Math.ceil((color1Decimal.blue + color2Decimal.blue) / 2)
}
//convert the result to hexadecimal and don't forget if the result is one character
//then convert it to uppercase
let color3Hex = {
red: color3Decimal.red.toString(16).padStart(2, '0').toUpperCase(),
green: color3Decimal.green.toString(16).padStart(2, '0').toUpperCase(),
blue: color3Decimal.blue.toString(16).padStart(2, '0').toUpperCase()
}
//put the colors (red, green, blue) together to have the output
let color3 = color3Hex.red + color3Hex.green + color3Hex.blue
return color3
}
console.log(avgColor("FF33CC", "3300FF"))
// avgColor("FF33CC", "3300FF") => "991AE6"
console.log(avgColor("991AE6", "FF0000"))
// avgColor("991AE6", "FF0000") => "CC0D73"
console.log(avgColor("CC0D73", "0000FF"))
// avgColor("CC0D73", "0000FF") => "6607B9"
To check you can use this link and midpoint 1 then blend
https://meyerweb.com/eric/tools/color-blend/#CC0D73:0000FF:1:hex

Categories

Resources