Javascript hsl到rgb的转换。价值观会消失。与解决方案进行比较。我的做法有什么不同?

Javascript hsl到rgb的转换。价值观会消失。与解决方案进行比较。我的做法有什么不同?,javascript,rgb,hsl,Javascript,Rgb,Hsl,解决了!参见编辑 我创建了一个颜色选择器应用程序。很简单,;单击rgb调色板,它将创建一个包含rgb值、HSL值和十六进制值的样例。 我用它来做转换 基本上,我从x和y鼠标位置构建HSL值,静态饱和度为99% 从那里,我通过将HSL转换为RGB创建了要拾取的调色板 调色板上的单击事件将创建RGB、HSL和十六进制样例以及每个样例的值 因为我不能得到RGB和HSL值来匹配,所以我还没有合并十六进制值 我终于找到了一个有效的解决办法。有人能告诉我,我的计算偏离工作方案的地方吗?我不只是想接受有效的解

解决了!参见编辑

我创建了一个颜色选择器应用程序。很简单,;单击rgb调色板,它将创建一个包含rgb值、HSL值和十六进制值的样例。
我用它来做转换

基本上,我从x和y鼠标位置构建HSL值,静态饱和度为99%

从那里,我通过将HSL转换为RGB创建了要拾取的调色板

调色板上的单击事件将创建RGB、HSL和十六进制样例以及每个样例的值

因为我不能得到RGB和HSL值来匹配,所以我还没有合并十六进制值

我终于找到了一个有效的解决办法。有人能告诉我,我的计算偏离工作方案的地方吗?我不只是想接受有效的解决方案,继续前进;我想知道我的逻辑从哪里开始崩溃

非常感谢你的帮助

编辑:所以Bob建议我使用一种更好的方法来规范化我的RGB值,而不是仅仅根据它们的值加减1。我添加了这个函数,使RGB通道基于色调值(-0.333-360.333)

index.html:

            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Color Picker, Bro</title>
                <link href='http://fonts.googleapis.com/css?  family=Raleway:700,300' rel='stylesheet' type='text/css'>
                <link rel="stylesheet" href="style.css">
                <script src='https://code.jquery.com/jquery-2.1.3.min.js'></script>
                <script type="text/javascript" src='myColorPickerSol.js'></script>
                <!-- <script type="text/javascript" src='actualWorkingColorPickerSol.js'></script> -->
            </head>
            <body>

                <div id='container'>
                    <h1>Color Picker, bro</h1>
                    <section id='canvas'></section>
                        <section id='readout'>
                            <p>HSL: <span id='hsl'></span></p>
                            <section id='swatchhsl'></section>
                            <p>RGB: <span id='rgb'></span></p>
                            <section id='swatchrgb'></section>
                            <p>HEX: <span id='hex'></span></p>
                        </section>
                    </section>
                </div>

            </body>
            </html>
             body {
                      background:   url(http://subtlepatterns.com/patterns/subtle_white_mini_waves.png);
             }

             #container {
                margin: 0 auto;
                width: 800px;
                height: inherit;
                text-align: center;
                font-family: Raleway;
                font-weight: 300;
            }
            #canvas {
                margin: 0 auto;
                border: 5px solid black;
                box-sizing: border-box;
                height: 360px;
                width: 360px;
            }
            #readout {
                background: rgba(117,117,117, .2);
                margin: 20px auto;
                height: 400px;
                width: 360px;
                border: 1px #333 solid;
                box-sizing: border-box;
                border-radius: 20px;
            }
            #swatchhsl,#swatchrgb {
                margin: 0 auto;
                height: 75px;
                width: 95%;
                border-radius: 20px;
            }
            p, span {
                letter-spacing: 1px;
            }
            p {
                font-weight: 700;
            }

            span {
                font-weight: 300;
            }
