Fiiish
Fiiish

Reputation: 1

Hex to rgb converter in javascript

I'm trying to make a simple rgb to hex converter and I keep getting stuck with Javascript, what am I doing wrong? In html part I made a form which on submit calls convert() function.

function convert() {
    r = parseInt(document.getElementById('r').value);
    g = parseInt(document.getElementById('g').value);
    b = parseInt(document.getElementById('b').value);

    rgb(r, g, b);
    function rgb(r, g, b){
        res = ColorToHex(r) + ColorToHex(g) + ColorToHex(b);
        function ColorToHex(color) {
            if (color > 255) return "FF";
            else if (color < 0) return "00";
            else color.toString(16).padStart(2, "0").toUpperCase();
          }
    }
    document.getElementById('result').innerHTML = res;    
    return false;
}

Upvotes: 0

Views: 815

Answers (2)

Myndex
Myndex

Reputation: 5364

First, please declare your variables properly. I don't know what else you have going on in the rest of your code, it may or may not be a factor.

Second, I don't know what you are doing in your HTML. From the code shown, I am assuming your HTML has something like:

<input id="r" type="number"/>
<input id="g" type="number"/>
<input id="b" type="number"/>

And

<span id="result">This Space For Lease</span> 

Though I gather you have some of that enclosed in a <form> with a submit button, which is not strictly necessary. For instance you could use something like onBlur to call convert() every time you make any input change for a more dynamic UX. And further, use ' onclick="select()" ` so that when you click in an input it auto-selects the existing contents.

Other optimizations noted in the comments in the below example.

<body>
    <h3>Enter integer RGB values</h3>
    <input id="r" type="number" onclick="select()" onblur="convert()" value="00" style="width: 5em; background:#fcc;" />
    <input id="g" type="number" onclick="select()" onblur="convert()" value="00" style="width: 5em; background:#cfc;" />
    <input id="b" type="number" onclick="select()" onblur="convert()" value="00" style="width: 5em; background:#ccf;" />
    <br>
    <h3>Result as a HEX string</h3>
    <div style="margin:1em 0.5em; padding: 0.5em 0;">THE COLOR IS:
        <span id="colorPatch" style="margin: 0.5em; padding: 1em; background-color: black; border-radius: 0.6em;"> &nbsp;&nbsp;&nbsp; </span><br>
        <span id="result">#000000</span>
    </div> 
</body>

<script>
        // create variables for all "getElement..." this was the DOM
        // only needs to be parsed on page load, so future access to
        // the elements is via the variable instead for better performance.
    let inputR = document.getElementById('r'),
        inputG = document.getElementById('g'),
        inputB = document.getElementById('b'),
        resultOut = document.getElementById('result'),
        colorOut = document.getElementById('colorPatch');

function convert() {
            // here making the assumption that the expected inputs are
            // unsigned integers, we clamp the values to 0-255, then
            // make each into a 2 char hex str with padding.
        let hexR = Math.min(Math.max(inputR.value, 0), 255).toString(16).padStart(2, "0"),
            hexG = Math.min(Math.max(inputG.value, 0), 255).toString(16).padStart(2, "0"),
            hexB = Math.min(Math.max(inputB.value, 0), 255).toString(16).padStart(2, "0");
            
            // concatenate to a hex color string
        let resultColor = "#" + hexR + hexG + hexB; 
        
            // Send to output and set color of sample color patch.
            // toUpperCase() is performed once on the final string,
            // instead of the substrings
        resultOut.innerHTML = 
        colorOut.style.backgroundColor = resultColor.toUpperCase(); 
    }
</script>

And also added it as a snippet below. Please do read the code comments as they explain what and why things are as they are.

Now, as for the concatenation, it could be even tighter:

function convert() {
  colorOut.style.backgroundColor =
  resultOut.innerHTML = ("#"
      + Math.min(Math.max(inputR.value,0),255).toString(16).padStart(2,"0")
      + Math.min(Math.max(inputG.value,0),255).toString(16).padStart(2,"0")
      + Math.min(Math.max(inputB.value,0),255).toString(16).padStart(2,"0")).toUpperCase();
}

