備忘錄_20160105(定位) 修改 回首頁

程式 2019-10-18 02:18:26 1571336306 100
color picker javascript

color picker javascript
20191018_colorPicker.htm
<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>
    <style>
      
      *
      {
        margin: 0;
        padding: 0;
      }
      
    </style>
  </head>
  <body>
    
    <input type="text" id="txt01" value="">
    <button type="button" id="btn01" onclick="oCP.pickColor('btn01','txt01');";>挑選顏色</button>
    
    <script>
    
      function colorPicker20191012()
      {
        var parent=this;
        
        function gebi(strId)
        {
          return document.getElementById(strId);
        }
      
        this.names={
          strDivBG:"colorPicker20191012.divModalBackground",
          strDivFG:"colorPicker20191012.divModalForeground",
          strDivCnt:"colorPicker20191012.divContent",
          strCanvasChoosen:"colorPicker20191012.myCanvasChoosen",
          strCanvasHS:"colorPicker20191012.myCanvasHS",
          strCanvasV:"colorPicker20191012.myCanvasV",
          strInpH:"colorPicker20191012.inpH",
          strInpS:"colorPicker20191012.inpS",
          strInpV:"colorPicker20191012.inpV",
          strInpR:"colorPicker20191012.inpR",
          strInpG:"colorPicker20191012.inpG",
          strInpB:"colorPicker20191012.inpB",
          strInpHex:"colorPicker20191012.inpHex",
        };
        
        this.strFGColor="";
        this.strBGColor="";
        
        this.booColorPicked=null; // true / false
        this.strColorPicked="";
        this.strBtnId="";
        this.strTxtId="";
        
        this.getStrBGColor=function(strId)
        {
          var strColorValue=window.getComputedStyle(gebi(strId)).backgroundColor;
          strColorValue=strColorValue.split("rgb(").join("");
          strColorValue=strColorValue.split(")").join("");
          var stra1=strColorValue.split(",");
          if(stra1.length!=3) { return "#ffffff"; }
          
          return "#"
            +("00"+(stra1[0]*1).toString(16)).slice(-2)
            +("00"+(stra1[1]*1).toString(16)).slice(-2)
            +("00"+(stra1[2]*1).toString(16)).slice(-2);
        }
        
        this.getStrFGColor=function(strBGColor)
        {
          var strFGColor="#000000";
          
          if(strBGColor.indexOf("#")===0 && strBGColor.length==4)
          {
            strBGColor
              ="#"
              +strBGColor.slice(1, 2)+strBGColor.slice(1, 2)
              +strBGColor.slice(2, 3)+strBGColor.slice(2, 3)
              +strBGColor.slice(3, 4)+strBGColor.slice(3, 4);
          }
          
          if(strBGColor.indexOf("#")===0 && strBGColor.length==7)
          {
            var iR = parseInt(strBGColor.slice(1, 3), 16);
            var iG = parseInt(strBGColor.slice(3, 5), 16);
            var iB = parseInt(strBGColor.slice(5, 7), 16);
            
            var fGray = (iR*0.299+iG*0.587+iB*0.114);
            
            if(fGray > 186) { strFGColor="#000000"; }
            else            { strFGColor="#ffffff"; }
          }
          
          return strFGColor;
        }
        
        this.setColor=function(strId, strBGColor)
        {
          gebi(strId).style.backgroundColor=strBGColor;
          this.strBGColor=this.getStrBGColor(strId);
          gebi(strId).style.backgroundColor=this.strBGColor;
          
          this.strFGColor=this.getStrFGColor(this.strBGColor);
          gebi(strId).style.color=this.strFGColor;
          
          gebi(strId).innerHTML="  挑選顏色 ("+this.strBGColor+")  ";
        }
        
        function getOTableElement()
        {
          var oTB=document.createElement("table");
          oTB.style.borderSpacing="0";
          oTB.style.margin="0 auto";
          oTB.style.padding="4px";
          oTB.style.borderStyle="solid";
          oTB.style.borderWidth="1px";
          oTB.style.borderColor="#000000";
          
            var oTR1=document.createElement("tr");
              
              {
              var oTD11=document.createElement("td");
                var oCanvasChoosen=document.createElement("canvas");
                oCanvasChoosen.setAttribute("id",parent.names.strCanvasChoosen);
                oCanvasChoosen.setAttribute("width","50");
                oCanvasChoosen.setAttribute("height","50");
                oCanvasChoosen.style.borderStyle="solid";
                oCanvasChoosen.style.borderWidth="1px";
                oCanvasChoosen.style.borderColor="#aaaaaa";
                oTD11.appendChild(oCanvasChoosen);
              oTR1.appendChild(oTD11);
              }
            
              {
              var oTD12=document.createElement("td");
                var oCanvasHS=document.createElement("canvas");
                oCanvasHS.setAttribute("id",parent.names.strCanvasHS);
                oCanvasHS.setAttribute("width","300");
                oCanvasHS.setAttribute("height","50");
                oCanvasHS.style.borderStyle="solid";
                oCanvasHS.style.borderWidth="1px";
                oCanvasHS.style.borderColor="#aaaaaa";
                oCanvasHS.style.position="relative";
                oCanvasHS.addEventListener("mousemove",function(event){moveOnHS(event);},false);
                oCanvasHS.addEventListener("click",function(event){clickOnHS(event);},false);
                oTD12.appendChild(oCanvasHS);
              oTR1.appendChild(oTD12);
              }
              
              {
              var oTD13=document.createElement("td");
                var oCanvasV=document.createElement("canvas");
                oCanvasV.setAttribute("id",parent.names.strCanvasV);
                oCanvasV.setAttribute("width","20");
                oCanvasV.setAttribute("height","50");
                oCanvasV.style.borderStyle="solid";
                oCanvasV.style.borderWidth="1px";
                oCanvasV.style.borderColor="#aaaaaa";
                oCanvasV.style.position="relative";
                oCanvasV.addEventListener("mousemove",function(event){moveOnV(event);},false);
                oCanvasV.addEventListener("click",function(event){clickOnV(event);},false);
                oTD13.appendChild(oCanvasV);
              oTR1.appendChild(oTD13);
              }
          
            oTB.appendChild(oTR1);
          
            var oTR2=document.createElement("tr");
              var oTD2=document.createElement("td");
              oTD2.setAttribute("colspan","3");
              
                var oDIV1=document.createElement("div");
                oDIV1.style.float="left";
                  
                  {
                  var oDIV11=document.createElement("div");
                  oDIV11.style.width="40px";
                  oDIV11.style.display="inline-block";
                  oDIV11.innerHTML="HSV";
                  oDIV1.appendChild(oDIV11);
          
                  var oINP11=document.createElement("input");
                  oINP11.setAttribute("type","text");
                  oINP11.setAttribute("id",parent.names.strInpH);
                  oINP11.setAttribute("value","359");
                  oINP11.style.fontFamily="Consolas, Courier";
                  oINP11.style.width="75px";
                  oINP11.style.backgroundColor="#eeeeee";
                  oINP11.addEventListener("blur",function(event){changeHSV();},false);
                  oDIV1.appendChild(oINP11);
                  
                  var oINP12=document.createElement("input");
                  oINP12.setAttribute("type","text");
                  oINP12.setAttribute("id",parent.names.strInpS);
                  oINP12.setAttribute("value","1");
                  oINP12.style.fontFamily="Consolas, Courier";
                  oINP12.style.width="75px";
                  oINP12.style.backgroundColor="#eeeeee";
                  oINP12.addEventListener("blur",function(event){changeHSV();},false);
                  oDIV1.appendChild(oINP12);
                  
                  var oINP13=document.createElement("input");
                  oINP13.setAttribute("type","text");
                  oINP13.setAttribute("id",parent.names.strInpV);
                  oINP13.setAttribute("value","1");
                  oINP13.style.fontFamily="Consolas, Courier";
                  oINP13.style.width="75px";
                  oINP13.style.backgroundColor="#eeeeee";
                  oINP13.addEventListener("blur",function(event){changeHSV();},false);
                  oDIV1.appendChild(oINP13);
                  
                  oDIV1.appendChild(document.createElement("br"));
                  }
                  
                  {
                  var oDIV12=document.createElement("div");
                  oDIV12.style.width="40px";
                  oDIV12.style.display="inline-block";
                  oDIV12.innerHTML="RGB";
                  oDIV1.appendChild(oDIV12);
          
                  var oINP14=document.createElement("input");
                  oINP14.setAttribute("type","text");
                  oINP14.setAttribute("id",parent.names.strInpR);
                  oINP14.setAttribute("value","255");
                  oINP14.style.fontFamily="Consolas, Courier";
                  oINP14.style.width="75px";
                  oINP14.style.backgroundColor="#eeeeee";
                  oINP14.addEventListener("blur",function(event){changeRGB();},false);
                  oDIV1.appendChild(oINP14);
                  
                  var oINP15=document.createElement("input");
                  oINP15.setAttribute("type","text");
                  oINP15.setAttribute("id",parent.names.strInpG);
                  oINP15.setAttribute("value","255");
                  oINP15.style.fontFamily="Consolas, Courier";
                  oINP15.style.width="75px";
                  oINP15.style.backgroundColor="#eeeeee";
                  oINP15.addEventListener("blur",function(event){changeRGB();},false);
                  oDIV1.appendChild(oINP15);
                  
                  var oINP16=document.createElement("input");
                  oINP16.setAttribute("type","text");
                  oINP16.setAttribute("id",parent.names.strInpB);
                  oINP16.setAttribute("value","255");
                  oINP16.style.fontFamily="Consolas, Courier";
                  oINP16.style.width="75px";
                  oINP16.style.backgroundColor="#eeeeee";
                  oINP16.addEventListener("blur",function(event){changeRGB();},false);
                  oDIV1.appendChild(oINP16);
                  
                  oDIV1.appendChild(document.createElement("br"));
                  }
                  
                  {
                  var oDIV13=document.createElement("div");
                  oDIV13.style.width="40px";
                  oDIV13.style.display="inline-block";
                  oDIV13.innerHTML="HEX";
                  oDIV1.appendChild(oDIV13);
          
                  var oINP17=document.createElement("input");
                  oINP17.setAttribute("type","text");
                  oINP17.setAttribute("id",parent.names.strInpHex);
                  oINP17.setAttribute("value","#ffffff");
                  oINP17.style.fontFamily="Consolas, Courier";
                  oINP17.style.width="75px";
                  oINP17.style.backgroundColor="#eeeeee";
                  oINP17.addEventListener("blur",function(event){changeRGB_HEX();},false);
                  oDIV1.appendChild(oINP17);
                  }
                  
                oTD2.appendChild(oDIV1);
                
                var oDIV2=document.createElement("div");
                oDIV2.style.float="right";

                  var oBtnOk=document.createElement("button");
                  oBtnOk.setAttribute("type","button");
                  oBtnOk.innerHTML="確定";
                  oBtnOk.style.padding="4px";
                  oBtnOk.style.width="6em";
                  oBtnOk.style.backgroundColor="#666666";
                  oBtnOk.style.color="#ffffff";
                  oBtnOk.onclick=function()
                  {
                    parent.booColorPicked=true;
                    parent.strColorPicked=oPickUnitColor.getStrRGBHEX();
                    
                    parent.setColor(parent.strBtnId, parent.strColorPicked);
                    gebi(parent.strTxtId).value=parent.strColorPicked;
                    gebi(parent.names.strDivBG).style.display="none";
                  }
                  oDIV2.appendChild(oBtnOk);
                  
                  oDIV2.appendChild(document.createElement("br"));
                  
                  var oBtnCancel=document.createElement("button");
                  oBtnCancel.setAttribute("type","button");
                  oBtnCancel.innerHTML="取消";
                  oBtnCancel.style.padding="4px";
                  oBtnCancel.style.width="6em";
                  oBtnCancel.style.backgroundColor="#666666";
                  oBtnCancel.style.color="#ffffff";
                  oBtnCancel.onclick=function()
                  {
                    parent.booColorPicked=false;
                    parent.strColorPicked="";
                    gebi(parent.names.strDivBG).style.display="none";
                  }
                  oDIV2.appendChild(oBtnCancel);
                
                oTD2.appendChild(oDIV2);
              
              oTR2.appendChild(oTD2);
            oTB.appendChild(oTR2);
            
          return oTB;
        }
        
        this.pickColor=function(strBtnId, strTxtId)
        {
          
          // 先歸零
          this.booColorPicked=null;
          this.strColorPicked="";
          this.strBtnId=strBtnId;
          this.strTxtId=strTxtId;
          
          // 加入 UI
          if(gebi(this.names.strDivBG)==null)
          {
            // 背景
            var oBG=document.createElement("div");
            oBG.setAttribute("id",this.names.strDivBG);
            oBG.style.display="none";
            oBG.style.position="fixed";
            oBG.style.zIndex="1";
            oBG.style.left="0";
            oBG.style.top="0";
            oBG.style.width="100%";
            oBG.style.height="100%";
            oBG.style.overflow="auto";
            oBG.style.backgroundColor="rgb(0,0,0)";
            oBG.style.backgroundColor="rgba(0,0,0,0.7)";
            
            // 前景
            var oFG=document.createElement("div");
            oFG.setAttribute("id",this.names.strDivFG);
            oFG.style.backgroundColor="rgb(255,255,255)";
            oFG.style.margin="10% auto";
            oFG.style.padding="10px";
            oFG.style.borderStyle="solid";
            oFG.style.borderWidth="1px";
            oFG.style.borderColor="#888888";
            oFG.style.borderRadius="12px";
            oFG.style.width="460px";
            oFG.style.minWidth="390px";
          
            // 內文
            var oContent=document.createElement("div");
            oContent.setAttribute("id",this.names.strDivCnt);
            oContent.style.margin="4px";
            oContent.appendChild(getOTableElement()); // 挑選器
            oFG.appendChild(oContent);
            
            // 把前景加入到背景裡頭
            oBG.appendChild(oFG);
          
            // 把背景加入到 body 中
            document.body.appendChild(oBG);
            
            // 點到背景灰黑的部分,等同按下取消。
            /*
            window.addEventListener("click",function(event)
            {
              if(event.target==gebi(parent.names.strDivBG))
              {
                parent.booColorPicked=false;
                parent.strColorPicked="";
                gebi(parent.names.strDivBG).style.display="none";
              }
            },false);
            */
            
          }
          
          // 預設顏色
          oPickUnitColor.setbyrgbhex(this.getStrBGColor(this.strBtnId));
          drawPickColor();
          
          gebi(this.names.strDivBG).style.display="block";
        }
        
        // ------------------------------------
        
        function CUnitColor()
        {
          var parent_unitcolor=this;
          
          this.r=0.0; // 0-1
          this.g=0.0; // 0-1
          this.b=0.0; // 0-1
          this.h=0.0; // [0-360)
          this.s=0.0; // 0-1
          this.v=0.0; // 0-1
          
          this.setbyrgbhex=function(strHex)
          {
            var iR=255,iG=255,iB=255;
            
            if(strHex.indexOf("#")===0 && strHex.length==7)
            {
              iR = parseInt(strHex.slice(1, 3), 16);
              iG = parseInt(strHex.slice(3, 5), 16);
              iB = parseInt(strHex.slice(5, 7), 16);
            }
            
            iR/=255.0;
            iG/=255.0;
            iB/=255.0;
            
            parent_unitcolor.setbyrgb(iR,iG,iB);
          }
          
          this.setbyrgb=function(r,g,b)
          {
            
            this.r=r;
            this.g=g;
            this.b=b;
          
            var max=Math.max(r,g,b);
            var min=Math.min(r,g,b);
            
            if(max==min)            { this.h=0.0; }
            else if(max==r && g>=b) { this.h=60.0*(g-b)/(max-min)+0.0; }
            else if(max==r && g<b)  { this.h=60.0*(g-b)/(max-min)+360.0; }
            else if(max==g)         { this.h=60.0*(b-r)/(max-min)+120.0; }
            else if(max==b)         { this.h=60.0*(r-g)/(max-min)+240.0; }
            else                    { alert("impossible1!"); }
        
            if(max==0) { this.s=0.0; }
            else       { this.s=1.0-min/max; }
        
            this.v=max;
            
          }
          
          this.setbyhsv=function(h,s,v)
          {
            
            this.h=h;
            this.s=s;
            this.v=v;
          
            var hi=Math.floor(h/60.0) % 6;
            var f=h/60.0-hi;
            var p=v*(1.0-s);
            var q=v*(1.0-f*s);
            var t=v*(1.0-(1.0-f)*s);
            
                 if(hi==0) { this.r=v; this.g=t; this.b=p; }
            else if(hi==1) { this.r=q; this.g=v; this.b=p; }
            else if(hi==2) { this.r=p; this.g=v; this.b=t; }
            else if(hi==3) { this.r=p; this.g=q; this.b=v; }
            else if(hi==4) { this.r=t; this.g=p; this.b=v; }
            else if(hi==5) { this.r=v; this.g=p; this.b=q; }
            else { alert("impossible2!"); }
          
          }
          
          this.getStrRGBHEX=function()
          {
            return '#'
              +('00'+(Math.floor(this.r*255)).toString(16)).slice(-2)
              +('00'+(Math.floor(this.g*255)).toString(16)).slice(-2)
              +('00'+(Math.floor(this.b*255)).toString(16)).slice(-2);
          }
          
          this.getIR=function() { return Math.floor(this.r*255); }
          this.getIG=function() { return Math.floor(this.g*255); }
          this.getIB=function() { return Math.floor(this.b*255); }
          
        }
        var oTempUnitColor = new CUnitColor();
        var oPickUnitColor = new CUnitColor();
        oPickUnitColor.setbyrgb(1,1,1); // 白色
  
        function drawPickColor()
        {
          // 將文字盒同步一下
          gebi(parent.names.strInpH).value=Math.floor(oPickUnitColor.h*10000.0)/10000.0;
          gebi(parent.names.strInpS).value=Math.floor(oPickUnitColor.s*10000.0)/10000.0;
          gebi(parent.names.strInpV).value=Math.floor(oPickUnitColor.v*10000.0)/10000.0;
          
          gebi(parent.names.strInpR).value=oPickUnitColor.getIR();
          gebi(parent.names.strInpG).value=oPickUnitColor.getIG();
          gebi(parent.names.strInpB).value=oPickUnitColor.getIB();
          
          gebi(parent.names.strInpHex).value=oPickUnitColor.getStrRGBHEX();
          
          // 開始畫圖
          var realh=oPickUnitColor.h;
          var reals=oPickUnitColor.s;
          var realv=oPickUnitColor.v;
          
          var ctxChoose=gebi(parent.names.strCanvasChoosen).getContext("2d");
          oTempUnitColor.setbyhsv(realh,reals,realv);
          ctxChoose.fillStyle=oTempUnitColor.getStrRGBHEX();
          ctxChoose.fillRect(0, 0, 50, 50);
          
          var v=realv;
          var ctxHS=gebi(parent.names.strCanvasHS).getContext("2d");
          var idHS=ctxHS.createImageData(300,50);
          var d=idHS.data;
          var iIdx=0;
          for(var tmps=49.0; tmps>=0; tmps--)
          {
            for(var tmph=0.0; tmph<300; tmph++)
            {
              var h=tmph/299*359.9999;
              var s=tmps/(49.0);
              oTempUnitColor.setbyhsv(h,s,v);
              
              d[iIdx+0]=Math.floor(oTempUnitColor.r*255);
              d[iIdx+1]=Math.floor(oTempUnitColor.g*255);
              d[iIdx+2]=Math.floor(oTempUnitColor.b*255);
              d[iIdx+3]=255;
              iIdx+=4;
            }
          }
          ctxHS.putImageData(idHS,0,0);
          
          var ctxV=gebi(parent.names.strCanvasV).getContext("2d");
          var idV=ctxV.createImageData(20,50);
          var d=idV.data;
          var iIdx=0;
          for(var tmpv=49.0; tmpv>=0; tmpv--)
          {
            var v=tmpv/(49.0);
            oTempUnitColor.setbyhsv(realh,reals,v);
            
            for(var x=0.0; x<20.0; x++)
            {
              d[iIdx+0]=Math.floor(oTempUnitColor.r*255);
              d[iIdx+1]=Math.floor(oTempUnitColor.g*255);
              d[iIdx+2]=Math.floor(oTempUnitColor.b*255);
              d[iIdx+3]=255;
              iIdx+=4;
            }
          }
          ctxV.putImageData(idV,0,0);
          
        }
  
        function changeHSV()
        {
          if(gebi(parent.names.strInpH).value>=0.0 && gebi(parent.names.strInpH).value<360.0) {} else { gebi(parent.names.strInpH).value=359.9999; }
          if(gebi(parent.names.strInpS).value>=0.0 && gebi(parent.names.strInpS).value<=1.0) {}  else { gebi(parent.names.strInpS).value=1.0; }
          if(gebi(parent.names.strInpV).value>=0.0 && gebi(parent.names.strInpV).value<=1.0) {}  else { gebi(parent.names.strInpV).value=1.0; }
          
          oPickUnitColor.setbyhsv(gebi(parent.names.strInpH).value, gebi(parent.names.strInpS).value, gebi(parent.names.strInpV).value);
          drawPickColor();
        }
        
        function changeRGB()
        {
          if(gebi(parent.names.strInpR).value>=0.0 && gebi(parent.names.strInpR).value<=255.0) {} else { gebi(parent.names.strInpR).value=255.0; }
          if(gebi(parent.names.strInpG).value>=0.0 && gebi(parent.names.strInpG).value<=255.0) {} else { gebi(parent.names.strInpG).value=255.0; }
          if(gebi(parent.names.strInpB).value>=0.0 && gebi(parent.names.strInpB).value<=255.0) {} else { gebi(parent.names.strInpB).value=255.0; }
          
          oPickUnitColor.setbyrgb(gebi(parent.names.strInpR).value/255.0, gebi(parent.names.strInpG).value/255.0, gebi(parent.names.strInpB).value/255.0);
          drawPickColor();
        }
        
        function changeRGB_HEX()
        {
          
          var strHEX=gebi(parent.names.strInpHex).value;
          if(strHEX.substring(0,1)!="#") { strHEX="#ffffff"; }
          if(strHEX.length==4) { strHEX="#"+strHEX.substring(1,2)+strHEX.substring(1,2)+strHEX.substring(2,3)+strHEX.substring(2,3)+strHEX.substring(3,4)+strHEX.substring(3,4); }
          if(strHEX.length!=7) { strHEX="#ffffff"; }
          
          var iR,iG,iB;
          
          iR=parseInt(strHEX.substring(1,3), 16);
          if(isNaN(iR)==true) { iR=255; }
          if(iR<0) { iR=0; }
          if(iR>255) { iR=255; }
          
          iG=parseInt(strHEX.substring(3,5), 16);
          if(isNaN(iG)==true) { iG=255; }
          if(iG<0) { iG=0; }
          if(iG>255) { iG=255; }
          
          iB=parseInt(strHEX.substring(5,7), 16);
          if(isNaN(iB)==true) { iB=255; }
          if(iB<0) { iB=0; }
          if(iB>255) { iB=255; }
          
          oPickUnitColor.setbyrgb(iR/255.0,iG/255.0,iB/255.0);
          drawPickColor();
          
        }
        
        // ------------------------------------
        
        var booMouseDown=false;
        window.addEventListener("mousedown",function(event) { booMouseDown=true; },false);
        window.addEventListener("mouseup",function(event) { booMouseDown=false; },false);
        
        function moveOnHS(event) 
        { 
          if(booMouseDown==true) { clickOnHS(event); }
        }
        
        function clickOnHS(event)
        {
          var fX = event.clientX-(gebi(parent.names.strCanvasHS).getBoundingClientRect()).left;
          var fY = event.clientY-(gebi(parent.names.strCanvasHS).getBoundingClientRect()).top;
          
          gebi(parent.names.strInpH).value=Math.floor((fX/300.0*359.9999)*10000.0)/10000.0;
          gebi(parent.names.strInpS).value=1.0-Math.floor(fY/50.0*10000.0)/10000.0;
          changeHSV();
        }
        
        function moveOnV(event)
        {
          if(booMouseDown==true) { clickOnV(event); }
        }
        
        function clickOnV(event)
        {
          var fX = event.clientX-(gebi(parent.names.strCanvasV).getBoundingClientRect()).left;
          var fY = event.clientY-(gebi(parent.names.strCanvasV).getBoundingClientRect()).top;
          
          gebi(parent.names.strInpV).value=1.0-Math.floor(fY/50.0*10000.0)/10000.0;
          changeHSV();
        }
          
        
      }
      var oCP=new colorPicker20191012(); // 只能創建一個!
      
      window.onload=function()
      {
        oCP.setColor("btn01","#39a");
        // oCP.pickColor('btn01','txt01');
      }
      
    </script>
    
  </body>
</html>