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

View File

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

View File

@ -7,10 +7,47 @@
<meta content="yes" name="apple-mobile-web-app-capable">
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
<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">
</head>
<body onload="onLoad()">
<body>
<div id="cv" class="overlay">Loading WLED UI...</div>
<noscript><div class="overlay" style="opacity:1;">Sorry, WLED UI needs JavaScript!</div></noscript>
@ -62,40 +99,54 @@
</div>
<div id="picker" class="center"></div>
<div id="rgbwrap" class="center">
<div id="rwrap" class="il">
<div id="Colors">
<div id="vwrap">
<!--p class="labels hd">Value</p-->
<div class="sliderwrap il">
<input id="sliderR" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
<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>
</div><br>
<div id="gwrap" class="il">
<div class="sliderwrap il">
<input id="sliderG" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div><br>
<div id="bwrap" class="il">
<div class="sliderwrap il">
<input id="sliderB" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div><br>
</div>
<div id="wwrap" class="center">
<p class="label hd">White channel</p>
<div class="sliderwrap il">
<input id="sliderW" onchange="setColor(0)" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div><br>
</div>
</div>
<div id="wbal">
<p class="labels hd">White balance</p>
<div class="sliderwrap il">
<input id="sliderA" onchange="setBalance(this.value)" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></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="rwrap" class="il">
<div class="sliderwrap il">
<input id="sliderR" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div><br>
<div id="gwrap" class="il">
<div class="sliderwrap il">
<input id="sliderG" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div><br>
<div id="bwrap" class="il">
<div class="sliderwrap il">
<input id="sliderB" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div><br>
</div>
<div id="wwrap" class="center">
<p class="label hd">White channel</p>
<div class="sliderwrap il">
<input id="sliderW" onchange="setColor(0)" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div>
<div id="wbal">
<p class="labels hd">White balance</p>
<div class="sliderwrap il">
<input id="sliderA" onchange="setBalance(this.value)" max="255" min="0" type="range" value="128" />
<div class="sliderdisplay"></div>
</div>
</div>
</div>

View File

@ -11,16 +11,15 @@ var csel = 0;
var currentPreset = -1;
var lastUpdate = 0;
var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
var lastw = 0;
var tr = 7;
var d = document;
const ranges = RangeTouch.setup('input[type="range"]', {});
var palettesData;
var fxdata = [];
var pJson = {}, eJson = {}, lJson = {};
var pN = "", pI = 0, pNum = 0;
var pmt = 1, pmtLS = 0, pmtLast = 0;
var lastinfo = {};
var ws;
var ws, cpick, ranges;
var cfg = {
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}
@ -33,30 +32,6 @@ var hol = [
[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 sCol(na, col) {d.documentElement.style.setProperty(na, col);}
function gId(c) {return d.getElementById(c);}
@ -237,13 +212,12 @@ async function onLoad()
loadPalettes(()=>{
loadPalettesData(redrawPalPrev);
loadFX(()=>{
loadFXData();
loadPresets(()=>{
//if (isObj(lastinfo) && isEmpty(lastinfo)) loadInfo(requestJson); // if not filled by WS
requestJson();
});
});
});
//updateUI(true);
d.addEventListener("visibilitychange", handleVisibilityChange, false);
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 = [];
function populateQL()
{
@ -500,7 +502,6 @@ function loadInfo(callback=null)
clearErrorToast();
lastinfo = json;
parseInfo();
showNodes();
if (isInfo) populateInfo(json);
updateUI();
reqsLegal = true;
@ -666,20 +667,27 @@ function populateEffects()
effects.sort((a,b) => (a.name).localeCompare(b.name));
effects.unshift({
"id": 0,
"name": "Solid",
"name": "Solid@;!;0"
});
for (let i = 0; i < effects.length; i++) {
var posAt = effects[i].name.indexOf("@");
var extra = '';
if (posAt > 0)
extra = effects[i].name.substr(posAt);
else
posAt = 999;
html += generateListItemHtml(
effects[i].id,
effects[i].name.substr(0,posAt),
'setEffect'
);
// 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 extra = '';
if (posAt > 0)
extra = effects[i].name.substr(posAt);
else
posAt = 999;
html += generateListItemHtml(
'fx',
effects[i].id,
effects[i].name.substr(0,posAt),
'setEffect',
'','',
extra
);
}
}
gId('fxlist').innerHTML=html;
}
@ -702,11 +710,12 @@ function populatePalettes()
var html = "";
for (let i = 0; i < palettes.length; i++) {
html += generateListItemHtml(
palettes[i].id,
palettes[i].name,
'setPalette',
'palette',
palettes[i].id,
palettes[i].name,
'setPalette',
`<div class="lstIprev"></div>`
);
);
}
gId('pallist').innerHTML=html;
}
@ -779,9 +788,16 @@ function generateOptionItemHtml(id, name)
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)
@ -832,7 +848,9 @@ function updateUI()
sel = 0;
if (eJson && eJson.length) {
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'));
@ -843,7 +861,7 @@ function updateUI()
updatePA(true);
redrawPalPrev();
updateRgb();
updatePSliders();
var l = cfg.comp.labels; //l = false;
var e = d.querySelectorAll('.label');
@ -874,7 +892,6 @@ function makeWS() {
if (i) {
lastinfo = i;
parseInfo();
showNodes();
if (isInfo) populateInfo(i);
} else
i = lastinfo;
@ -981,11 +998,6 @@ function requestJson(command=null)
if (command) {
if (useWs || !command.ps) command.v = true; // force complete /json/si API response
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);
if (req.length > 1000) useWs = false; //do not send very long requests over websocket
};
@ -1124,7 +1136,7 @@ function setSegBri(s)
requestJson(obj);
}
function setEffect(ind = null)
function setEffect(ind = 0)
{
tglFxDropdown();
var obj = {"seg": {"fx": parseInt(ind)}};
@ -1181,7 +1193,7 @@ function selectSlot(b)
cpick.color.set(cd[csel].style.backgroundColor);
gId('sliderW').value = whites[csel];
redrawPalPrev();
updateRgb();
updatePSliders();
}
var lasth = 0;
@ -1199,12 +1211,45 @@ function pC(col)
setColor(0);
}
function updateRgb()
{
function updatePSliders() {
//update RGB sliders
var col = cpick.color.rgb;
gId('sliderR').value = col.r;
gId('sliderG').value = col.g;
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()
@ -1390,7 +1435,6 @@ function move(e)
function size()
{
w = window.innerWidth;
var h = gId('top').clientHeight;
sCol('--th', h + "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