What is the most efficient way to parse a CSS color in JavaScript?

后端 未结 9 1896
甜味超标
甜味超标 2020-12-06 04:36

Given a string of a valid CSS color value:

  • #fff
  • #ffffff
  • white
  • rgb(255, 255, 255)

Need to get an array of numbers of t

相关标签:
9条回答
  • 2020-12-06 05:13
    function parseColor(input) {
        var m;
    

    Obviously, the numeric values will be easier to parse than names. So we do those first.

        m = input.match(/^#([0-9a-f]{3})$/i)[1];
        if( m) {
            // in three-character format, each value is multiplied by 0x11 to give an
            // even scale from 0x00 to 0xff
            return [
                parseInt(m.charAt(0),16)*0x11,
                parseInt(m.charAt(1),16)*0x11,
                parseInt(m.charAt(2),16)*0x11
            ];
        }
    

    That's one. Now for the full six-digit format:

        m = input.match(/^#([0-9a-f]{6})$/i)[1];
        if( m) {
            return [
                parseInt(m.substr(0,2),16),
                parseInt(m.substr(2,2),16),
                parseInt(m.substr(4,2),16)
            ];
        }
    

    And now for rgb() format:

        m = input.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
        if( m) {
            return [m[1],m[2],m[3]];
        }
    

    Optionally, you can also add support for rgba format, and even hsl/hsla if you add an HSL2RGB conversion function.

    Finally, the named colours.

        return ({
            "red":[255,0,0],
            "yellow":[255,255,0],
            // ... and so on. Yes, you have to define ALL the colour codes.
        })[input];
    

    And close the function:

    }
    

    Actually, I don't know why I bothered writing all that. I just noticed you specified "assuming a major browser", I'm assuming that also means "up-to-date"? If so...

    function parseColor(input) {
        var div = document.createElement('div'), m;
        div.style.color = input;
        m = getComputedStyle(div).color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
        if( m) return [m[1],m[2],m[3]];
        else throw new Error("Colour "+input+" could not be parsed.");
    }
    

    An up-to-date browser will convert any given colour to rgb() format in its computed style. Just get it back, and read it out.

    0 讨论(0)
  • 2020-12-06 05:13

    Trying @Niet_the_Dark_Absol's answer with this beautiful getComputedStyle hack, I've been unable to make it work until appending to the DOM the created element (Chrome 69 and Firefox 75).

    As I also wanted to be able to handle the alpha channel value (transparency), I modified the Regex and returned result.

    Here is my function if it can be of any help for anyone:

    function colorToRgbParser(cssColor) {
      const div = document.createElement('div');
      div.id = 'for-computed-style';
    
      div.style.color = cssColor;
    
      // appending the created element to the DOM
      document.querySelector('body').appendChild(div);
    
      const match = getComputedStyle(div).color.match(/^rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d\.\d)\s*)?\)$/i);
    
      // removing element from the DOM
      document.querySelector('#for-computed-style').remove();
    
      if (match) {
        // match[0] is regex complete match (e.g. "rgb(0,0,0)"), not a regex capturing group
        let parsedColor = {
          r: match[1],
          g: match[2],
          b: match[3]
        };
        if (match[4]) { // if alpha channel is present
          parsedColor.a = match[4];
        }
        return parsedColor;
      } else {
        throw new Error(`Color ${cssColor} could not be parsed.`);
      }
    }
    
    0 讨论(0)
  • 2020-12-06 05:17
    var input = '#FFF';
    var color = input.toLowerCase();
    var hex = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
    var rgb = [];
    if(/#/.test(color))
        if(color.length==4){
            var parsed = color.match(/\w/g);
            rgb = [
                hex.indexOf(parsed[0])*16+hex.indexOf(parsed[0]),
                hex.indexOf(parsed[1])*16+hex.indexOf(parsed[1]),
                hex.indexOf(parsed[2])*16+hex.indexOf(parsed[2])
            ]
        }else{
            var parsed = color.match(/\w{2}/g);
            rgb = [
                hex.indexOf(parsed[0][0])*16+hex.indexOf(parsed[0][1]),
                hex.indexOf(parsed[1][0])*16+hex.indexOf(parsed[1][1]),
                hex.indexOf(parsed[2][0])*16+hex.indexOf(parsed[2][1])
            ]
        }
    else if(/(rgb)/.test(color))
        rgb = color.match(/\d+/g);
    else{
        //Here you define all the colors, like 'blue': [0,0,255]
    }
    

    If you are trying to get an element's background-color, for example, you can use this:

    var bg = getComputedStyle(myElem,null).getPropertyValue('background-color');
    var rgb = match(/\d+/g).slice(0,3);
    
    0 讨论(0)
提交回复
热议问题