7

Javascript code

$(".designer-element").each(function () {
        var $this = $(this),
        var  moot = $this.css(["color", "border-color", "background-color"]);
} );

is used to get element colors. This returns colors as strings like

"background-color": "rgba(0, 0, 0, 0)"
"border-color": "rgb(211, 211, 211)"
"color": "rgb(51, 51, 51)"

How to extract individual r , g and b values from those strings. a value is not needed. Or is there some better method which returns those color values directly?

substrg cannot used since values have variable sizes 1-3 digits Can some regex used ?

html5, jquery, jquery-ui and bootstrap are used.

Andrus
  • 26,339
  • 60
  • 204
  • 378

5 Answers5

10

This is what I use

// return array of [r,g,b,a] from any valid color. if failed returns undefined
function colorValues(color)
{
    if (color === '')
        return;
    if (color.toLowerCase() === 'transparent')
        return [0, 0, 0, 0];
    if (color[0] === '#')
    {
        if (color.length < 7)
        {
            // convert #RGB and #RGBA to #RRGGBB and #RRGGBBAA
            color = '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3] + (color.length > 4 ? color[4] + color[4] : '');
        }
        return [parseInt(color.substr(1, 2), 16),
            parseInt(color.substr(3, 2), 16),
            parseInt(color.substr(5, 2), 16),
            color.length > 7 ? parseInt(color.substr(7, 2), 16)/255 : 1];
    }
    if (color.indexOf('rgb') === -1)
    {
        // convert named colors
        var temp_elem = document.body.appendChild(document.createElement('fictum')); // intentionally use unknown tag to lower chances of css rule override with !important
        var flag = 'rgb(1, 2, 3)'; // this flag tested on chrome 59, ff 53, ie9, ie10, ie11, edge 14
        temp_elem.style.color = flag;
        if (temp_elem.style.color !== flag)
            return; // color set failed - some monstrous css rule is probably taking over the color of our object
        temp_elem.style.color = color;
        if (temp_elem.style.color === flag || temp_elem.style.color === '')
            return; // color parse failed
        color = getComputedStyle(temp_elem).color;
        document.body.removeChild(temp_elem);
    }
    if (color.indexOf('rgb') === 0)
    {
        if (color.indexOf('rgba') === -1)
            color += ',1'; // convert 'rgb(R,G,B)' to 'rgb(R,G,B)A' which looks awful but will pass the regxep below
        return color.match(/[\.\d]+/g).map(function (a)
        {
            return +a
        });
    }
}

https://gist.github.com/oriadam/396a4beaaad465ca921618f2f2444d49

Examples

colorValues('transparent'); // [0,0,0,0]
colorValues('white'); // [255, 255, 255, 1]
colorValues('teal'); // [0, 128, 128, 1]
colorValues('rgba(11,22,33,.44)'); // [11, 22, 33, 0.44]
colorValues('rgb(11,22,33)'); // [11, 22, 33, 1]
colorValues('#abc'); // [170, 187, 204, 1]
colorValues('#abc6'); // [170, 187, 204, 0.4]
colorValues('#aabbcc'); // [170, 187, 204, 1]
colorValues('#aabbcc66'); // [170, 187, 204, 0.4]
colorValues('asdf'); // undefined
colorValues(''); // undefined
colorValues(NaN); // Script Error
colorValues(123); // Script Error
oriadam
  • 7,747
  • 2
  • 50
  • 48
9

You can use a regex:

function getRGB(str){
  var match = str.match(/rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?(\d(?:\.\d?))\))?/);
  return match ? {
    red: match[1],
    green: match[2],
    blue: match[3]
  } : {};
}

console.log(getRGB("rgb(211, 211, 211)"));
console.log(getRGB("rgba(211, 0, 211, 0.5)"));
akinuri
  • 10,690
  • 10
  • 65
  • 102
Marcos Casagrande
  • 37,983
  • 8
  • 84
  • 98
  • 1
    a little fix here is needed. To match values like: "rgba(1,2,3,0.25)" and "rgba(1,2,3,0)" - `rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?(\d(?:\.\d*)?)\))?` – aleha_84 Mar 31 '20 at 13:28
5

If you want to avoid Regular Expression usage for performance reasons, try something like:

function getRGBValues(str) {
  var vals = str.substring(str.indexOf('(') +1, str.length -1).split(', ');
  return {
    'r': vals[0],
    'g': vals[1],
    'b': vals[2]
  };
}
diego nunes
  • 2,750
  • 1
  • 14
  • 16
1

If you want the RGB return-values as array of integer

    function toRGB(str) {
        let sep = str.indexOf(",") > -1 ? "," : " ";
        return  str.substr(4).split(")")[0].split(sep).map(Number); 
    }
Flemming
  • 694
  • 7
  • 22
0

use regular expression to capture the rbg values something like below

~ /((.*?))/

then you will get "0,0,0" split that using string and you will get array of numbers and depending on the length of the array determine individual values

  • you could at least write the proper regexp `/rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d\.]+))?\s*\)/` – oriadam Sep 09 '19 at 07:35