This question already has answers here:
RGB to hex and hex to RGB
(59 answers)
Closed 7 years ago.
I'm using Vivagraph JS library to render some graphs.
I would like to change the color of the node like this
nodeUI.color = 0xFFA500FF;
^ This is a random example. Not the corresponding hexadecimal value for RGB below
I get from server RGB values as an array like this
rgb = [229,64,51]
How do i convert RGB to the Hexadecimal type value metioned above?
Thanks
According to the comments in code here: https://github.com/anvaka/VivaGraphJS/blob/master/demos/other/webglCustomNode.html
The value 0xFFA500FF is a 32 bit value that includes an alpha channel, so ignoring the alpha channel it's equivalent to rgb(255,165,0).
Some functions to convert from 32 bit hex to 24 bit rgb and back are below, the comments should suffice to explain how they work.
/* #param {number} v - value to convert to RGB values
** #returns {Array} - three values for equivalent RGB triplet
** alpha channel is ingored
**
** e.g. from32toRGB(0xaec7e8) // 255,165,0
*/
function from32toRGB(v) {
var rgb = ('0000000' + v.toString(16)) // Convert to hex string with leading zeros
.slice(-8) // Get last 8 characters
.match(/../g) // Split into array of character pairs
.splice(0,3) // Get first three pairs only
.map(function(v) {return parseInt(v,16)}); // Convert each value to decimal
return rgb;
}
/* #param {Array} rgbArr - array of RGB values
** #returns {string} - Hex value for equivalent 32 bit color
** Alpha is always 1 (FF)
**
** e.g. fromRGBto32([255,165,0]) // aec7e8FF
**
** Each value is converted to a 2 digit hex string and concatenated
** to the previous value, with ff (alpha) appended to the end
*/
function fromRGBto32(rgbArr) {
return rgbArr.reduce(function(s, v) {
return s + ('0' + v.toString(16)).slice(-2);
},'') + 'ff'
}
// Tests for from32toRGB
[0xFFA500FF, 0xaec7e8ff,0,0xffffffff].forEach(function(v) {
document.write(v.toString(16) + ' : ' + from32toRGB(v) + '<br>')
});
document.write('<br>');
// Tests for fromRGBto32
[[255,165,0],[174,199,232], [0,0,0], [255,255,255]].forEach(function(rgbArr) {
document.write(rgbArr + ' : ' + fromRGBto32(rgbArr) + '<br>');
});
Note that in the assignment:
odeUI.color = 0xFFA500FF
the hex value 0xFFA500FF is immediately converted to decimal 11454440. To convert the result of fromRGBto32 to a number that can be assigned to odeUI.color, use parseInt:
parseInt(fromRGBto32([229,64,51]), 16);
or if you want to hard code it, just add '0x' in front.
If you have a string like 'rgb(229,64,51)', you can convert it to a hex value by getting the numbers, converting to hex strings and concatenating:
var s = 'rgb = [229,64,51]';
var hex = s.match(/\d+/g);
if (hex) {
hex = hex.reduce(function(acc, value) {
return acc + ('0' + (+value).toString(16)).slice(-2);
}, '#')
}
document.write(hex + '<br>');
// Append FF to make 32 bit and convert to decimal
// equivalent to 0xe54033ff
document.write(parseInt(hex.slice(-6) + 'ff', 16)); // 0xe54033ff -> 3846190079
Related
This question already has answers here:
Generate random string/characters in JavaScript
(93 answers)
Closed 8 months ago.
I am trying to create a random number as the keyName for a local storage for example in this code:
localStorage.setItem('_8bcsk999r778311o', input.value);
I want to create a random number in the place of "_8bcsk999r778311o" using javascript . Is it possible , and if possible , could you please send me the code? Thanks in advance!
const random_id = `_${Math.random().toString(30).substr(2,17) + Math.random().toString(30).substring(2,17)}`
console.log(random_id)
//localStorage.setItem(random_id, 'value goes here');
Very simple and fast solution
Takes a number from 1 to 10 and save into number then with floor convert number to integer
//random integer from 0 to 10000:
let number = Math.floor(Math.random() * 10000);
localStorage.setItem(number, input.value);
In JavaScript, floor() is a function that is used to return the largest integer value that is less than or equal to a number.
see more
Math.random() returns a random number between 0 (inclusive), and 1 (exclusive):
see more
var key = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < Math.floor(10+10*Math.random()); i++) {
key += possible.charAt(Math.floor(Math.random() * possible.length));
}
localStorage.setItem(key, input.value);
I hope this will be helpful for you. Thanks.
You could utilise the random nature of the window.crypto object to deliver your numeric / string IDs with a simple function as below. By tweaking the input arguments you can easily generate either numeric or alphanumeric strings of varying sizes.
Uint32Array
crypto.getRandomValues()
const uniqid = (length = 2, base = 16) => {
let t = [];
// invoke the crypto
let crypto = window.crypto || window.msCrypto;
// create a large storage array
let tmp = new Uint32Array(length);
// populate random values into tmp array
crypto.getRandomValues( tmp );
// process these random values
tmp.forEach(i => {
t.push( Math.floor( i * 0x15868 ).toString( base ).substring( 1 ) )
});
return t.join('');
}
// purely numeric using Base10
console.info( 'Numeric - Base 10: %s', uniqid(2, 10) );
console.info( 'Long Numeric - Base 10: %s', uniqid(4, 10) );
// Alphanumeric strings using Base16
console.info( 'Alphanumeric String - Base 16: %s', uniqid(2, 16) );
console.info( 'Long Alphanumeric String - Base 16: %s', uniqid(4, 16) );
INSTRUCTIONS
Write a function that takes 2 colors as arguments and returns the average color.
The parameters will be two 6-digit hexadecimal strings. This does not need to be validated.
The return value should be a 6-digit hexadecimal string.
The hexadecimal strings represent colors in RGB, much like in CSS.
The average color is to be determined by taking the arithmetic mean for each component: red, green and blue.
CODE
const avgColor = (str1, str2) => {
return (str1 + str2) / 2
}
QUESTION
Hexadecimal is something like this 0000ff right?
I'm not sure what it means when I need to take the arithmetic mean for each component and lists 3 colors. How do you take an average of strings?
Here's a plain JS function:
You have to split the hex string into it's three color components before converting them to calculate the mean:
function calcAvg(hex1,hex2) {
//parsed into decimal from hex
//for each color pair
let hexC11 = parseInt(hex1.slice(0,2), 16);
let hexC12 = parseInt(hex1.slice(2,4), 16);
let hexC13 = parseInt(hex1.slice(4,6), 16);
let hexC21 = parseInt(hex2.slice(0,2), 16);
let hexC22 = parseInt(hex2.slice(2,4), 16);
let hexC23 = parseInt(hex2.slice(4,6), 16);
//calculate mean for each color pair
let colorMean1 = (hexC11 + hexC21) / 2;
let colorMean2 = (hexC12 + hexC22) / 2;
let colorMean3 = (hexC13 + hexC23) / 2;
//convert back to hex
let colorMean1Hex = colorMean1.toString(16);
let colorMean2Hex = colorMean2.toString(16);
let colorMean3Hex = colorMean3.toString(16);
//pad hex if needed
if (colorMean1Hex.length == 1)
colorMean1Hex = "0" + colorMean1Hex;
if (colorMean2Hex.length == 1)
colorMean2Hex = "0" + colorMean2Hex;
if (colorMean3Hex.length == 1)
colorMean3Hex = "0" + colorMean3Hex;
//merge color pairs back into one hex color
let avgColor = colorMean1Hex +
colorMean2Hex +
colorMean3Hex;
return avgColor;
}
let avg = calcAvg("999999","777777");
console.log(avg);
You can do it with this snippet:
function avg(a,b){
const regex=/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ //regular expression to parse string
a=regex.exec(a).slice(1) //create array from string 'a' using regex
b=regex.exec(b).slice(1) //create array from string 'b' using regex
let output=''
for(let i=0;i<3;i++){
const value=Math.floor(
(
parseInt(a[i],16) + //parse decimal from hexadecimal
parseInt(b[i],16) //parse decimal from hexadecimal
)/2 //perform averaging
).toString(16) //convert back to hexadecimal
output += (value.length<2?'0':'') + value //add leading zero if needed
}
return output
}
Hexadecimal is something like this 0000ff right?
Yes.
To elaborate, each two characters of the "hexadecimal string" represents a color in hexadecimal (16 numbers per digit), rather than decimal (10 numbers per digit). So the first two characters represent the Red value of the color, the second two characters represent the Green value of the color, and the last two characters represent the Blue value of the color. Combining these values results in the final color.
To further elaborate, the "ff" hexadecimal value equals 256 as a decimal value. Hexadecimal digits go from 0-9, then continue to a, b, c, d, e, and f, before wrapping around to 0 again, so a hexadecimal "0f" number, would equal 16 in decimal. A hexadecimal "10" number would equal 17 as a decimal value. Counting from 0 to 17 in hexadecimal would look like this:
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0f", "10".
In order to calculate the average of a hexadecimal string value, you need to:
Convert the hexadecimal string to integer (something similar to parseInt('0000ff', 16))
Split the color components
Calculate the average value for each color component
Reconstruct the final value from the color components
Convert the result back to hexadecimal string (with padding), you can refer to this question How to convert decimal to hexadecimal in JavaScript .
An example of full code snippet will be something similar to
const avgColor = (str1, str2) => {
// Convert the hexadecimal string to integer
const color1 = parseInt(str1, 16);
const color2 = parseInt(str2, 16);
let avgColor = 0;
for (let i = 0; i < 3; i++) {
// Split the color components
comp1 = (color1 >> (8 * i)) & 0xff;
comp2 = (color2 >> (8 * i)) & 0xff;
// Calculate the average value for each color component
let v = parseInt((comp1 + comp2) / 2) << 8 * i;
// Reconstruct the final value from the color components
avgColor += parseInt((comp1 + comp2) / 2) << 8 * i;
}
return decimalToHex(avgColor, 6);
}
// Reference from https://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hexadecimal-in-javascript
function decimalToHex(d, padding) {
var hex = Number(d).toString(16);
padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
while (hex.length < padding) {
hex = "0" + hex;
}
return hex;
}
console.log(avgColor("0000ff", "ff0000"))
There is a jQuery plugin for this if you can use jQuery -
$.xcolor.average(color, color)
Is it possible to convert a hex number to a decimal number with a loop?
Example: input "FE" output "254"
I looked at those questions :
How to convert decimal to hex in JavaScript?
Writing a function to convert hex to decimal
Writing a function to convert hex to decimal
Writing a function to convert hex to decimal
How to convert hex to decimal in R
How to convert hex to decimal in c#.net?
And a few more that were not related to JS or loops. I searched for a solution in other languages too in case that I find a way to do it,but I didn't. The first one was the most useful one. Maybe I can devide by 16,compare the result to preset values and print the result, but I want to try with loops. How can I do it?
Maybe you are looking for something like this, knowing that it can be done with a oneliner (with parseInt)?
function hexToDec(hex) {
var result = 0, digitValue;
hex = hex.toLowerCase();
for (var i = 0; i < hex.length; i++) {
digitValue = '0123456789abcdef'.indexOf(hex[i]);
result = result * 16 + digitValue;
}
return result;
}
console.log(hexToDec('FE'));
Alternative
Maybe you want to have a go at using reduce, and ES6 arrow functions:
function hexToDec(hex) {
return hex.toLowerCase().split('').reduce( (result, ch) =>
result * 16 + '0123456789abcdefgh'.indexOf(ch), 0);
}
console.log(hexToDec('FE'));
Just another way to do it...
// The purpose of the function is to convert Hex to Decimal.
// This is done by adding each of the converted values.
function hextoDec(val) {
// Reversed the order because the added values need to 16^i for each value since 'F' is position 1 and 'E' is position 0
var hex = val.split('').reverse().join('');
// Set the Decimal variable as a integer
var dec = 0;
// Loop through the length of the hex to iterate through each character
for (i = 0; i < hex.length; i++) {
// Obtain the numeric value of the character A=10 B=11 and so on..
// you could also change this to var conv = parseInt(hex[i], 16) instead
var conv = '0123456789ABCDEF'.indexOf(hex[i]);
// Calculation performed is the converted value * (16^i) based on the position of the character
// This is then added to the original dec variable. 'FE' for example
// in Reverse order [E] = (14 * (16 ^ 0)) + [F] = (15 * (16 ^ 1))
dec += conv * Math.pow(16, i);
}
// Returns the added decimal value
return dec;
}
console.log(hextoDec('FE'));
Sorry that was backwards, and I can't find where to edit answer, so here is corrected answer:
function doit(hex) {
var num = 0;
for(var x=0;x<hex.length;x++) {
var hexdigit = parseInt(hex[x],16);
num = (num << 4) | hexdigit;
}
return num;
}
If you want to loop over every hex digit, then just loop from end to beginning, shifting each digit 4 bits to the left as you add them (each hex digit is four bits long):
function doit(hex) {
var num = 0;
for(var x=0;x<hex.length;x++) {
var hexdigit = parseInt(hex[x],16);
num = (num << 4) | hexdigit;
}
return num;
}
JavaScript can natively count in hex. I'm finding out the hard way that, in a loop, it converts hex to decimal, so for your purposes, this is great.
prepend your hex with 0x , and you can directly write a for loop.
For example, I wanted get an array of hex values for these unicode characters, but I am by default getting an array of decimal values.
Here's sample code that is converting unicode hex to dec
var arrayOfEmojis = [];
// my range here is in hex format
for (var i=0x1F600; i < 0x1F64F; i++) {
arrayOfEmojis.push('\\u{' + i + '}');
}
console.log(arrayOfEmojis.toString()); // this outputs an array of decimals
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get hex value rather than RGB value using jQuery
I've got a <span> like this:
<span class="colour" style="background:#000000;"></span>
In most browsers, including IE 8, I can get the hex value of the background colour like this:
$('span.colour').attr('style').match(/#[0123456789ABCDEF]{3,6}/gi);
However, in IE 9, $('span.colour').attr('style') returns the following string:
background: rgb(0, 0, 0);
Do I have to convert back to hex in JavaScript, or is there a way to get IE 9 to give me the hex value (i.e. the thing that's actually in the damn HTML) straight from the element?
You can use the following to convert it (source).
I believe most modern browsers (including chrome) return the rgb and not the hex.
Perhaps you could do a basic match to decide if it was hex or rgb, and then convert the rgb if required.
function rgb2hex(rgb) {
rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
}
Updated version (supports alpha), as found by Cody O'Dell:
//Function to convert hex format to a rgb color
function rgb2hex(rgb){
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}
i dont think there's a direct function in IE to do that for you. Using a JS is the only way for you to convert the rgb value to the hex code.
here's a function that can convert color values to hex
function toHex(color) {
var body = createPopup().document.body,
range = body.createTextRange();
body.style.color = color;
var value = range.queryCommandValue("ForeColor");
value = ((value & 0x0000ff) << 16) | (value & 0x00ff00) | ((value & 0xff0000) >>> 16);
value = value.toString(16);
return "#000000".slice(0, 7 - value.length) + value;
};
you can read more about it over here:
http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/
I'm trying to write a function that is the inverse of the function below.
So that I can get the output from the function foo and generate it's input parameter.
I'm not entirely sure if it's possible.
function foo(str){
var hexMap = {
"0":0,
"1":1,
"2":2,
"3":3,
"4":4,
"5":5,
"6":6,
"7":7,
"8":8,
"9":9,
"A":10,
"B":11,
"C":12,
"D":13,
"E":14,
"F":15
};
var charList = [];
str = str.toUpperCase();
for (var i = 0; i < str.length; i += 2) {
charList.push(hexMap[str.charAt(i)] * 16 + hexMap[str.charAt(i + 1)]);
}
charList.splice(0, 8);
charList.splice(0, 123);
var sliceEnd = charList[0] + charList[1] * 256;
charList.splice(0, 4);
charList = charList.slice(0, sliceEnd);
return charList;
}
Your function takes in a string that is hopefully a hexadecimal string using only the characters [0-9a-fA-F]. Then it makes an array where every two hex characters are converted to a decimal integer between 0 and 255. Then the function immediately throws away the first 131 elements from this array. This means that the first 262 characters on your string have no impact on the output of the function (The first 262 characters can be any characters).
Then there is this line:
var sliceEnd = charList[0] + charList[1] * 256;
sliceEnd becomes a number between 0 and 65535 (the maximum size of the resulting array). Based on the characters at indices 262 - 265 in the input string. (Two two digit hex values converted to two integers. The value at position 264 is multiplied by 256 and added to the value at position 262).
Then the resulting array contains the integers converted using the same method from the characters from position 270 to 270 + sliceEnd*2.
MSN is correct that this function is not 1 to 1 and therefore not mathematically invertible, but you can write a function which given an array of less than 65536 integers between 0 and 255 can generate an input string for foo which will give back that array. Specifically the following function will do just that:
function bar(arr){
var sliceEnd = arr.length;
var temp = '00' + (sliceEnd & 255).toString(16);
var first = temp.substring(temp.length - 2);
temp = '00' + Math.floor(sliceEnd/256).toString(16);
var second = temp.substring(temp.length - 2);
var str = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + first + second + '0000';
for(var i = 0; i < arr.length; i++){
temp = '00' + arr[i].toString(16);
str += temp.substring(temp.length - 2);
}
return str;
}
This gives you the property that foo(bar(x)) === x (if x is an array of less than 65536 integers between 0 and 255 as stated previously), but not the property bar(foo(x)) === x because as MSN pointed out that property is impossible to achieve for your function.
EG. bar([17,125,12,11]) gives the string:
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000117dcb" which if you give as input to your function foo you get back the original array: [17,125,12,11], but there are many other inputs (at least 268 of those 0's can be any other of the values in [0-9a-fA-F], and the 04 can be anything greater than 04 which means 22^268*(255 - 4) different strings multiplied by a bit more since that only takes into account either lower case or capitals but not both when multiplying by 255 - 4. regardless 22^268 is a ridiculous number of inputs for one output anyways, and that's ignoring the fact that their are an infinite amount of strings which begin with the string above and have any other hexadecimal string appended to them which will give the same output from foo because of the sliceEnd variable.
That function is not a 1 to 1 function, i.e., many inputs will generate the same output.