2022-05-08 10:50:48 +02:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=500" >
< meta content = "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name = "viewport" / >
< title > 2D Set-up< / title >
< script >
var d=document;
2023-01-16 22:12:02 +01:00
var loc = false, locip;
2023-01-02 20:56:00 +01:00
var maxPanels=64;
2022-05-08 10:50:48 +02:00
function H(){window.open("https://kno.wled.ge/features/2D");}
function B(){window.open("/settings","_self");}
function gId(n){return d.getElementById(n);}
2022-06-23 17:42:02 +02:00
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
function loadJS(FILE_URL, async = true) {
let scE = d.createElement("script");
scE.setAttribute("src", FILE_URL);
scE.setAttribute("type", "text/javascript");
scE.setAttribute("async", async);
d.body.appendChild(scE);
// success event
scE.addEventListener("load", () => {
//console.log("File loaded");
GetV();
UI();
2023-01-03 17:12:35 +01:00
Sf.MPC.setAttribute("max",maxPanels);
2022-06-23 17:42:02 +02:00
});
// error event
scE.addEventListener("error", (ev) => {
console.log("Error on loading file", ev);
alert("Loading of configuration script failed.\nIncomplete page data!");
});
}
function S() {
2023-01-16 22:12:02 +01:00
if (window.location.protocol == "file:") {
loc = true;
locip = localStorage.getItem('locIp');
if (!locip) {
locip = prompt("File Mode. Please enter WLED IP!");
localStorage.setItem('locIp', locip);
}
}
var url = (loc?`http://${locip}`:'') + '/settings/s.js?p=10';
2022-06-23 17:42:02 +02:00
loadJS(url, false); // If we set async false, file is loaded and executed, then next statement is processed
}
2022-05-08 10:50:48 +02:00
2023-01-03 17:12:35 +01:00
function UI() {
2022-05-08 10:50:48 +02:00
if (gId("somp").value === "0") {
gId("mpdiv").style.display = "none";
resetPanels();
return;
}
2023-01-03 17:12:35 +01:00
gId("mpdiv").style.display = "block";
2022-05-08 10:50:48 +02:00
}
function addPanels() {
2023-01-02 20:56:00 +01:00
let c = parseInt(d.Sf.MPC.value);
2023-01-03 17:12:35 +01:00
let i = gId("panels").children.length;
if (i< c ) for ( let j = i; j < c ; j + + ) addPanel ( j ) ;
if (i>c) for (let j=i; j>c; j--) remPanel();
2022-05-08 10:50:48 +02:00
}
function addPanel(i=0) {
let p = gId("panels");
if (p.children.length >= maxPanels) return;
2023-01-03 17:12:35 +01:00
var pw = parseInt(d.Sf.PW.value);
var ph = parseInt(d.Sf.PH.value);
2023-01-02 20:56:00 +01:00
let b = `< div id = "pnl${i}" > < hr class = "sml" > Panel ${i}< br >
1< sup > st< / sup > LED: < select name = "P${i}B" >
2022-05-08 10:50:48 +02:00
< option value = "0" > Top< / option >
< option value = "1" > Bottom< / option >
< / select > < select name = "P${i}R" >
< option value = "0" > Left< / option >
< option value = "1" > Right< / option >
< / select > < br >
Orientation: < select name = "P${i}V" >
< option value = "0" > Horizontal< / option >
< option value = "1" > Vertical< / option >
< / select > < br >
2023-01-02 20:56:00 +01:00
Serpentine: < input type = "checkbox" name = "P${i}S" > < br >
2023-01-03 17:12:35 +01:00
Dimensions (WxH): < input id = "P${i}W" name = "P${i}W" type = "number" min = "1" max = "128" value = "${pw}" > x < input id = "P${i}H" name = "P${i}H" type = "number" min = "1" max = "128" value = "${ph}" > < br >
2023-01-02 20:56:00 +01:00
Offset X:< input id = "P${i}X" name = "P${i}X" type = "number" min = "0" max = "256" value = "0" >
Y:< input id = "P${i}Y" name = "P${i}Y" type = "number" min = "0" max = "256" value = "0" > < br > < i > (offset from top-left corner in # LEDs)< / i >
< / div > `;
2022-05-08 10:50:48 +02:00
p.insertAdjacentHTML("beforeend", b);
}
2023-01-16 22:12:02 +01:00
function remPanel() {
2022-05-08 10:50:48 +02:00
let p = gId("panels").children;
2023-01-16 22:12:02 +01:00
var i = p.length;
if (i < = 1) return;
p[i-1].remove();
}
2022-05-08 10:50:48 +02:00
function resetPanels() {
2023-01-02 20:56:00 +01:00
d.Sf.MPC.value = 1;
2023-01-03 17:12:35 +01:00
let e = gId("panels").children
for (let i = e.length; i>0; i--) e[i-1].remove();
2022-05-08 10:50:48 +02:00
}
2023-01-03 17:12:35 +01:00
/*
2022-05-08 10:50:48 +02:00
function btnPanel(i) {
gId("pnl_add").style.display = (i< maxPanels ) ? " inline " : " none " ;
gId("pnl_rem").style.display = (i>1) ? "inline":"none";
}
2023-01-03 17:12:35 +01:00
*/
2023-01-02 20:56:00 +01:00
function gen() {
resetPanels();
var pansH = parseInt(d.Sf.MPH.value);
var pansV = parseInt(d.Sf.MPV.value);
var c = pansH*pansV;
d.Sf.MPC.value = c; // number of panels
var ps = d.Sf.PS.checked;
var pv = d.Sf.PV.value==="1";
var pb = d.Sf.PB.value==="1";
var pr = d.Sf.PR.value==="1";
var pw = parseInt(d.Sf.PW.value);
var ph = parseInt(d.Sf.PH.value);
var h = pv ? pansV : pansH;
var v = pv ? pansH : pansV;
for (let j = 0, p = 0; j < v ; j + + ) {
for (let i = 0; i < h ; i + + , p + + ) {
if (j*i < maxPanels ) addPanel ( p ) ;
var y = (pv?pr:pb) ? v-j-1: j;
var x = (pv?pb:pr) ? h-i-1 : i;
x = ps & & j%2 ? h-x-1 : x;
gId("P"+p+"X").value = (pv?y:x) * pw;
gId("P"+p+"Y").value = (pv?x:y) * ph
gId("P"+p+"W").value = pw;
gId("P"+p+"H").value = ph;
}
}
}
2022-05-08 10:50:48 +02:00
< / script >
< style > @ import url ( "style.css" ) ; < / style >
< / head >
< body onload = "S()" >
< form id = "form_s" name = "Sf" method = "post" >
< div class = "toprow" >
< div class = "helpB" > < button type = "button" onclick = "H()" > ?< / button > < / div >
< button type = "button" onclick = "B()" > Back< / button > < button type = "submit" > Save< / button > < hr >
< / div >
< h2 > 2D setup< / h2 >
2023-01-16 22:12:02 +01:00
Strip or panel:
2022-05-08 10:50:48 +02:00
< select id = "somp" name = "SOMP" onchange = "resetPanels();addPanels();UI();" >
< option value = "0" > 1D Strip< / option >
< option value = "1" > 2D Matrix< / option >
< / select > < br >
< div id = "mpdiv" style = "display:none;" >
2023-01-02 20:56:00 +01:00
< hr class = "sml" >
< h3 > Matrix Generator< / h3 >
2022-05-08 10:50:48 +02:00
Panel dimensions (WxH): < input name = "PW" type = "number" min = "1" max = "128" value = "8" > x < input name = "PH" type = "number" min = "1" max = "128" value = "8" > < br >
2023-01-03 17:12:35 +01:00
Horizontal panels: < input name = "MPH" type = "number" min = "1" max = "8" value = "1" >
Vertical panels: < input name = "MPV" type = "number" min = "1" max = "8" value = "1" > < br >
2022-05-08 10:50:48 +02:00
1< sup > st< / sup > panel: < select name = "PB" >
< option value = "0" > Top< / option >
< option value = "1" > Bottom< / option >
< / select > < select name = "PR" >
< option value = "0" > Left< / option >
< option value = "1" > Right< / option >
< / select > < br >
Orientation: < select name = "PV" >
< option value = "0" > Horizontal< / option >
< option value = "1" > Vertical< / option >
< / select > < br >
2023-01-02 20:56:00 +01:00
Serpentine: < input type = "checkbox" name = "PS" > < br >
< i style = "color:#fa0;" > Can populate LED panel layout with pre-arranged matrix.< br > These values do not affect final layout.< / i > < br >
< button type = "button" onclick = "gen()" > Populate< / button >
2022-11-11 20:20:11 +01:00
< hr class = "sml" >
2023-01-02 20:56:00 +01:00
< h3 > Panel set-up< / h3 >
2023-01-03 17:12:35 +01:00
Number of panels: < input name = "MPC" type = "number" min = "1" max = "64" value = "1" oninput = "addPanels()" > < br >
2023-01-02 20:56:00 +01:00
< i > A matrix is made of 1 or more physical LED panels.< br >
<!-- Panels should be arranged from top - left to bottom - right order, starting with lower panel number on the left (or top if transposed).<br> -->
Each panel can be of different size and/or have different LED orientation and/or starting point and/or layout.< / i > < br >
2022-08-09 21:14:37 +02:00
< h3 > LED panel layout< / h3 >
2022-05-08 10:50:48 +02:00
< div id = "panels" >
< / div >
< / div >
< hr >
< button type = "button" onclick = "B()" > Back< / button > < button type = "submit" > Save< / button >
< / form >
< / body >
< / html >