Simple UI update.

This commit is contained in:
Blaz Kristan 2022-01-03 22:37:21 +01:00
parent b6059939b4
commit 816823b115
6 changed files with 2260 additions and 2156 deletions

View File

@ -15,7 +15,7 @@ var csel = 0;
var currentPreset = -1, prevPS = -1; var currentPreset = -1, prevPS = -1;
var lastUpdate = 0; var lastUpdate = 0;
var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0; var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
var pcMode = false, pcModeA = false, lastw = 0; var pcMode = false, pcModeA = false, lastw = 0, wW;
var tr = 7; var tr = 7;
var d = document; var d = document;
var palettesData; var palettesData;
@ -2340,7 +2340,7 @@ function showNodes() {
function size() function size()
{ {
w = window.innerWidth; wW = window.innerWidth;
showNodes(); showNodes();
var h = gId('top').clientHeight; var h = gId('top').clientHeight;
sCol('--th', h + "px"); sCol('--th', h + "px");
@ -2357,8 +2357,8 @@ function togglePcMode(fromB = false)
localStorage.setItem('pcm', pcModeA); localStorage.setItem('pcm', pcModeA);
pcMode = pcModeA; pcMode = pcModeA;
} }
if (w < 1250 && !pcMode) return; if (wW < 1250 && !pcMode) return;
if (!fromB && ((w < 1250 && lastw < 1250) || (w >= 1250 && lastw >= 1250))) return; if (!fromB && ((wW < 1250 && lastw < 1250) || (wW >= 1250 && lastw >= 1250))) return;
openTab(0, true); openTab(0, true);
if (w < 1250) {pcMode = false;} if (w < 1250) {pcMode = false;}
else if (pcModeA && !fromB) pcMode = pcModeA; else if (pcModeA && !fromB) pcMode = pcModeA;
@ -2367,7 +2367,7 @@ function togglePcMode(fromB = false)
gId('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto"; gId('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto";
sCol('--bh', gId('bot').clientHeight + "px"); sCol('--bh', gId('bot').clientHeight + "px");
_C.style.width = (pcMode)?'100%':'400%'; _C.style.width = (pcMode)?'100%':'400%';
lastw = w; lastw = wW;
} }
function mergeDeep(target, ...sources) function mergeDeep(target, ...sources)

View File