myColorPickerSol.js

     $(document).ready(function(){
    var canvas = $('#canvas');
  //swatch matches closest when either pure blue, green or red; loses all accuracy when colors mix.
  // dark blue gets really close. Purple gets really close, which makes me suspect the Green channel value is where the problem lies.

    // y-axis as Luminace(0-100%)
    // x-axis as Hue(0-360)


    var yPos;
    var lum;
    var hue;// aka xPos;

    var temp1;//for hslToRGB
    var temp2;//for hslToRGB
    var tempR;
    var tempG;
    var tempB;

    var red;
    var blue;
    var green;
    var realColVal;

    $('#canvas').mousemove(function(event){
      hue = Math.abs(event.offsetX);

      hueForRGB = (hue/360);

      yPos = Math.abs(event.offsetY);

      lum = (yPos/360);
      // console.log(lum + ' lum');

      $(canvas).css({'background-color':'hsl('+ event.offsetX + ',99%,'+ Math.round(lum *100) + '%)'});





    });
  // swatch listener
    $(canvas).click(function(event){

      hsl2RGB(lum);

      $('#rgb').text(red + ','+ green + ',' + blue);
      $('#hsl').text(hue + ',99%,' + Math.round(lum * 100) + '%');
      $(canvas).css({'background-color':'rgb('+ red + ','+ green + ','+ blue + ')'});
    });


  //red channel must be in upper third; green in middle third; blue in lower third.
    function hsl2RGB(lum){

      tempR = (hueForRGB + 0.333);
      tempG = hueForRGB;
      tempB = (hueForRGB - 0.333);
    // set temporary lum based on whether it is above/below 50%
      temp1 = lumMorOrLess50(lum);

  // set secondary temporary lum value
      temp2 = ((2.0 * (lum)) - temp1);

 //-----------EDIT ----------------------------- 
 // used the formula to make the tempR|G|B values between 0 and 1
 // tempR = makeRGB01(tempR);
//  tempG = makeRGB01(tempG);
//  tempB = makeRGB01(tempB);  
 //-----------------------------------------------

      red   = Math.round(convert2RGB(tempR,temp1,temp2));
      green = Math.round(convert2RGB(tempG,temp1,temp2));
      blue  = Math.round(convert2RGB(tempB,temp1,temp2));

  //swatch appears on click for hsl and rgb
      $('#swatchhsl').css({'background-color':'hsl('+ hue + ',99%,'+ Math.round(lum * 100 )+ '%)'});
      $('#swatchrgb').css({'background-color':'rgb('+ red + ','+ green + ','+ blue + ')'});

    };

    //force tempR|G|B to be between 0-1
    function makeRGB01(input) {
      if(input > 1){
        input -= 1.0;
      } else if(input < 0){
        input += 1.0;
      };
      return input;
    };

    //get value for each rgb channel
    function convert2RGB(tempColVal, val1, val2){
       //first convert tempColVal to between 0 and 1 then make it an RGB value
       tempColVal = makeRGB01(tempColVal);

      //next run 3 test;
        if(6.0 * tempColVal < 1){
          realColVal = (val2 + (val1 - val2) * 6 * tempColVal);
          console.log(realColVal + 'test 1; val1: '+ val1 + 'val2: ' + val2  );
       //-------EDIT ------------------------------------------
       // test2 will set realColVal to val1 instead of tempColVal
       //-------------------------------------------------------
        } else if(2.0 * tempColVal < 1){
          realColVal = val1;
          console.log(realColVal + 'test 2');
        } else if(3.0 * tempColVal < 2){
          realColVal = (val2 + (val1 - val2)*(0.666 - tempColVal) * 6.0);
          console.log(realColVal + 'test 3');
        } else {
          realColVal = val2;
          console.log(realColVal + 'realColVal = default (temp 2)');
        };

       //-------EDIT ------------------------------------------
       // normalize value before multiplying by 255

       realColVal = normalizeRGB(realColVal); 
       //-------------------------------------------------------
      // force value between 0 and 1 then set it to RGB scale and    
      // return
      return  (Math.abs(realColVal) * 255.0));

    };


    //configure temporary luminance value, temp1,  based on luminance
    function lumMorOrLess50(val){
      if(val < 0.50){
        return ((1.0 + 0.99) * val);
      } else {
        return ((.99 + val) - (val * .99));
      };
    };



  });
