234 lines
26 KiB
HTML
234 lines
26 KiB
HTML
<!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>Led Matrix Pixel Art Converter</title>
|
|
<style>
|
|
h1,h2{line-height:.5;margin:1px 0}h1,h2,h3{margin:1px 0}#fieldTable,#scaleTable,p{color:#777;font-family:Arcade,Arial,sans-serif}#drop-zone,.container{text-align:center;padding:20px}#drop-zone,#fieldTable,#scaleTable,body,h1,h2,h3,p{font-family:Arcade,Arial,sans-serif}.rangeNumber,.svg-icon{vertical-align:middle}a:active,a:link,a:visited,h2,h3{color:rgba(126,76,128,.61)}a:hover,h1{color:#7e4c80}a:active,a:hover,a:link,a:visited{background-color:transparent;text-decoration:none}.box{border:2px solid #fff}body{background-color:#151515}.top-part{width:600px;margin:0 auto}.container{max-width:100% -40px;border-radius:0}h1{font-size:2.3em}h2{font-size:1.1em;text-align:center}h3{font-size:.7em;line-height:1.4;text-align:center;align-items:center;justify-content:center;display:flex}p{font-size:1.2em;line-height:1.5}#fieldTable,#scaleTable{font-size:1 em;line-height:1}#drop-zone{display:block;width:100%-40px;border:3px dashed #7e4c80;border-radius:0;margin:0;cursor:pointer;font-size:15px;color:#777}* select,.fullTextField[type=text]{background-color:#333;border:1px solid silver;width:100%;color:#777;font-size:15px}#file-picker,.hide{display:none}* select{margin-top:.5em;margin-bottom:.5em;padding:0;height:27px;border-radius:0}* input[type=range]{-webkit-appearance:none;flex-grow:1;border-radius:0;background:linear-gradient(to right,#333 0,#333 100%);color:silver;border:1px solid silver;margin-top:.5em;margin-left:0}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:25px;height:25px;background:#7e4c80;position:relative;z-index:3}.rangeNumber{width:20px}.fullTextField[type=text]{padding-inline-start:5px;margin-top:10px;height:24px;border-radius:0;font-family:Arcade,Arial,sans-serif}* button,* input[type=submit]{background-color:#333;border:1px solid silver;width:100%;font-family:Arcade,Arial,sans-serif}* input[type=submit]{padding:.5em;border-radius:0;font-size:1.3em;color:#777}* button{padding-inline:5px;border-radius:0;font-size:1em;color:#777;display:flex;align-items:center;justify-content:center;cursor:pointer}.sizeInputFields,textarea{background-color:#333;border:1px solid silver;color:#777}textarea{grid-row:1/2;width:100%;height:200px}.grids-class{position:fixed;top:0;left:0;width:100vw;height:100vh;display:grid;grid-template-columns:repeat(auto-fill,20px);grid-template-rows:repeat(auto-fill,20px);grid-gap:0px}.buttondivmid-class,.gap{width:10px}#sizeDiv *,.buttondiv-class,.buttondivmid-class{display:inline-block}.buttondiv-class{flex:1}#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}#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}.sizeInputFields{width:50px;padding-inline-start:5px;margin-top:-5px;height:24px;border-radius:0;font-family:Arcade,Arial,sans-serif;font-size:15px}
|
|
</style>
|
|
</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" id="logomatrix" viewBox="0 0 24 24">
|
|
<path fill="#7e4c80" d="M6,5
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc1"/>
|
|
<path fill="#7e4c80" d="M12,5
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc2"/>
|
|
<path fill="#7e4c80" d="M18,5
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc3"/>
|
|
<path fill="#7e4c80" d="M6,11
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc4"/>
|
|
<path fill="#7e4c80" d="M12,11
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc5"/>
|
|
<path fill="#7e4c80" d="M18,11
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc6"/>
|
|
<path fill="#7e4c80" d="M6,17
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc7"/>
|
|
<path fill="#7e4c80" d="M12,17
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc8"/>
|
|
<path fill="#7e4c80" d="M18,17
|
|
a2,2 0 1,0 4,0
|
|
a2,2 0 1,0 -4,0" id="sc9"/>
|
|
</svg>
|
|
|
|
Led Matrix 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 style="vertical-align: middle;">
|
|
<select id="ledSetupSelector">
|
|
<option value="matrix" 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 style="vertical-align: middle;">
|
|
<select id="formatSelector">
|
|
<option value="wled" 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 style="vertical-align: middle;">
|
|
<select id="colorFormatSelector">
|
|
<option value="hex" 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 style="vertical-align: middle;">
|
|
<select id="addressingSelector">
|
|
<option value="hybrid" 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="255">
|
|
<span id="brightnessValue">255</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 style="vertical-align: middle;">
|
|
<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 style="vertical-align: middle;">
|
|
<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 style="vertical-align: middle;">
|
|
<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 style="vertical-align: middle;">
|
|
<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 style="vertical-align: middle;">
|
|
<select id="targetSegment">
|
|
</select>
|
|
</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 id="scaleToggle" style="width:36px;height:36px" viewBox="0 0 24 24" onclick="switchScale()">
|
|
<path id="scaleTogglePath" fill="currentColor" d="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" />
|
|
</svg>
|
|
|
|
<svg id="scaleSvg" style="width:36px;height:36px" viewBox="0 0 24 24" onclick="switchScale()">
|
|
<path id="scalePath" fill="currentColor" d="M21,15H23V17H21V15M21,11H23V13H21V11M23,19H21V21C22,21 23,20 23,19M13,3H15V5H13V3M21,7H23V9H21V7M21,3V5H23C23,4 22,3 21,3M1,7H3V9H1V7M17,3H19V5H17V3M17,19H19V21H17V19M3,3C2,3 1,4 1,5H3V3M9,3H11V5H9V3M5,3H7V5H5V3M1,11V19A2,2 0 0,0 3,21H15V11H1M3,19L5.5,15.79L7.29,17.94L9.79,14.72L13,19H3Z" />
|
|
</svg>
|
|
</div>
|
|
</td>
|
|
<td style="vertical-align: middle;">
|
|
<div id="sizeDiv" style="display: none;">
|
|
<label for="sizeX">X : </label> <input class="sizeInputFields" type="number" id="sizeX" value="0">
|
|
|
|
<label for="sizeY">Y : </label> <input class="sizeInputFields" type="number" id="sizeY" value="0">
|
|
</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;">
|
|
<div style="width: 100%; text-align: center;">
|
|
<img id="preview" style="display: block; margin: 0 auto;">
|
|
<img id="newimage" style="display: block; margin: 0 auto;"><br>
|
|
</div>
|
|
|
|
<div id="submitConvertDiv" style="display: none;">
|
|
<button id="convertbutton" class="buttonclass"></button>
|
|
</div>
|
|
|
|
<div id="raw-image-container" style="display: none">
|
|
<img id="image" src="" alt="RawImage image">
|
|
</div>
|
|
|
|
</p>
|
|
|
|
<div id="image-container" style="display: none;">
|
|
<div id="image-info" style="display: none"></div>
|
|
<textarea id="JSONled"></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 id = "gap2" class="gap"></div>
|
|
<button id="fileJSONledbutton" class="buttonclass"></button>
|
|
</div>
|
|
<div>
|
|
<h3><div id="version">Version 1.0.4</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>
|
|
</div>
|
|
<script>
|
|
var intervalId,curlStart='curl -X POST "http://',curlMid1="/json/state\" -d '",curlEnd='\' -H "Content-Type: application/json"';const haStart="#Uncomment if you don't allready have these defined in your switch section of your configuration.yaml\n#- platform: command_line\n #switches:\n ",haMid1="\n friendly_name: ",haMid2="\n unique_id: ",haMid3="\n command_on: >\n ",haMid4='\n command_off: >\n curl -X POST "http://',haEnd='/json/state" -d \'{"on":false}\' -H "Content-Type: application/json"',haCommandLeading=" ",JSONledStringStart='{"on":true,"bri":',JSONledStringMid1=',"seg":{"id":',JSONledStringMid2=',"i":[',JSONledStringEnd="]}}";var accentColor="#7E4C80",accentTextColor="#777",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";document.getElementById("curlUrl").value=location.host;let devMode=!1;const urlParams=new URLSearchParams(window.location.search);urlParams.has("dev")&&(devMode=!0),devMode?console.log("Developer mode active. Experimental and unstable functions active."):console.log('Developer mode inactive. Append "?dev" to the URL.'),devMode?(document.getElementById("fileJSONledbutton").style.display="buttonclass",document.getElementById("gap2").style.display="gap"):(document.getElementById("fileJSONledbutton").style.display="none",document.getElementById("gap2").style.display="none");let httpArray=[],fileJSON="";async function postPixels(){for(let e of httpArray)try{console.log(e),console.log(e.length);let t=await fetch("http://"+document.getElementById("curlUrl").value+"/json/state",{method:"POST",headers:{"Content-Type":"application/json"},body:e}),l=await t.json();console.log(l)}catch(n){console.error(n)}}document.getElementById("convertbutton").addEventListener("click",function(){let e=document.getElementById("preview").src;if(isValidBase64Gif(e))document.getElementById("image").src=e,getPixelRGBValues(e),document.getElementById("image-container").style.display="block",document.getElementById("button-container").style.display="";else{let t=document.getElementById("image-info");t.innerHTML="<p><b>WARNING!</b> File does not appear to be a valid image</p>",t.style.display="block",document.getElementById("image-container").style.display="none",document.getElementById("JSONled").value="",console.log("The string '"+e+"' is not a valid base64 image.")}}),copyJSONledbutton.addEventListener("click",async()=>{let e=document.getElementById("JSONled");e.select();try{await navigator.clipboard.writeText(e.value)}catch(t){try{await document.execCommand("copy")}catch(l){console.error("Failed to copy text: ",l)}}}),sendJSONledbutton.addEventListener("click",async()=>{"https:"===window.location.protocol?alert("Will only be available when served over http (or WLED is run over https)"):postPixels()}),fileJSONledbutton.addEventListener("click",async()=>{if("https:"===window.location.protocol)alert("Will only be available when served over http (or WLED is run over https)");else{let e;sendAsFile(fileJSON,"TheName.json","http://"+document.getElementById("curlUrl").value+"/upload")}});const dropZone=document.getElementById("drop-zone"),filePicker=document.getElementById("file-picker"),preview=document.getElementById("preview");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");let t=e.dataTransfer.files[0];updatePreview(t)}function filePicked(e){let t=e.target.files[0];updatePreview(t)}function updatePreview(e){let t=new FileReader;t.onload=function(){preview.src=t.result,document.getElementById("submitConvertDiv").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),document.getElementById("brightnessNumber").oninput=function(){document.getElementById("brightnessValue").textContent=this.value},document.getElementById("colorLimitNumber").oninput=function(){document.getElementById("colorLimitValue").textContent=this.value};for(var formatSelector=document.getElementById("formatSelector"),hideableRows=document.querySelectorAll(".ha-hide"),i=0;i<hideableRows.length;i++)hideableRows[i].classList.add("hide");function switchScale(){let e=document.getElementById("scalePath"),t=document.getElementById("scaleTogglePath"),l=e.getAttribute("fill"),n="";l===accentColor?(l=accentTextColor,n=scaleToggleOffd,document.getElementById("sizeDiv").style.display="none"):(l=accentColor,n=scaleToggleOnd,document.getElementById("sizeDiv").style.display=""),e.setAttribute("fill",l),t.setAttribute("fill",l),t.setAttribute("d",n)}function sendAsFile(e,t,l){var n=new Blob([e],{type:"application/json"});console.log(e),console.log(t),console.log(l);var a=new FormData;a.append("file",n,t);var o=new XMLHttpRequest;o.open("POST",l,!0),o.onload=function(){200===o.status?console.log("File uploaded successfully!"):console.log("File upload failed!")},o.send(a)}function generateSegmentOptions(e){var t=document.getElementById("targetSegment");t.innerHTML="";for(var l=0;l<e.length;l++){var n=document.createElement("option");n.value=e[l].value,n.text=e[l].text,t.appendChild(n),0===l&&(n.selected=!0)}}function generateSegmentArray(e){for(var t=[],l=0;l<e;l++)t.push({value:l,text:"Segment index "+l});return t}formatSelector.addEventListener("change",function(){for(var e=0;e<hideableRows.length;e++)hideableRows[e].classList.toggle("hide","ha"!==this.value)});var matrixcircles=document.querySelectorAll("#logomatrix path");function changeColorOfDot(){var e=matrixcircles[Math.floor(Math.random()*matrixcircles.length)],t=e.getAttribute("fill");e.setAttribute("fill","#bb8fbc"),setTimeout(()=>{e.setAttribute("fill",t),clearInterval(intervalId),intervalId=setInterval(changeColorOfDot,randomInterval())},500)}function randomInterval(){return 1e3*(Math.floor(5*Math.random())+1)}intervalId=setInterval(changeColorOfDot,randomInterval());var segmentData=generateSegmentArray(10);function getPixelRGBValues(e){httpArray=[],fileJSON=JSONledStringStart+document.getElementById("brightnessNumber").value+JSONledStringMid1+document.getElementById("targetSegment").value+JSONledStringMid2;let t=document.getElementById("JSONled"),l=document.getElementById("colorLimitNumber").value,n=!1,a=-1,o=document.getElementById("formatSelector");a=o.selectedIndex;let r=o.options[a].value;a=(o=document.getElementById("ledSetupSelector")).selectedIndex;let d=o.options[a].value;a=(o=document.getElementById("colorFormatSelector")).selectedIndex;let s=!0;"dec"==o.options[a].value&&(s=!1),a=(o=document.getElementById("addressingSelector")).selectedIndex;let _=!0;"single"==o.options[a].value?_=!1:"hybrid"==o.options[a].value&&(n=!0);let c="",g="",$="'",u="'";s||($="[",u="]");let m=!1,p="";var y=document.createElement("canvas"),v=y.getContext("2d"),h=new Image;h.src=e,h.onload=function(){let e=document.getElementById("scalePath").getAttribute("fill"),a=document.getElementById("sizeX").value,o=document.getElementById("sizeY").value;(e!=accentColor||a<1||o<1)&&(a=h.width,o=h.height),y.width=a,y.height=o,p="<p>Width: "+a+", Height: "+o+" (make sure this matches your led matrix setup)</p>",v.drawImage(h,0,0,a,o);var f=v.getImageData(0,0,a,o).data,E=[];let I=1;"l2r"==d&&(I=0);for(var B=0;B<f.length;B+=4){var S=f[B],b=f[B+1],A=f[B+2],w=f[B+3];let x=B/4,L=Math.floor(x/a),C=x;if("matrix"==d);else if((L+I)%2==0);else{let O=C-L*a,M=a-1-O;C=L*a+M}E.push([S,b,A,w,C,x,L])}E.sort((e,t)=>e[5]-t[5]);let H=[...E];H.sort((e,t)=>e[4]-t[4]);let N="",T=-1,k=H.length,J=0,V=[];for(let D=0;D<k;D++){let P=H[D],R=P[0],j=P[1],W=P[2],Z=P[3],U="",z=-1;if(_){if(T<0&&(T=D),D<k-1){let F=H[D+1];(F[0]!=R||F[1]!=j||F[2]!=W)&&(z=D+1,U=T==D&&n?""==N?""+D+",":"":T+","+z+",")}else U=T+1==(z=D+1)&&n?""==N?""+D+",":"":T+","+z+","}else""==N&&(N=D),T=D,z=D;if(Z<255&&(m=!0),z>-1){let G=R+","+j+","+W;if(s){let[Q,q,X]=[R,j,W];G=`${[Q,q,X].map(e=>e.toString(16).padStart(2,"0")).join("")}`}fileJSON=(N=N+U+$+G+u)+U+$+G+u,(J+=1)%l==0||D==k-1?(V.push(N),N=""):N+=",",T=-1}}N="";for(let Y=0;Y<V.length;Y++){let K=JSONledStringStart+document.getElementById("brightnessNumber").value+JSONledStringMid1+document.getElementById("targetSegment").value+JSONledStringMid2+V[Y]+"]}}";httpArray.push(K);let ee=curlStart+document.getElementById("curlUrl").value+curlMid1+K+curlEnd;Y>0&&(N+="\n",c+=" && "),N+=K,c+=ee}g="#Uncomment if you don't allready have these defined in your switch section of your configuration.yaml\n#- platform: command_line\n #switches:\n "+document.getElementById("haID").value+"\n friendly_name: "+document.getElementById("haName").value+"\n unique_id: "+document.getElementById("haUID").value+haMid3+c+haMid3+document.getElementById("curlUrl").value+'/json/state" -d \'{"on":false}\' -H "Content-Type: application/json"',"wled"==r?t.value=N:"curl"==r?t.value=c:"ha"==r?t.value=g:t.value="ERROR!/n"+r+" is an unknown format.",fileJSON+="]}}";let et=document.getElementById("image-info"),el=document.getElementById("image-info");m&&(p+="<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>"),et.innerHTML=p,el.style.display="block",drawBoxes(E,a,o)}}function drawBoxes(e,t,l){var n=document.getElementById("pixelCanvas"),a=n.getContext("2d");window.innerHeight<window.innerWidth?n.width=Math.floor(.98*window.innerHeight):n.width=Math.floor(.98*window.innerWidth);let o=Math.floor(n.width/t);n.height=o*l+10;for(let r=0;r<l;r++)for(let d=0;d<t;d++){let s=e[r*t+d],_="rgb("+s[0]+", "+s[1]+", "+s[2]+")";s[0],s[1],s[2];let c=s[4];a.fillStyle=_,a.fillRect(d*o,r*o,o,o),a.strokeStyle="#888888",a.lineWidth=1,a.strokeRect(d*o,r*o,o,o),a.font="10px Arial",a.fillStyle="rgb(128,128,128)",a.textAlign="center",a.textBaseline="middle",a.fillText(c+1,d*o+o/2,r*o+o/2)}}function drawBackground(){let e=document.createElement("div");e.id="grid",e.classList.add("grid-class"),e.style.cssText="";let t=Math.ceil(window.innerWidth/20)*Math.ceil(window.innerHeight/20);for(let l=0;l<t;l++){let n=document.createElement("div");n.classList.add("box"),n.style.backgroundColor=getRandomColor(),e.appendChild(n)}e.style.zIndex=-1,document.body.appendChild(e)}function getRandomColor(){let e="rgba(";for(let t=0;t<3;t++)e+=Math.floor(256*Math.random())+",";return e+"0.05)"}generateSegmentOptions(segmentData),document.getElementById("fileJSONledbutton").innerHTML='<svg style="width:36px;height:36px" viewBox="0 0 24 24"><path fill="currentColor" d="M20 18H4V8H20M20 6H12L10 4H4A2 2 0 0 0 2 6V18A2 2 0 0 0 4 20H20A2 2 0 0 0 22 18V8A2 2 0 0 0 20 6M16 17H14V13H11L15 9L19 13H16Z" /></svg> File to device',document.getElementById("convertbutton").innerHTML='<svg style="width:36px;height:36px" 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> Convert to WLED JSON ',document.getElementById("copyJSONledbutton").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',document.getElementById("sendJSONledbutton").innerHTML='<svg class="svg-icon" style="width:36px;height:36px" viewBox="0 0 24 24"> <path 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',window.drawBackground=drawBackground;
|
|
</script>
|
|
</body>
|
|
</html>
|