@ -381,11 +381,7 @@ img {
width: 225px; width: 225px;
position: relative; position: relative;
} }
#rwrap .sliderwrap, #Colors .sliderwrap {
#gwrap .sliderwrap,
#bwrap .sliderwrap,
#wwrap .sliderwrap,
#wbal .sliderwrap {
width: 260px; width: 260px;
margin: 10px 0 0; margin: 10px 0 0;
} }
@ -400,11 +396,7 @@ img {
pointer-events: none; pointer-events: none;
z-index: -1; z-index: -1;
} }
#rwrap .sliderdisplay, #Colors .sliderdisplay {
#gwrap .sliderdisplay,
#bwrap .sliderdisplay,
#wwrap .sliderdisplay,
#wbal .sliderdisplay {
height: 28px; height: 28px;
top: 0; bottom: 0; top: 0; bottom: 0;
left: 0; right: 0; left: 0; right: 0;
@ -414,6 +406,7 @@ img {
#gwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #0f0); } #gwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #0f0); }
#bwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #00f); } #bwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #00f); }
#wwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #fff); } #wwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #fff); }
#kwrap .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #cbdbff); }
#wbal .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #d4e0ff); } #wbal .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #d4e0ff); }
.sliderbubble { .sliderbubble {
@ -448,11 +441,7 @@ input[type=range] {
background-color: transparent; background-color: transparent;
cursor: pointer; cursor: pointer;
} }
#rwrap input[type=range], #Colors input[type=range] {
#gwrap input[type=range],
#bwrap input[type=range],
#wwrap input[type=range],
#wbal input[type=range] {
width: 252px; width: 252px;
margin: 0; margin: 0;
} }
@ -484,25 +473,17 @@ input[type=range]::-moz-range-thumb {
background: var(--c-f); background: var(--c-f);
transform: translateY(5px); transform: translateY(5px);
} }
#rwrap input[type=range]::-webkit-slider-thumb, #Colors input[type=range]::-webkit-slider-thumb {
#gwrap input[type=range]::-webkit-slider-thumb,
#bwrap input[type=range]::-webkit-slider-thumb,
#wwrap input[type=range]::-webkit-slider-thumb,
#wbal input[type=range]::-webkit-slider-thumb {
height: 18px; height: 18px;
width: 18px; width: 18px;
border: 2px solid #000; border: 2px solid #000;
margin-top: 5px; margin-top: 5px;
} }
#rwrap input[type=range]::-moz-range-thumb, #Colors input[type=range]::-moz-range-thumb {
#gwrap input[type=range]::-moz-range-thumb,
#bwrap input[type=range]::-moz-range-thumb,
#wwrap input[type=range]::-moz-range-thumb,
#wbal input[type=range]::-moz-range-thumb {
border: 2px solid var(--c-1); border: 2px solid var(--c-1);
} }
#wwrap, #wbal { #kwrap, #wwrap, #wbal {
display: block; display: none;
} }
.hd { .hd {

View File

@ -7,10 +7,47 @@
<meta content="yes" name="apple-mobile-web-app-capable"> <meta content="yes" name="apple-mobile-web-app-capable">
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/> <link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
<title>WLED</title> <title>WLED</title>
<script>function feedback(){}</script> <script>
function feedback(){}
// instead of including [script src="iro.js"][/script] and [script src="rangetouch.js"][/script]
// (which would be inlined by nodeJS inliner during minimization and compression) we need to load them dynamically
// the following is needed to load iro.js and rangetouch.js as consecutive requests to allow ESP8266
// to keep up with requests (if requests happent too fast some may not get processed)
// it will also call onLoad() after last is loaded (it was removed from [body onload="onLoad()"]).
var h = document.getElementsByTagName('head')[0];
var l = document.createElement('script');
l.type = 'application/javascript';
l.src = 'iro.js';
l.addEventListener('load', (e) => {
// after iro is loaded initialize global variable
cpick = new iro.ColorPicker("#picker", {
width: 260,
wheelLightness: false,
wheelAngle: 270,
wheelDirection: "clockwise",
layout: [{
component: iro.ui.Wheel,
options: {}
}]
});
cpick.on("input:end", () => {setColor(1);});
cpick.on("color:change", () => {updatePSliders()});
var l = document.createElement('script');
l.type = 'application/javascript';
l.src = 'rangetouch.js';
l.addEventListener('load', (e) => {
// after rangetouch is loaded initialize global variable
ranges = RangeTouch.setup('input[type="range"]', {});
onLoad(); // start processing UI
});
//h.appendChild(l); // if this fires too quickly for ESP8266 use next line
setTimeout(function(){h.appendChild(l)},50);
});
setTimeout(function(){h.appendChild(l)},50);
</script>
<link rel="stylesheet" href="simple.css"> <link rel="stylesheet" href="simple.css">
</head> </head>
<body onload="onLoad()"> <body>
<div id="cv" class="overlay">Loading WLED UI...</div> <div id="cv" class="overlay">Loading WLED UI...</div>
<noscript><div class="overlay" style="opacity:1;">Sorry, WLED UI needs JavaScript!</div></noscript> <noscript><div class="overlay" style="opacity:1;">Sorry, WLED UI needs JavaScript!</div></noscript>
@ -62,7 +99,21 @@
</div> </div>
<div id="picker" class="center"></div> <div id="picker" class="center"></div>
<div id="Colors">
<div id="vwrap">
<!--p class="labels hd">Value</p-->
<div class="sliderwrap il">
<input id="sliderV" class="noslide" oninput="fromV()" onchange="setColor(0)" max="100" min="0" type="range" value="100" step="any" />
<div class="sliderdisplay"></div>
</div><br>
</div>
<div id="kwrap">
<!--p class="labels hd">Temperature</p-->
<div class="sliderwrap il">
<input id="sliderK" class="noslide" oninput="fromK()" onchange="setColor(0)" max="10091" min="1900" type="range" value="6550" />
<div class="sliderdisplay"></div>
</div>
</div>
<div id="rgbwrap" class="center"> <div id="rgbwrap" class="center">
<div id="rwrap" class="il"> <div id="rwrap" class="il">
<div class="sliderwrap il"> <div class="sliderwrap il">
@ -83,7 +134,6 @@
</div> </div>
</div><br> </div><br>
</div> </div>
<div id="wwrap" class="center"> <div id="wwrap" class="center">
<p class="label hd">White channel</p> <p class="label hd">White channel</p>
<div class="sliderwrap il"> <div class="sliderwrap il">
@ -98,6 +148,7 @@
<div class="sliderdisplay"></div> <div class="sliderdisplay"></div>
</div> </div>
</div> </div>
</div>
<div id="Segments" class="center"> <div id="Segments" class="center">
<div id="segcont"></div> <div id="segcont"></div>

View File

@ -11,16 +11,15 @@ var csel = 0;
var currentPreset = -1; var currentPreset = -1;
var lastUpdate = 0; var lastUpdate = 0;
var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0; var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
var lastw = 0;
var tr = 7; var tr = 7;
var d = document; var d = document;
const ranges = RangeTouch.setup('input[type="range"]', {});
var palettesData; var palettesData;
var fxdata = [];
var pJson = {}, eJson = {}, lJson = {}; var pJson = {}, eJson = {}, lJson = {};
var pN = "", pI = 0, pNum = 0; var pN = "", pI = 0, pNum = 0;
var pmt = 1, pmtLS = 0, pmtLast = 0; var pmt = 1, pmtLS = 0, pmtLast = 0;
var lastinfo = {}; var lastinfo = {};
var ws; var ws, cpick, ranges;
var cfg = { var cfg = {
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true, seglen:false} comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true, seglen:false}
@ -33,30 +32,6 @@ var hol = [
[2024,2,31,2,"https://aircoookie.github.io/easter.png"] [2024,2,31,2,"https://aircoookie.github.io/easter.png"]
]; ];
var cpick = new iro.ColorPicker("#picker", {
width: 260,
wheelLightness: false,
wheelAngle: 90,
layout: [
{
component: iro.ui.Wheel,
options: {}
},
{
component: iro.ui.Slider,
options: { sliderType: 'value' }
}/*,
{
component: iro.ui.Slider,
options: {
sliderType: 'kelvin',
minTemperature: 2100,
maxTemperature: 10000
}
}*/
]
});
function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();} function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();}
function sCol(na, col) {d.documentElement.style.setProperty(na, col);} function sCol(na, col) {d.documentElement.style.setProperty(na, col);}
function gId(c) {return d.getElementById(c);} function gId(c) {return d.getElementById(c);}
@ -237,13 +212,12 @@ async function onLoad()
loadPalettes(()=>{ loadPalettes(()=>{
loadPalettesData(redrawPalPrev); loadPalettesData(redrawPalPrev);
loadFX(()=>{ loadFX(()=>{
loadFXData();
loadPresets(()=>{ loadPresets(()=>{
//if (isObj(lastinfo) && isEmpty(lastinfo)) loadInfo(requestJson); // if not filled by WS
requestJson(); requestJson();
}); });
}); });
}); });
//updateUI(true);
d.addEventListener("visibilitychange", handleVisibilityChange, false); d.addEventListener("visibilitychange", handleVisibilityChange, false);
size(); size();
@ -425,6 +399,34 @@ function loadFX(callback = null)
}); });
} }
function loadFXData(callback = null)
{
var url = (loc?`http://${locip}`:'') + '/json/fxdata';
fetch(url, {
method: 'get'
})
.then(res => {
if (!res.ok) showErrorToast();
return res.json();
})
.then(json => {
clearErrorToast();
fxdata = json||[];
// add default value for Solid
fxdata.shift()
fxdata.unshift("@;!;");
})
.catch(function (error) {
fxdata = [];
showToast(error, true);
})
.finally(()=>{
if (callback) callback();
updateUI();
});
}
var pQL = []; var pQL = [];
function populateQL() function populateQL()
{ {
@ -500,7 +502,6 @@ function loadInfo(callback=null)
clearErrorToast(); clearErrorToast();
lastinfo = json; lastinfo = json;
parseInfo(); parseInfo();
showNodes();
if (isInfo) populateInfo(json); if (isInfo) populateInfo(json);
updateUI(); updateUI();
reqsLegal = true; reqsLegal = true;
@ -666,9 +667,12 @@ function populateEffects()
effects.sort((a,b) => (a.name).localeCompare(b.name)); effects.sort((a,b) => (a.name).localeCompare(b.name));
effects.unshift({ effects.unshift({
"id": 0, "id": 0,
"name": "Solid", "name": "Solid@;!;0"
}); });
for (let i = 0; i < effects.length; i++) { for (let i = 0; i < effects.length; i++) {
// WLEDSR: add slider and color control to setEffect (used by requestjson)
if (effects[i].name.indexOf("Reserved") < 0) {
var posAt = effects[i].name.indexOf("@"); var posAt = effects[i].name.indexOf("@");
var extra = ''; var extra = '';
if (posAt > 0) if (posAt > 0)
@ -676,11 +680,15 @@ function populateEffects()
else else
posAt = 999; posAt = 999;
html += generateListItemHtml( html += generateListItemHtml(
'fx',
effects[i].id, effects[i].id,
effects[i].name.substr(0,posAt), effects[i].name.substr(0,posAt),
'setEffect' 'setEffect',
'','',
extra
); );
} }
}
gId('fxlist').innerHTML=html; gId('fxlist').innerHTML=html;
} }
@ -702,6 +710,7 @@ function populatePalettes()
var html = ""; var html = "";
for (let i = 0; i < palettes.length; i++) { for (let i = 0; i < palettes.length; i++) {
html += generateListItemHtml( html += generateListItemHtml(
'palette',
palettes[i].id, palettes[i].id,
palettes[i].name, palettes[i].name,
'setPalette', 'setPalette',
@ -779,9 +788,16 @@ function generateOptionItemHtml(id, name)
return `<option value="${id}">${name}</option>`; return `<option value="${id}">${name}</option>`;
} }
function generateListItemHtml(id, name, clickAction, extraHtml = '') function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', extraClass = '', extraPar = '')
{ {
return `<div class="lstI c" data-id="${id}" onClick="${clickAction}(${id})"><span class="lstIname">${name}</span>${extraHtml}</div>`; return `<div class="lstI ${extraClass}" data-id="${id}" data-opt="${extraPar}" onClick="${clickAction}(${id})">
<div class="lstIcontent">
<span class="lstIname">
${name}
</span>
</div>
${extraHtml}
</div>`;
} }
function updateTrail(e) function updateTrail(e)
@ -832,7 +848,9 @@ function updateUI()
sel = 0; sel = 0;
if (eJson && eJson.length) { if (eJson && eJson.length) {
for (var i=0; i<eJson.length; i++) if (eJson[i].id == selectedFx) {sel = i; break;} for (var i=0; i<eJson.length; i++) if (eJson[i].id == selectedFx) {sel = i; break;}
gId('fxBtn').innerHTML = '<i class="icons">&#xe0e8;</i> ' + eJson[sel].name; var posAt = eJson[sel].name.indexOf("@");
if (posAt<=0) posAt=999;
gId('fxBtn').innerHTML = '<i class="icons">&#xe0e8;</i> ' + eJson[sel].name.substr(0,posAt);
} }
updateTrail(gId('sliderBri')); updateTrail(gId('sliderBri'));
@ -843,7 +861,7 @@ function updateUI()
updatePA(true); updatePA(true);
redrawPalPrev(); redrawPalPrev();
updateRgb(); updatePSliders();
var l = cfg.comp.labels; //l = false; var l = cfg.comp.labels; //l = false;
var e = d.querySelectorAll('.label'); var e = d.querySelectorAll('.label');
@ -874,7 +892,6 @@ function makeWS() {
if (i) { if (i) {
lastinfo = i; lastinfo = i;
parseInfo(); parseInfo();
showNodes();
if (isInfo) populateInfo(i); if (isInfo) populateInfo(i);
} else } else
i = lastinfo; i = lastinfo;
@ -981,11 +998,6 @@ function requestJson(command=null)
if (command) { if (command) {
if (useWs || !command.ps) command.v = true; // force complete /json/si API response if (useWs || !command.ps) command.v = true; // force complete /json/si API response
command.time = Math.floor(Date.now() / 1000); command.time = Math.floor(Date.now() / 1000);
var t = gId('tt');
if (t.validity.valid && command.transition==null) {
var tn = parseInt(t.value*10);
if (tn != tr) command.transition = tn;
}
req = JSON.stringify(command); req = JSON.stringify(command);
if (req.length > 1000) useWs = false; //do not send very long requests over websocket if (req.length > 1000) useWs = false; //do not send very long requests over websocket
}; };
@ -1124,7 +1136,7 @@ function setSegBri(s)
requestJson(obj); requestJson(obj);
} }
function setEffect(ind = null) function setEffect(ind = 0)
{ {
tglFxDropdown(); tglFxDropdown();
var obj = {"seg": {"fx": parseInt(ind)}}; var obj = {"seg": {"fx": parseInt(ind)}};
@ -1181,7 +1193,7 @@ function selectSlot(b)
cpick.color.set(cd[csel].style.backgroundColor); cpick.color.set(cd[csel].style.backgroundColor);
gId('sliderW').value = whites[csel]; gId('sliderW').value = whites[csel];
redrawPalPrev(); redrawPalPrev();
updateRgb(); updatePSliders();
} }
var lasth = 0; var lasth = 0;
@ -1199,12 +1211,45 @@ function pC(col)
setColor(0); setColor(0);
} }
function updateRgb() function updatePSliders() {
{ //update RGB sliders
var col = cpick.color.rgb; var col = cpick.color.rgb;
gId('sliderR').value = col.r; gId('sliderR').value = col.r;
gId('sliderG').value = col.g; gId('sliderG').value = col.g;
gId('sliderB').value = col.b; gId('sliderB').value = col.b;
//update hex field
var str = cpick.color.hexString.substring(1);
var w = whites[csel];
if (w > 0) str += w.toString(16);
//update value slider
var v = gId('sliderV');
v.value = cpick.color.value;
//background color as if color had full value
var hsv = {"h":cpick.color.hue,"s":cpick.color.saturation,"v":100};
var c = iro.Color.hsvToRgb(hsv);
var cs = 'rgb('+c.r+','+c.g+','+c.b+')';
v.nextElementSibling.style.backgroundImage = `linear-gradient(90deg, #000 0%, ${cs})`;
//update Kelvin slider
gId('sliderK').value = cpick.color.kelvin;
}
function setPicker(rgb) {
var c = new iro.Color(rgb);
if (c.value > 0) cpick.color.set(c);
else cpick.color.setChannel('hsv', 'v', 0);
}
function fromV()
{
cpick.color.setChannel('hsv', 'v', d.getElementById('sliderV').value);
}
function fromK()
{
cpick.color.set({ kelvin: d.getElementById('sliderK').value });
} }
function fromRgb() function fromRgb()
@ -1390,7 +1435,6 @@ function move(e)
function size() function size()
{ {
w = window.innerWidth;
var h = gId('top').clientHeight; var h = gId('top').clientHeight;
sCol('--th', h + "px"); sCol('--th', h + "px");
sCol("--tp", h - (gId(`briwrap`).style.display === "block" ? 0 : gId(`briwrap`).clientTop) + "px"); sCol("--tp", h - (gId(`briwrap`).style.display === "block" ? 0 : gId(`briwrap`).clientTop) + "px");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff