-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathpixart.htm
100 lines (100 loc) · 23.7 KB
/
pixart.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<!DOCTYPE html> <html> <head> <meta http-equiv="Cache-Control"
content="no-cache, no-store, must-revalidate"> <meta http-equiv="Pragma"
content="no-cache"> <meta http-equiv="Expires" content="0"> <title>
WLED Pixel Art Converter</title> <style>
.box{border:2px solid #fff}body{font-family:Arial,sans-serif;background-color:#111}.top-part{width:600px;margin:0 auto}.container{max-width:100% -40px;border-radius:0;padding:20px;text-align:center}h1{font-size:2.3em;color:#ddd;margin:1px 0;font-family:Arial,sans-serif;line-height:.5}h2{font-size:1.1em;color:rgba(221,221,221,.61);margin:1px 0;font-family:Arial,sans-serif;line-height:.5;text-align:center}h3{font-size:.7em;color:rgba(221,221,221,.61);margin:1px 0;font-family:Arial,sans-serif;line-height:1.4;text-align:center;align-items:center;justify-content:center;display:flex}p{font-size:1em;color:#777;line-height:1.5;font-family:Arial,sans-serif}#fieldTable{font-size:1 em;color:#777;line-height:1;font-family:Arial,sans-serif}#scaleTable{font-size:1 em;color:#777;line-height:1;font-family:Arial,sans-serif}#drop-zone{display:block;width:100%-40px;border:3px dashed #ddd;border-radius:0;text-align:center;padding:20px;margin:0;cursor:pointer;font-family:Arial,sans-serif;font-size:15px;color:#777}#file-picker{display:none}.adaptiveTD{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center}.mainSelector{background-color:#222;color:#ddd;border:1px solid #333;margin-top:4px;margin-bottom:4px;padding:0 8px;height:28px;font-size:15px;border-radius:7px;flex-grow:1;display:flex;align-items:center;justify-content:center}.adaptiveSelector{background-color:#222;color:#ddd;border:1px solid #333;margin-top:4px;margin-bottom:4px;padding:0 8px;height:28px;font-size:15px;border-radius:7px;flex-grow:1;display:none}.segmentsDiv{width:36px;padding-left:5px}* input[type=range]{appearance:none;-moz-appearance:none;-webkit-appearance:none;flex-grow:1;padding:0;margin:4px 8px 4px 0;background-color:transparent;cursor:pointer;background:linear-gradient(to right,#bbb 50%,#333 50%);border-radius:7px}input[type=range]:focus{outline:0}input[type=range]::-webkit-slider-runnable-track{height:28px;cursor:pointer;background:0 0;border-radius:7px}input[type=range]::-webkit-slider-thumb{height:16px;width:16px;border-radius:50%;background:#fff;cursor:pointer;-webkit-appearance:none;margin-top:4px;border-radius:7px}input[type=range]::-moz-range-track{height:28px;background-color:rgba(0,0,0,0);border-radius:7px}input[type=range]::-moz-range-thumb{border:0 solid transparent;height:16px;width:16px;border-radius:7px;background:#fff}.rangeNumber{width:20px;vertical-align:middle}.fullTextField[type=text]{background-color:#222;border:1px solid #333;padding-inline-start:5px;margin-top:4px;margin-bottom:4px;height:24px;border-radius:0;font-family:Arial,sans-serif;font-size:15px;color:#ddd;border-radius:7px;flex-grow:1;display:flex;align-items:center;justify-content:center}.flxTFld{background-color:#222;border:1px solid #333;padding-inline-start:5px;height:24px;border-radius:0;font-family:Arial,sans-serif;font-size:15px;color:#ddd;border-radius:7px;flex-grow:1;display:flex;align-items:center;justify-content:center}* input[type=submit]{background-color:#222;border:1px solid #333;padding:.5em;width:100%;border-radius:24px;font-family:Arial,sans-serif;font-size:1.3em;color:#ddd}* button{background-color:#222;border:1px solid #333;padding-inline:5px;width:100%;border-radius:24px;font-family:Arial,sans-serif;font-size:1em;color:#ddd;display:flex;align-items:center;justify-content:center;cursor:pointer}#scaleDiv{display:flex;align-items:center;vertical-align:middle}textarea{grid-row:1/2;width:100%;height:200px;background-color:#222;border:1px solid #333;color:#ddd}.hide{display:none}.svg-icon{vertical-align:middle}#image-container{display:grid;grid-template-rows:1fr 1fr}#button-container{display:flex;padding-bottom:10px;padding-top:10px}.buttonclass{flex:1;padding-top:5px;padding-bottom:5px}.gap{width:10px}#submitConvert::before{content:"";display:inline-block;background-image:url('data:image/svg+xml;utf8, <svg style="width:24px;height:24px" viewBox="0 0 24 24" <path fill="currentColor" d="M12,6V9L16,5L12,1V4A8,8 0 0,0 4,12C4,13.57 4.46,15.03 5.24,16.26L6.7,14.8C6.25,13.97 6,13 6,12A6,6 0 0,1 12,6M18.76,7.74L17.3,9.2C17.74,10.04 18,11 18,12A6,6 0 0,1 12,18V15L8,19L12,23V20A8,8 0 0,0 20,12C20,10.43 19.54,8.97 18.76,7.74Z" /></svg>');width:36px;height:36px}#sizeDiv *{display:inline-block}.sizeInputFields{width:50px;background-color:#222;border:1px solid #333;padding-inline-start:5px;margin-top:-5px;height:24px;border-radius:7px;font-family:Arial,sans-serif;font-size:15px;color:#ddd}a:link{color:rgba(221,221,221,.61);background-color:transparent;text-decoration:none}a:visited{color:rgba(221,221,221,.61);background-color:transparent;text-decoration:none}a:hover{color:#ddd;background-color:transparent;text-decoration:none}a:active{color:rgba(221,221,221,.61);background-color:transparent;text-decoration:none}
</style> <link rel="shortcut icon"
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAkNJREFUOE+lUstO21AUnHNsF0V+0EXVivAXfAe7qlL7EZEcQ5cQ8nCICbDJF7Trvhas6YbyDdBu2hSk7kihscK1fU91HRKKaFf1xhrP8ejMnCH850P/+v/cC2qcqw4gsGD3Hk/G23+bvSdw7nk1K887BeCQ4AGMAiEjcGaB7gndEfhRqdRQSC9ncQikAVisAWGBFggR5QvQ7UcTNd9mLvDdC2p2rhIN2G4U/vRbneyynzhps70oAPlhNPLjZna1v4/xVmtQHU8tzQXO3CCk4nrPD8MLN+6qd8ef8erwBKvH750XK1Xy4li9/fQFrw9PAGSDg8azuwJDN6jbuep7a+GFF3ezN0en5fDq8Qfn+UqVgjhW5bePpwCKwUHj6a2ACY7zrCdCC34UjrzutjLZiQC/kh0HlyPyu9tKzM4iGPf7uG5sDEwWpYWvrh85RZYAYAIp7+XayNtqytXeLqWbjUUNcLC+fuG2mpLu7tPl5sZDAnpLk0mzFDir+BFJlkCECaKFuSBYSlA4pLWtiRjEygIyErFzyIKjreYTlbZKgaHrRlzoHotweXeAhEhIxPBTDBhQYgEYhNbybINhxY1sbSwwkbHOZrzs3VRmjmnOk6bOkrqxMHT9yCqyxNybAFMg1mWRBGYlg2eboOSFGdT+IwM3Eil6zBwXZF1xkSWkOa6qtHleceuQvC+g4pZXiaOt9jyDb24Q2qKC5XTSvrlK3ZHMW04nLdMPKtQOMzoGTzPz69YNP2vi7D11ftvQWYCzyt7jfwO10TQgL5hT6QAAAABJRU5ErkJggg==">
<script type="text/javascript">
function gId(e){return d.getElementById(e)}function cE(e){return d.createElement(e)}var d=document
</script> </head> <body> <body> <div class="top-part"> <div
style="display:flex;justify-content:center"> <h1
style="display:flex;align-items:center"> <svg
style="width:36px;height:36px;margin-right:6px" viewBox="0 0 32 32"><path
fill="#003fff" d="M6 22h8v4H6zM14 14h4v8h-4zM18 10h4v8h-4zM22 6h8v4h-8z"/></svg>
WLED Pixel Art Converter </h1> </div> <h2>
Convert image to WLED JSON (pixel art on WLED matrix)</h2> <p> <table
id="fieldTable" style="width:100%;table-layout:fixed;align-content:center"> <tr>
<td style="vertical-align:middle"> <label for="ledSetupSelector">Led setup:
</label> </td> <td class="adaptiveTD"> <select id="ledSetupSelector"
class="mainSelector"> <option value="matrix" selected="selected">2D Matrix
</option> <option value="r2l">Serpentine, first row right to left <-</option>
<option value="l2r">Serpentine, first row left to right -></option>
</select> </td> </tr> <tr> <td style="vertical-align:middle"> <label
for="formatSelector">Output format:</label> </td> <td class="adaptiveTD">
<select id="formatSelector" class="mainSelector"> <option value="wled"
selected="selected">WLED JSON</option> <option value="curl">CURL</option>
<option value="ha">Home Assistant YAML</option> </select> </td> </tr> <tr> <td
style="vertical-align:middle"> <label for="colorFormatSelector">
Color code format:</label> </td> <td class="adaptiveTD"> <select
id="colorFormatSelector" class="mainSelector"> <option value="hex"
selected="selected">HEX ("f4f4f4")</option> <option value="dec">
DEC (244,244,244)</option> </select> </td> </tr> <tr> <td
style="vertical-align:middle"> <label for="addressingSelector">Addressing:
</label> </td> <td class="adaptiveTD"> <select id="addressingSelector"
class="mainSelector"> <option value="hybrid" selected="selected">
Hybrid ("f0f0f0",10, 17, "f4f4f4")</option> <option
value="range">Range (10, 17, "f4f4f4")</option> <option
value="single">Single ("f4f4f4")</option> </select> </td> </tr> <tr>
<td style="vertical-align:middle"> <label for="brightnessNumber">Brightness:
</label> </td> <td
style="vertical-align:middle;display:flex;align-items:center"> <input
type="range" id="brightnessNumber" min="1" max="255" value="128"> <span
id="brightnessValue">128</span> </td> </tr> <tr> <td
style="vertical-align:middle"> <label for="colorLimitNumber">
Max no of colors/JSON:</label> </td> <td
style="vertical-align:middle;display:flex;align-items:center"> <input
type="range" id="colorLimitNumber" min="1" max="512" value="256"> <span
id="colorLimitValue">256</span> </td> </tr> <tr class="ha-hide"> <td
style="vertical-align:middle"> <label for="haID">HA Device ID:</label> </td> <td
class="adaptiveTD"> <input class="fullTextField" type="text" id="haID"
value="pixel_art_controller_001"> </td> </tr> <tr class="ha-hide"> <td
style="vertical-align:middle"> <label for="haUID">HA Device Unique ID:</label>
</td> <td class="adaptiveTD"> <input class="fullTextField" type="text"
id="haUID" value="pixel_art_controller_001a"> </td> </tr> <tr class="ha-hide">
<td style="vertical-align:middle"> <label for="haName">HA Device Name:</label>
</td> <td class="adaptiveTD"> <input class="fullTextField" type="text"
id="haName" value="Pixel Art Kitchen"> </td> </tr> <tr> <td
style="vertical-align:middle"> <label for="curlUrl">Device IP/host name:</label>
</td> <td class="adaptiveTD"> <input class="fullTextField" type="text"
id="curlUrl" value> </td> </tr> <tr> <td style="vertical-align:middle"> <label
for="targetSegment">Target segment id:</label> </td> <td class="adaptiveTD">
<input class="flxTFld" type="number" id="segID" value="0" min="0" max="63">
<select id="targetSegment" class="adaptiveSelector"> </select> <div
id="getSegmentsDiv" class="segmentsDiv"></div> </td> </tr> </table> <table
class="scaleTableClass" id="scaleTable"
style="width:100%;table-layout:fixed;align-content:center"> <tr> <td
style="vertical-align:middle"> <div id="scaleDiv"> <svg
style="width:36px;height:36px" viewBox="0 0 24 24" onclick="switchScale()"
cursor="pointer"><path fill="currentColor"
d="M17 7H7a5 5 0 0 0-5 5 5 5 0 0 0 5 5h10a5 5 0 0 0 5-5 5 5 0 0 0-5-5M7 15a3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3 3 3 0 0 1-3 3z"/>
</svg> Scale image </div> </td> <td style="vertical-align:middle"> <div
id="sizeDiv" style="display:none"> <label for="sizeX">W : </label> <input
class="sizeInputFields" type="number" id="sizeX" min="1" value="16">
<label for="sizeY">H : </label> <input
class="sizeInputFields" type="number" id="sizeY" min="1" value="16"> </div>
</td> </tr> </table> </p> <p> <label for="file-picker"> <div id="drop-zone">
Drop image here <br>or <br> Click to select a file </div> </label> </p> <p>
<input type="file" id="file-picker" style="display:none"> </p><div
style="width:100%;text-align:center"> <img id="preview"
style="display:none;margin:0 auto" src="data:text/html;base64,"> </div> <div
id="raw-image-container" style="display:none"> <img id="image"
src="data:text/html;base64," alt="RawImage image"> </div> <p></p> <div
id="image-container" style="display:none"> <div id="image-info"
style="display:none"></div> <textarea id="JSONled" readonly="readonly">
</textarea> </div> <div id="button-container" style="display:none"> <button
id="copyJSONledbutton" class="buttonclass"></button> <div id="gap1" class="gap">
</div> <button id="sendJSONledbutton" class="buttonclass"></button> </div> <div>
<h3><div id="version">Version 1.0.8</div> - <a
href="https://github.com/werkstrom/WLED-PixelArtConverter/blob/main/README.md"
target="_blank">Help/About</a></h3> </div> </div> <div id="bottom-part"
style="display:none" class="bottom-part"></div> <canvas id="pixelCanvas">
</canvas> <script type="text/javascript">
for(var gurl=gId("curlUrl"),szX=gId("sizeX"),szY=gId("sizeY"),szDiv=gId("sizeDiv"),prw=gId("preview"),sID=gId("segID"),JLD=gId("JSONled"),tSg=gId("targetSegment"),brgh=gId("brightnessNumber"),seDiv=gId("getSegmentsDiv"),cjb=gId("copyJSONledbutton"),frm=gId("formatSelector"),cLN=gId("colorLimitNumber"),haIDe=gId("haID"),haUe=gId("haUID"),haNe=gId("haName"),aS=gId("addressingSelector"),cFS=gId("colorFormatSelector"),lSS=gId("ledSetupSelector"),imin=gId("image-info"),imcn=gId("image-container"),bcn=gId("button-container"),im=gId("image"),scDiv=gId("scaleDiv"),w=window,canvas=gId("pixelCanvas"),brgV=gId("brightnessValue"),cLV=gId("colorLimitValue"),httpArray=[],fileJSON="",hideableRows=d.querySelectorAll(".ha-hide"),i=0;i<hideableRows.length;i++)hideableRows[i].classList.add("hide");var accentColor="#eee",accentTextColor="#777",prsCol="#ccc",greenColor="#056b0a",redColor="#6b050c",scaleToggleOffd="M17,7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7M7,15A3,3 0 0,1 4,12A3,3 0 0,1 7,9A3,3 0 0,1 10,12A3,3 0 0,1 7,15Z",scaleToggleOnd="M17,7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7M17,15A3,3 0 0,1 14,12A3,3 0 0,1 17,9A3,3 0 0,1 20,12A3,3 0 0,1 17,15Z",sSg=gId("getSegmentsSVGpath")
</script> <script type="text/javascript">
function getPixelRGBValues(e){httpArray=[],fileJSON=`{"on":true,"bri":${brgh.value},"seg":{"id":${tSg.value},"i":[`;let t=0;t="flex"==tSg.style.display?tSg.value:sID.value;const l=parseInt(cLN.value);let n=!1,a=-1;a=frm.selectedIndex;const i=frm.options[a].value;a=lSS.selectedIndex;const o=lSS.options[a].value;a=cFS.selectedIndex;let s=!0;"dec"==cFS.options[a].value&&(s=!1),a=aS.selectedIndex;let r=!0;"single"==aS.options[a].value?r=!1:"hybrid"==aS.options[a].value&&(n=!0);let u="",d="",c='"',h='"';s||(c="[",h="]");let p=!1,f="";var g=cE("canvas"),m=g.getContext("2d",{willReadFrequently:!0}),v=new Image;v.src=e,v.onload=function(){let e=scDiv.children[0].children[0].getAttribute("fill"),a=szX.value,y=szY.value;(e!=accentColor||a<1||y<1)&&(a=v.width,y=v.height,(v.width>512||v.height>512)&&(a=16,y=16)),g.width=a,g.height=y,f="<p>Width: "+a+", Height: "+y+" (make sure this matches your led matrix setup)</p>",m.drawImage(v,0,0,a,y);var S=m.getImageData(0,0,a,y).data,I=[];let $=1;"l2r"==o&&($=0);for(var w=0;w<S.length;w+=4){var b=S[w],x=S[w+1],N=S[w+2],T=S[w+3];let e=w/4,t=Math.floor(e/a),l=e;if("matrix"==o);else if((t+$)%2==0);else{l=t*a+(a-1-(l-t*a))}I.push([b,x,N,T,l,e,t])}I.sort((e,t)=>e[5]-t[5]);let O=[...I];O.sort((e,t)=>e[4]-t[4]);let A="",D=-1,R=O.length,j=0,C=[];for(let e=0;e<R;e++){let t=O[e],a=t[0],i=t[1],o=t[2],u=t[3],d="",f=-1;if(r)if(D<0&&(D=e),e<R-1){let t=O[e+1];t[0]==a&&t[1]==i&&t[2]==o||(f=e+1,d=D==e&&n?""==A?e+",":"":D+","+f+",")}else f=e+1,d=D+1==f&&n?""==A?e+",":"":D+","+f+",";else""==A&&(A=e),D=e,f=e;if(u<255&&(p=!0),f>-1){let t=a+","+i+","+o;if(s){const[e,l,n]=[a,i,o];t=""+[e,l,n].map(e=>e.toString(16).padStart(2,"0")).join("")}A+=d+c+t+h,fileJSON=A+d+c+t+h,j+=1,j%l==0||e==R-1?(C.push(A),A=""):A+=",",D=-1}}A="";for(let e=0;e<C.length;e++){let l=`{"on":true,"bri":${brgh.value},"seg":{"id":${t},"i":[${C[e]}]}}`;httpArray.push(l);let n=`curl -X POST "http://${gurl.value}/json/state" -d '${l}' -H "Content-Type: application/json"`;e>0&&(A+="\n<NEXT COMMAND (multiple commands not supported in API/preset setup)>\n",u+=" && "),A+=l,u+=n}d=`#Uncomment if you don't allready have these defined in your switch section of your configuration.yaml \n#- platform: command_line \n #switches: \n ${haIDe.value} \n friendly_name: ${haNe.value} \n unique_id: ${haUe.value} \n command_on: > \n ${u} \n command_off: > \n curl -X POST "http://${gurl.value}/json/state" -d '{"on":false}' -H "Content-Type: application/json"`,JLD.value="wled"==i?A:"curl"==i?u:"ha"==i?d:"ERROR!/n"+i+" is an unknown format.",fileJSON+="]}}";let _=imin,H=imin;p&&(f+="<p><b>WARNING!</b> Transparency info detected in image. Transparency (alpha) has been ignored. To ensure you get the result you desire, use only solid colors in your image.</p>"),_.innerHTML=f,H.style.display="block",drawBoxes(I,a,y)}}
</script> <script type="text/javascript">
function drawBoxes(t,e,a){var i=window,n=canvas.getContext("2d",{willReadFrequently:!0});i.innerHeight<i.innerWidth?canvas.width=Math.floor(.98*i.innerHeight):canvas.width=Math.floor(.98*i.innerWidth);let l=Math.floor(canvas.width/e),h=(i.innerWidth-e*l)/2;canvas.height=l*a+10;for(let i=0;i<a;i++)for(let a=0;a<e;a++){let h=t[i*e+a],r="rgb("+h[0]+", "+h[1]+", "+h[2]+")",d="rgb(128,128,128)";n.fillStyle=r,n.fillRect(a*l,i*l,l,l),n.strokeStyle="#888888",n.lineWidth=1,n.strokeRect(a*l,i*l,l,l),n.font="10px Arial",n.fillStyle=d,n.textAlign="center",n.textBaseline="middle",n.fillText(h[4]+1,a*l+l/2,i*l+l/2)}var r=n.getImageData(0,0,canvas.width,canvas.height);n.clearRect(0,0,canvas.width,canvas.height),canvas.width=i.innerWidth,n.putImageData(r,h,0)}
</script> <script type="text/javascript">
let devMode=!1;gurl.value=location.host;const urlParams=new URLSearchParams(window.location.search);function gen(){if((szX.value>0&&szY.value>0||"none"==szDiv.style.display)&&gurl.value.length>0&&"none"!=prw.style.display){let e=prw.src;if(isValidBase64Gif(e))im.src=e,getPixelRGBValues(e),imcn.style.display="block",bcn.style.display="";else{let t="<p><b>WARNING!</b> File does not appear to be a valid image</p>";imin.innerHTML=t,imin.style.display="block",imcn.style.display="none",JLD.value="",devMode&&console.log("The string '"+e+"' is not a valid base64 image.")}}if(gurl.value.length>0)gId("sSg").setAttribute("fill",accentColor);else{gId("sSg").setAttribute("fill",accentTextColor);let e=tSg;e.style.display="none",e.innerHTML="",sID.style.display="flex"}}async function postPixels(){let e=gId("sendSvgP");e.setAttribute("fill",prsCol);let t=!1;for(let e of httpArray)try{devMode&&console.log(e),devMode&&console.log(e.length);const t=await fetch("http://"+gId("curlUrl").value+"/json/state",{method:"POST",headers:{"Content-Type":"application/json"},body:e}),n=await t.json();devMode&&console.log(n)}catch(e){console.error(e),t=!0}t?(e.setAttribute("fill",redColor),setTimeout((function(){e.setAttribute("fill",accentTextColor)}),1e3)):(e.setAttribute("fill",greenColor),setTimeout((function(){e.setAttribute("fill",accentColor)}),1e3))}gurl.value.length<1&&(gurl.value="Missing_Host"),cjb.addEventListener("click",async()=>{let e=JLD;e.select();try{await navigator.clipboard.writeText(e.value)}catch(e){try{await d.execCommand("copy")}catch(e){console.error("Failed to copy text: ",e)}}}),lSS.addEventListener("change",gen),szY.addEventListener("change",gen),szX.addEventListener("change",gen),cFS.addEventListener("change",gen),aS.addEventListener("change",gen),brgh.addEventListener("change",gen),cLN.addEventListener("change",gen),haIDe.addEventListener("change",gen),haUe.addEventListener("change",gen),haNe.addEventListener("change",gen),gurl.addEventListener("change",gen),sID.addEventListener("change",gen),prw.addEventListener("load",gen),tSg.addEventListener("change",()=>{sop=tSg.options[tSg.selectedIndex],szX.value=sop.dataset.x,szY.value=sop.dataset.y,gen()}),gId("sendJSONledbutton").addEventListener("click",async()=>{"https:"===window.location.protocol?alert("Will only be available when served over http (or WLED is run over https)"):postPixels()}),brgh.oninput=()=>{brgV.textContent=brgh.value;let e=100*parseInt(brgh.value)/255;var t=`linear-gradient(90deg, #bbb ${e}%, #333 ${e}%)`;brgh.style.backgroundImage=t},cLN.oninput=()=>{let e=cLN;cLV.textContent=e.value;let t=100*parseInt(e.value)/512;var n=`linear-gradient(90deg, #bbb ${t}%, #333 ${t}%)`;e.style.backgroundImage=n},frm.addEventListener("change",()=>{for(var e=0;e<hideableRows.length;e++)hideableRows[e].classList.toggle("hide","ha"!==frm.value),gen()});const dropZone=gId("drop-zone"),filePicker=gId("file-picker"),preview=prw;function zoneClicked(e){e.preventDefault(),filePicker.click()}function dragEnter(e){e.preventDefault(),this.classList.add("drag-over")}function dragOver(e){e.preventDefault()}function dropped(e){e.preventDefault(),this.classList.remove("drag-over");updatePreview(e.dataTransfer.files[0])}function filePicked(e){updatePreview(e.target.files[0])}function updatePreview(e){const t=new FileReader;t.onload=()=>{preview.src=t.result,prw.style.display=""},t.readAsDataURL(e)}function isValidBase64Gif(e){return!0}dropZone.addEventListener("dragenter",dragEnter),dropZone.addEventListener("dragover",dragOver),dropZone.addEventListener("drop",dropped),dropZone.addEventListener("click",zoneClicked),filePicker.addEventListener("change",filePicked);for(var hideableRows=d.querySelectorAll(".ha-hide"),i=0;i<hideableRows.length;i++)hideableRows[i].classList.add("hide");function switchScale(){let e=scDiv.children[0].children[0],t=e.getAttribute("fill"),n="";t===accentColor?(t=accentTextColor,n=scaleToggleOffd,szDiv.style.display="none"):(t=accentColor,n=scaleToggleOnd,szDiv.style.display=""),e.setAttribute("fill",t),e.setAttribute("d",n),gen()}function generateSegmentOptions(e){tSg.innerHTML="";for(var t=0;t<e.length;t++){var n=cE("option");n.value=e[t].value,n.text=e[t].text,n.dataset.x=e[t].x,n.dataset.y=e[t].y,tSg.appendChild(n),0===t&&(n.selected=!0,szX.value=n.dataset.x,szY.value=n.dataset.y)}}async function getSegments(){if(cv=gurl.value,cv.length>0)try{var e=[];const n=await fetch("http://"+cv+"/json/state");let l=(await n.json()).seg.map(e=>({id:e.id,n:e.n,xs:e.start,xe:e.stop,ys:e.startY,ye:e.stopY}));for(var t=0;t<l.length;t++)e.push({value:l[t].id,text:l[t].n+" (index: "+l[t].id+")",x:l[t].xe-l[t].xs,y:l[t].ye-l[t].ys});generateSegmentOptions(e),tSg.style.display="flex",sID.style.display="none",gId("sSg").setAttribute("fill",greenColor),setTimeout((function(){gId("sSg").setAttribute("fill",accentColor)}),1e3)}catch(e){console.error(e),gId("sSg").setAttribute("fill",redColor),setTimeout((function(){gId("sSg").setAttribute("fill",accentColor)}),1e3),tSg.style.display="none",sID.style.display="flex"}else gId("sSg").setAttribute("fill",redColor),setTimeout((function(){gId("sSg").setAttribute("fill",accentTextColor)}),1e3),tSg.style.display="none",sID.style.display="flex"}function generateSegmentArray(e){for(var t=[],n=0;n<e;n++)t.push({value:n,text:"Segment index "+n});return t}frm.addEventListener("change",()=>{for(var e=0;e<hideableRows.length;e++)hideableRows[e].classList.toggle("hide","ha"!==frm.value)});var segmentData=generateSegmentArray(10);generateSegmentOptions(segmentData),seDiv.innerHTML='<svg id=getSegmentsSVG style="width:36px;height:36px;cursor:pointer" viewBox="0 0 24 24" onclick="getSegments()"><path id=sSg fill="currentColor" d="M6.5 20Q4.22 20 2.61 18.43 1 16.85 1 14.58 1 12.63 2.17 11.1 3.35 9.57 5.25 9.15 5.68 7.35 7.38 5.73 9.07 4.1 11 4.1 11.83 4.1 12.41 4.69 13 5.28 13 6.1V12.15L14.6 10.6L16 12L12 16L8 12L9.4 10.6L11 12.15V6.1Q9.1 6.45 8.05 7.94 7 9.43 7 11H6.5Q5.05 11 4.03 12.03 3 13.05 3 14.5 3 15.95 4.03 17 5.05 18 6.5 18H18.5Q19.55 18 20.27 17.27 21 16.55 21 15.5 21 14.45 20.27 13.73 19.55 13 18.5 13H17V11Q17 9.8 16.45 8.76 15.9 7.73 15 7V4.68Q16.85 5.55 17.93 7.26 19 9 19 11 20.73 11.2 21.86 12.5 23 13.78 23 15.5 23 17.38 21.69 18.69 20.38 20 18.5 20M12 11.05Z" /></svg>',cjb.innerHTML='<svg class="svg-icon" style="width:36px;height:36px" viewBox="0 0 24 24"> <path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z" /> </svg> Copy to clipboard',gId("sendJSONledbutton").innerHTML='<svg class="svg-icon" style="width:36px;height:36px" viewBox="0 0 24 24"> <path id=sendSvgP fill="currentColor" d="M6.5 20Q4.22 20 2.61 18.43 1 16.85 1 14.58 1 12.63 2.17 11.1 3.35 9.57 5.25 9.15 5.88 6.85 7.75 5.43 9.63 4 12 4 14.93 4 16.96 6.04 19 8.07 19 11 20.73 11.2 21.86 12.5 23 13.78 23 15.5 23 17.38 21.69 18.69 20.38 20 18.5 20H13Q12.18 20 11.59 19.41 11 18.83 11 18V12.85L9.4 14.4L8 13L12 9L16 13L14.6 14.4L13 12.85V18H18.5Q19.55 18 20.27 17.27 21 16.55 21 15.5 21 14.45 20.27 13.73 19.55 13 18.5 13H17V11Q17 8.93 15.54 7.46 14.08 6 12 6 9.93 6 8.46 7.46 7 8.93 7 11H6.5Q5.05 11 4.03 12.03 3 13.05 3 14.5 3 15.95 4.03 17 5.05 18 6.5 18H9V20M12 13Z" /> </svg> Send to device',gurl.value.length>0&&gId("sSg").setAttribute("fill",accentColor)
</script> </body> </body></html>