Everything all on one logical line (line breaks added only for readability), so no need to declare and assign any more variables. Though this kind of thing can impact code readability if taken too far.

When making big strings, I like to put the concatenation operator (+) at the head of each line, which is the opposite of how I'd breakup a long equation by putting the math operators at the end of each line. This makes it clear the + is for concatenation and not addition.

Let me know if any questions...

     // create variables for all "getElement..." this was the DOM
    // only needs to be parsed on page load, so future access to
   // the elements is via the variable instead for better 
    let inputR = document.getElementById('r'),
          inputG = document.getElementById('g'),
        inputB = document.getElementById('b'),
        resultOut = document.getElementById('result'),
        colorOut = document.getElementById('colorPatch');

function convert() {
             // here making the assumption that the expected inputs are
      // unsigned integers, we clamp the values to 0-255, then
     // make each into a 2 char hex str with padding.
        let hexR = Math.min(Math.max(inputR.value, 0), 255).toString(16).padStart(2, "0"),
            hexG = Math.min(Math.max(inputG.value, 0), 255).toString(16).padStart(2, "0"),
            hexB = Math.min(Math.max(inputB.value, 0), 255).toString(16).padStart(2, "0");
        
        // concatenate to a hex color string
        let resultColor = "#" + hexR + hexG + hexB; 
        
             // Send to output and set color of sample color patch.
            // toUpperCase() is performed once on the final string,
     // instead of the substrings
        resultOut.innerHTML = 
        colorOut.style.backgroundColor = resultColor.toUpperCase(); 
    }
body {
    margin: 0;
    padding: 0.5em 1.5em ;
    font-family: sans-serif;
    background-color: #ffd;
    }
    
h2, h3 { position: relative; font-style: oblique; }
h2 { margin: 0.5em 1em 0.5em;}
h3 { margin: 0.5em 2em 1.4em;}

#r,#g,#b {
    width: 5em;
    height: 1.75em;
    font-size: 1.33em;
    font-weight: 600;
    text-align: center; 
    border-radius: 0.6em;   
    }
#r { background:#fcc; }
#g { background:#cfc; }
#b { background:#ccf; }

.resultDiv {
    display: inline-block;
    position: relative;
    margin: 1.33em;
    padding: 0.5em 0.5em 2em;
    background-color: #4bb4;
    border-radius: 2em;
    text-shadow: 0.15em 0.15em 0.3em #6886;
    box-shadow: inset 3px 3px 6px #0448,
                      inset 0 0 22px #4888;
    }
.resultVal {
    position: relative;
    margin: 1em 2em;
    padding: 0em;
    }

#result {
  font-size: 1.5em;
  font-weight: 500;
  letter-spacing: 0.07em;
  color: #135a;
  text-shadow: -0.05em -0.05em 0.08em #defd,
                 0.05em 0.05em 0.08em #1238;
  }
#colorPatch {
    min-width: 5em;
    margin: 0.5em;
    padding: 0.5em 1em 2em;
    font-size: 1.25em;
    background-color: black;
    border: 0.33em solid #999;
    border-radius: 0.75em;
    box-shadow:  2px 2px 3px #2449; 
    }
<body>
    <h2>Enter integer RGB values</h2>
    <input id="r" type="number" onclick="select()" onblur="convert()" value="00"/>
    <input id="g" type="number" onclick="select()" onblur="convert()" value="00"/>
    <input id="b" type="number" onclick="select()" onblur="convert()" value="00"/>
    <br>
    <div class="resultDiv">
    <h3>Result as a HEX string</h3>
    <div class="resultVal">THE COLOR IS:
        <span id="colorPatch" > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br>
        <span id="result">#000000</span>
    </div> 
    </div> 
</body>

Upvotes: 0

user13457138
user13457138

Reputation:

This returns hex from RGB

console.log(convert('255','18', '50'));

function convert(r, g, b) {
    r = parseInt(r); g = parseInt(g); b = parseInt(b);
    res = r.toString(16) + g.toString(16) + b.toString(16);
    res = res.toUpperCase();
    return res;
}

Upvotes: 1

Related Questions