$(文档).ready(函数(){
var canvas=$(“#canvas”);
//当纯蓝色、绿色或红色时,样例匹配最接近;当颜色混合时,将失去所有准确性。
//深蓝色非常接近,紫色非常接近,这让我怀疑绿色通道值是问题所在。
//y轴作为亮度(0-100%)
//x轴作为色调(0-360)
var-yPos;
变种;
var hue;//又称xPos;
var temp1;//用于hslToRGB
var temp2;//用于hslToRGB
var-tempR;
var tempG;
var tempB;
变种红;
蓝变种;
绿色变种;
var realColVal;
$('#canvas').mousemove(函数(事件){
色调=Math.abs(event.offsetX);
HueforGB=(色调/360);
yPos=Math.abs(event.offsetY);
lum=(yPos/360);
//控制台日志(lum+‘lum’);
$(canvas.css({'background-color':'hsl('+event.offsetX+',99%,'+Math.round(lum*100)+'%'));
});
//样例侦听器
$(画布)。单击(函数(事件){
hsl2RGB(lum);
$(“#rgb')。文本(红色+”、“+绿色+”、“+蓝色);
$('#hsl').text(色调+',99%,'+Math.round(lum*100)+'%);
$(canvas.css({'background-color':'rgb('+red+'、'+green+'、'+blue+'))});
});
//红色通道必须位于上三分之一;绿色通道位于中三分之一;蓝色通道位于下三分之一。
功能hsl2RGB(lum){
tempR=(hueforgb+0.333);
tempG=hueforgb;
tempB=(火狐GB-0.333);
//根据是否高于/低于50%设置临时lum
temp1=lummorless50(lum);
//设置辅助临时值
temp2=((2.0*(lum))-temp1);
//-----------编辑------------------
//使用公式使tempR | G | B值介于0和1之间
//tempR=makeRGB01(tempR);
//tempG=makeRGB01(tempG);
//tempB=makeRGB01(tempB);
//-----------------------------------------------
红色=数学圆(convert2RGB(tempR,temp1,temp2));
绿色=数学圆(convert2RGB(tempG,temp1,temp2));
蓝色=数学圆(convert2RGB(tempB,temp1,temp2));
//单击hsl和rgb时会显示样例
$('#swatchhsl').css({'background-color':'hsl('+hue+',99%,'+Math.round(lum*100)+'%'))});
$('swatchrgb').css({'background-color':'rgb('+red+'、'+green+'、'+blue+'))});
};
//力节拍| G | B在0-1之间
函数makeRGB01(输入){
如果(输入>1){
输入-=1.0;
}else if(输入<0){
输入+=1.0;
};
返回输入;
};
//获取每个rgb通道的值
函数convert2RGB(tempColVal、val1、val2){
//首先将tempColVal转换为介于0和1之间的值,然后将其设置为RGB值
tempColVal=makeRGB01(tempColVal);
//下一次运行3次测试;
如果(6.0*tempColVal<1){
realColVal=(val2+(val1-val2)*6*tempColVal);
log(realColVal+'test1;val1:'+val1+'val2:'+val2);
//-------编辑------------------------------------------
//test2将realColVal设置为val1,而不是tempColVal
//-------------------------------------------------------
}否则如果(2.0*tempColVal<1){
realColVal=val1;
log(realColVal+'test2');
}否则如果(3.0*tempColVal<2){
realColVal=(val2+(val1-val2)*(0.666-tempColVal)*6.0);
log(realColVal+'test3');
}否则{
realColVal=val2;
log(realColVal+'realColVal=default(temp2)');
};
//-------编辑------------------------------------------
//在乘以255之前对值进行规格化
realColVal=normalizeRGB(realColVal);
//-------------------------------------------------------
//强制值介于0和1之间,然后将其设置为RGB比例和
//返回
返回值(数学绝对值(realColVal)*255.0);
};
//基于亮度配置临时亮度值temp1
函数LUMMORLESS50(val){
如果(val<0.50){
返回((1.0+0.99)*val);
}否则{
返回((.99+val)-(val*.99));
};
};
});
这就是有效的解决方案,actualColorPickerSol.js我做了哪些不同的事情

            $(function() {
                console.log('Loaded, bro');
                colorPicker();
            });

            function colorPicker() {
                var canvas = $('#canvas');
                canvas.on('mousemove', changeCanvasBackground);
                canvas.on('click', printColorReadout);
            }

            function changeCanvasBackground(event) {
                var xCoord = Math.abs(event.offsetX);
                var yCoord = Math.abs(event.offsetY);
                var rgbValues = 'rgb(' + rgb(hsl(xCoord, yCoord)) + ')';
                $(this).css('background', rgbValues);
            }

            function printColorReadout(event) {
                var xCoord = event.offsetX;
                var yCoord = event.offsetY;
                var hslValues = hsl(xCoord, yCoord);
                var rgbValues = rgb(hslValues);
                var hexValues = hex(rgbValues);

                var hslString = parseHSL(hslValues);
                var rgbString = parseRGB(rgbValues);
                var hexString = parseHEX(hexValues);

                $('#hsl').text(hslString);
                $('#rgb').text(rgbString);
                $('#hex').text(hexString);
                $('#swatchhsl').css('background', hslString);
                $('#swatchrgb').css('background', rgbString);
            }

            function hsl(xCoord, yCoord) {
                // HSL = hsl(hue, saturation, luminance)
                var hsl;
                var hue = xCoord;
                var luminance = Math.round(((yCoord / 360) * 100));

                return [hue, 100, luminance];
            }

            function rgb(hslValues) {
                var hue = hslValues[0];
                var sat = hslValues[1] / 100;
                var lum = hslValues[2] / 100;
                var tempLum1, tempLum2, tempHue, tempR, tempG, tempB;

                if (lum < .50) {
                    tempLum1 = lum * (1 + sat);
                } else {
                    tempLum1 = (lum + sat) - (lum * sat);
                }

                tempLum2 = (2 * lum) - tempLum1;
                tempHue = hue / 360;

                tempR = tempHue + .333;
                tempG = tempHue;
                tempB = tempHue - .333;

             //This is the only part I think I did differently. 
             //The code below makes sure the green and blue values 
             //are between 0 and 1, then it checks all the colors to 
             //make sure they are between 0 and 1.  I tried this, 
            // and there was no change in the effect; 
           // the hsl and rgb values were still different.

                if (tempG < 0) { tempG += 1};
                if (tempG > 1) { tempG -= 1};
                if (tempB < 0) { tempB += 1};
                if (tempB > 1) { tempB -= 1};

                var normalizedRGB = [tempR, tempG, tempB].map(function(color, idx) {
                    if (color < 0) { return color += 1};
                    if (color > 1) { return color -= 1};
                    return color;
                });

                var rgbArray = normalizedRGB.map(function(color) {
                    if (colorCondition1(color)) {
                        return tempLum2 + ( tempLum1 - tempLum2 ) * 6 * color;
                    } else if (colorCondition2(color)) {
                        return tempLum1;
                    } else if (colorCondition3(color)) {
                        return tempLum2 + (tempLum1 - tempLum2) * (.666 - color) * 6;
                    }   else {
                        return tempLum2;
                    }
                });

                var rgbValues = rgbArray.map(function(color, idx) {
                    var convertedVal = color * 255;
                    return Math.round(convertedVal);
                });

                return rgbValues;
            }

            function hex(rgbValues) {
                var r = rgbValues[0];
                var g = rgbValues[1];
                var b = rgbValues[2];

                return [numToHex(r), numToHex(g), numToHex(b)];
            }

            function numToHex(num) {
                var hexCode = num.toString(16);
                if (hexCode.length < 2) { hexCode = "0" + hexCode; }
                return hexCode;
            }

            function colorCondition1(val) {
                return 6 * val < 1;
            }

            function colorCondition2(val) {
                return 2 * val < 1;
            }

            function colorCondition3(val) {
                return 3 * val < 2;
            }

            function parseHSL(hslValues) {
                return [
                    "hsl(",
                    hslValues[0], ", ",
                    hslValues[1], "%, ",
                    hslValues[2], "%)"
                ].join('');
            }

            function parseRGB(rgbValues) {
                return "rgb(" + rgbValues.join(', ') + ")";
            }

            function parseHEX(hexValues) {
                return "#" + hexValues.join('');
            }
$(函数(){
console.log('Loaded,bro');
颜色选择器();
});
函数colorPicker(){
var canvas=$(“#canvas”);
canvas.on('mousemove',changeCanvasBackground);
canvas.on('点击',打印颜色读数);
}
功能更改CanvasBackground(事件){
var xCoord=Math.abs(event.offsetX);
var yCoord=Math.abs(event.offsetY);
            $(function() {
                console.log('Loaded, bro');
                colorPicker();
            });

            function colorPicker() {
                var canvas = $('#canvas');
                canvas.on('mousemove', changeCanvasBackground);
                canvas.on('click', printColorReadout);
            }

            function changeCanvasBackground(event) {
                var xCoord = Math.abs(event.offsetX);
                var yCoord = Math.abs(event.offsetY);
                var rgbValues = 'rgb(' + rgb(hsl(xCoord, yCoord)) + ')';
                $(this).css('background', rgbValues);
            }

            function printColorReadout(event) {
                var xCoord = event.offsetX;
                var yCoord = event.offsetY;
                var hslValues = hsl(xCoord, yCoord);
                var rgbValues = rgb(hslValues);
                var hexValues = hex(rgbValues);

                var hslString = parseHSL(hslValues);
                var rgbString = parseRGB(rgbValues);
                var hexString = parseHEX(hexValues);

                $('#hsl').text(hslString);
                $('#rgb').text(rgbString);
                $('#hex').text(hexString);
                $('#swatchhsl').css('background', hslString);
                $('#swatchrgb').css('background', rgbString);
            }

            function hsl(xCoord, yCoord) {
                // HSL = hsl(hue, saturation, luminance)
                var hsl;
                var hue = xCoord;
                var luminance = Math.round(((yCoord / 360) * 100));

                return [hue, 100, luminance];
            }

            function rgb(hslValues) {
                var hue = hslValues[0];
                var sat = hslValues[1] / 100;
                var lum = hslValues[2] / 100;
                var tempLum1, tempLum2, tempHue, tempR, tempG, tempB;

                if (lum < .50) {
                    tempLum1 = lum * (1 + sat);
                } else {
                    tempLum1 = (lum + sat) - (lum * sat);
                }

                tempLum2 = (2 * lum) - tempLum1;
                tempHue = hue / 360;

                tempR = tempHue + .333;
                tempG = tempHue;
                tempB = tempHue - .333;

             //This is the only part I think I did differently. 
             //The code below makes sure the green and blue values 
             //are between 0 and 1, then it checks all the colors to 
             //make sure they are between 0 and 1.  I tried this, 
            // and there was no change in the effect; 
           // the hsl and rgb values were still different.

                if (tempG < 0) { tempG += 1};
                if (tempG > 1) { tempG -= 1};
                if (tempB < 0) { tempB += 1};
                if (tempB > 1) { tempB -= 1};

                var normalizedRGB = [tempR, tempG, tempB].map(function(color, idx) {
                    if (color < 0) { return color += 1};
                    if (color > 1) { return color -= 1};
                    return color;
                });

                var rgbArray = normalizedRGB.map(function(color) {
                    if (colorCondition1(color)) {
                        return tempLum2 + ( tempLum1 - tempLum2 ) * 6 * color;
                    } else if (colorCondition2(color)) {
                        return tempLum1;
                    } else if (colorCondition3(color)) {
                        return tempLum2 + (tempLum1 - tempLum2) * (.666 - color) * 6;
                    }   else {
                        return tempLum2;
                    }
                });

                var rgbValues = rgbArray.map(function(color, idx) {
                    var convertedVal = color * 255;
                    return Math.round(convertedVal);
                });

                return rgbValues;
            }

            function hex(rgbValues) {
                var r = rgbValues[0];
                var g = rgbValues[1];
                var b = rgbValues[2];

                return [numToHex(r), numToHex(g), numToHex(b)];
            }

            function numToHex(num) {
                var hexCode = num.toString(16);
                if (hexCode.length < 2) { hexCode = "0" + hexCode; }
                return hexCode;
            }

            function colorCondition1(val) {
                return 6 * val < 1;
            }

            function colorCondition2(val) {
                return 2 * val < 1;
            }

            function colorCondition3(val) {
                return 3 * val < 2;
            }

            function parseHSL(hslValues) {
                return [
                    "hsl(",
                    hslValues[0], ", ",
                    hslValues[1], "%, ",
                    hslValues[2], "%)"
                ].join('');
            }

            function parseRGB(rgbValues) {
                return "rgb(" + rgbValues.join(', ') + ")";
            }

            function parseHEX(hexValues) {
                return "#" + hexValues.join('');
            }
function convert2RGB(tempColVal, val1, val2){
   //first convert tempColVal to between 0 and 1 then make it an RGB value
   tempColVal = makeRGB01(tempColVal);

  //next run 3 test;
    if(6.0 * tempColVal < 1){
      realColVal = (val2 + (val1 - val2) * 6.0 * tempColVal);
  //    console.log(realColVal + 'test 1; val1: '+ val1 + 'val2: ' + val2  );
    } else if(2.0 * tempColVal < 1){
      realColVal = val1;
  //    console.log(realColVal + 'test 2');
    } else if(3.0 * tempColVal < 2){
      realColVal = (val2 + (val1 - val2)*(0.666 - tempColVal) * 6.0);
  //    console.log(realColVal + 'test 3');
    } else {
      realColVal = val2;
  //    console.log(realColVal + 'realColVal = default (temp 2)');
    };
      // Convert them to 8-bit by multiply them with 255 and return
  return  Math.round(realColVal * 255.0);

};