Search code examples
javascriptcolorshex

Best way to convert hex string with hash to hex value with 0x in JavaScript?


This question is not asking how to convert a hash string hex value to it's opposite color. This question is asking how to convert a hash string hex value to a regular hex value explained below:

I get element's hex color values from their stored style. I need to convert their hex value which is a string with a hash like "#FFFFFF" to 0xFFFFFF. What is the fastest, and most direct way of accomplishing this?

I want to do this so I can do some bitwise modifications to the style's value. For example, storedColor ^ 0xFFFFFF to get an approximate inverse color.


Solution

  • I know this answer is coming quite late, but I had a similar issue and here is what helped me (please note, the code provided below is not mine, this is simply a combination of multiple StackOverflow answers).

    General workflow: convert hex code to RGB and then to the 0x representation.

    You can check different HEX TO RGB conversion options here: RGB to hex and hex to RGB

    I used this function to do it (easy to reverse, as it returns an array [r, g, b]. Also works with shorthand hex triplets such as "#03F").

    hexToRgb(hex) {
      return hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i
          , (m, r, g, b) => "#" + r + r + g + g + b + b)
          .substring(1).match(/.{2}/g)
          .map(x => parseInt(x, 16));
    }
    

    Idea for the final conversion is taken from here: convert rgba color value to 0xFFFFFFFF form in javascript

    Like user @Chanwoo Park mentions, a color in this representation 0xFFFFFFFF is formed as Alpha, Blue, Green, Red and not Alpha, Red, Green, Blue. So simply converting a color #4286F4 to 0xFF4286F4 would not render the same color.

    What you can do is reverse RGB values and then do the conversion. The full code:

    hexToRgb(hex) {
      return hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i
          , (m, r, g, b) => "#" + r + r + g + g + b + b)
          .substring(1).match(/.{2}/g)
          .map(x => parseInt(x, 16));
    },
    getFillColor(color) {
      let rgbColor = this.hexToRgb(color);
      let reversed = rgbColor.reverse();
      let hex = 0xff000000 | (reversed[0] << 16) | (reversed[1] << 8) | reversed[2];
    
      return parseInt(`0x${(hex >>> 0).toString(16)}`);
    }
    

    P.S. this is Vue.js code, but should be super simple to convert to vanilla JS.

    All credit goes to users: https://stackoverflow.com/users/7377162/chanwoo-park, https://stackoverflow.com/users/10317684/ricky-mo, https://stackoverflow.com/users/3853934/micha%c5%82-per%c5%82akowski