Quick effect filter.

This commit is contained in:
Blaz Kristan 2022-07-27 00:11:24 +02:00
parent 78aad924c5
commit 1b64747c2b
5 changed files with 1918 additions and 1828 deletions

View File

@ -911,7 +911,7 @@ uint16_t mode_chase_rainbow(void) {
return chase(color, SEGCOLOR(0), SEGCOLOR(1), false); return chase(color, SEGCOLOR(0), SEGCOLOR(1), false);
} }
static const char *_data_FX_MODE_CHASE_RAINBOW PROGMEM = "Chase Rainbow@!,Width;!,!,;0"; static const char *_data_FX_MODE_CHASE_RAINBOW PROGMEM = "Chase Rainbow@!,Width;!,!,;";
/* /*
@ -925,7 +925,7 @@ uint16_t mode_chase_rainbow_white(void) {
return chase(SEGCOLOR(0), color2, color3, false); return chase(SEGCOLOR(0), color2, color3, false);
} }
static const char *_data_FX_MODE_CHASE_RAINBOW_WHITE PROGMEM = "Rainbow Runner@!,Size;Bg,,;!"; static const char *_data_FX_MODE_CHASE_RAINBOW_WHITE PROGMEM = "Rainbow Runner@!,Size;Bg,,;";
/* /*
@ -1066,7 +1066,7 @@ uint16_t mode_chase_flash_random(void) {
} }
return delay; return delay;
} }
static const char *_data_FX_MODE_CHASE_FLASH_RANDOM PROGMEM = "Chase Flash Rnd@!,;,Fx,;!"; static const char *_data_FX_MODE_CHASE_FLASH_RANDOM PROGMEM = "Chase Flash Rnd@!,;,Fx,;0";
/* /*
@ -2022,7 +2022,7 @@ uint16_t mode_fire_2012()
} }
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012@Cooling=120,Spark rate=64;1,2,3;!=35"; static const char *_data_FX_MODE_FIRE_2012 PROGMEM = "Fire 2012 1D/2D@Cooling=120,Spark rate=64;1,2,3;!=35";
// ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb // ColorWavesWithPalettes by Mark Kriegsman: https://gist.github.com/kriegsman/8281905786e8b2632aeb
@ -4199,7 +4199,7 @@ uint16_t mode_blends(void) {
return FRAMETIME; return FRAMETIME;
} }
static const char *_data_FX_MODE_BLENDS PROGMEM = "Blends@Shift speed,Blend speed;1,2,3,!"; static const char *_data_FX_MODE_BLENDS PROGMEM = "Blends@Shift speed,Blend speed;1,2,3;!";
/* /*

View File

@ -193,7 +193,7 @@ button {
position: absolute; position: absolute;
top: 8px; top: 8px;
left: 12px; left: 12px;
pointer-events: none; /*pointer-events: none;*/
width: 24px; width: 24px;
height: 24px; height: 24px;
} }
@ -369,7 +369,7 @@ button {
#sliders { #sliders {
width: 300px; width: 300px;
margin: 32px auto 0; margin: 0 auto;
position: sticky; position: sticky;
bottom: 0; bottom: 0;
} }
@ -380,14 +380,26 @@ button {
} }
.slider { .slider {
background: var(--c-2); background-color: var(--c-2);
max-width: 300px; max-width: 300px;
min-width: 280px; min-width: 280px;
margin: 0 auto; /* add 5px; if you want some vertical space but looks ugly */ margin: 0 auto; /* add 5px; if you want some vertical space but looks ugly */
border-radius: 15px; border-radius: 24px;
position: relative; position: relative;
} }
.filter {
background-color: var(--c-4);
border-radius: 26px;
height: 26px;
margin: 0 auto; /* 8px if you want space */
padding: 8px;
position: relative;
width: 260px;
/*transition: opacity 1s;*/
/*opacity: 1;*/
}
/* Tooltip text */ /* Tooltip text */
.slider .tooltiptext { .slider .tooltiptext {
visibility: hidden; visibility: hidden;
@ -447,6 +459,10 @@ button {
.hide { .hide {
display: none !important; display: none !important;
} }
.fade {
visibility: hidden;
opacity: 0;
}
.first { .first {
margin-top: 10px; margin-top: 10px;
@ -1186,6 +1202,17 @@ TD .checkmark, TD .radiomark {
left: 9px; left: 9px;
} }
.filter .fchkl {
display: inline-block;
min-width: 1em;
padding: 4px 4px 4px 32px;
text-align: left;
line-height: 24px;
vertical-align: middle;
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
.lbl-s { .lbl-s {
display: inline-block; display: inline-block;
/* margin: 10px 4px 0 0; */ /* margin: 10px 4px 0 0; */
@ -1279,6 +1306,9 @@ TD .checkmark, TD .radiomark {
/* list item name (for sorting) */ /* list item name (for sorting) */
.lstIname { .lstIname {
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis;
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
} }
/* list item palette preview */ /* list item palette preview */
@ -1308,6 +1338,8 @@ TD .checkmark, TD .radiomark {
border-radius: 21px; border-radius: 21px;
background: var(--c-2); background: var(--c-2);
border: 1px solid var(--c-3); border: 1px solid var(--c-3);
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
} }
.fnd input[type="text"]:focus { .fnd input[type="text"]:focus {

View File

@ -202,7 +202,7 @@
<div class="staytop fnd" id="fxFind"> <div class="staytop fnd" id="fxFind">
<input type="text" placeholder="Search" oninput="search(this,'fxlist')" onfocus="search(this,'fxlist')" /> <input type="text" placeholder="Search" oninput="search(this,'fxlist')" onfocus="search(this,'fxlist')" />
<i class="icons clear-icon" onclick="clean(this);">&#xe38f;</i> <i class="icons clear-icon" onclick="clean(this);">&#xe38f;</i>
<i class="icons search-icon">&#xe0a1;</i> <i class="icons search-icon" onclick="gId('filters').classList.toggle('hide');" style="cursor:pointer;">&#xe0a1;</i>
</div> </div>
<div id="fxlist" class="list"> <div id="fxlist" class="list">
<div class="lstI"> <div class="lstI">
@ -217,6 +217,24 @@
</div> </div>
</div> </div>
<div id="sliders"> <div id="sliders">
<div id="filters" class="filter">
<label class="check fchkl">&#127912;
<input type="checkbox" id="filterPal" data-flt="&#127912;" onchange="filterFx(this)">
<span class="checkmark"></span>
</label>
<label class="check fchkl">2D<!-- &#8862; -->
<input type="checkbox" id="filter2D" data-flt="2D" onchange="filterFx(this)">
<span class="checkmark"></span>
</label>
<label class="check fchkl">&#9834;
<input type="checkbox" id="filterVol" data-flt="&#9834;" onchange="filterFx(this)">
<span class="checkmark"></span>
</label>
<label class="check fchkl">&#9835;
<input type="checkbox" id="filterFreq" data-flt="&#9835;" onchange="filterFx(this)">
<span class="checkmark"></span>
</label>
</div>
<div id="slider0" class="slider"> <div id="slider0" class="slider">
<i class="icons slider-icon" style="cursor: pointer;" onclick="tglFreeze()">&#xe325;</i> <i class="icons slider-icon" style="cursor: pointer;" onclick="tglFreeze()">&#xe325;</i>
<div class="sliderwrap il"> <div class="sliderwrap il">

View File

@ -690,12 +690,12 @@ function populateSegments(s)
<div class="sliderdisplay"></div> <div class="sliderdisplay"></div>
</div> </div>
</div>`; </div>`;
let rvXck = `<label class="check revchkl">Reverse ${isM?'':'direction'}<input type="checkbox" id="seg${i}rev" onchange="setRev(${i})" ${inst.rev?"checked":""}><span class="checkmark schk"></span></label>`; let rvXck = `<label class="check revchkl">Reverse ${isM?'':'direction'}<input type="checkbox" id="seg${i}rev" onchange="setRev(${i})" ${inst.rev?"checked":""}><span class="checkmark"></span></label>`;
let miXck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mi" onchange="setMi(${i})" ${inst.mi?"checked":""}><span class="checkmark schk"></span></label>`; let miXck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mi" onchange="setMi(${i})" ${inst.mi?"checked":""}><span class="checkmark"></span></label>`;
let rvYck = "", miYck =""; let rvYck = "", miYck ="";
if (isM) { if (isM) {
rvYck = `<label class="check revchkl">Reverse<input type="checkbox" id="seg${i}rY" onchange="setRevY(${i})" ${inst.rY?"checked":""}><span class="checkmark schk"></span></label>`; rvYck = `<label class="check revchkl">Reverse<input type="checkbox" id="seg${i}rY" onchange="setRevY(${i})" ${inst.rY?"checked":""}><span class="checkmark"></span></label>`;
miYck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mY" onchange="setMiY(${i})" ${inst.mY?"checked":""}><span class="checkmark schk"></span></label>`; miYck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mY" onchange="setMiY(${i})" ${inst.mY?"checked":""}><span class="checkmark"></span></label>`;
} }
let map2D = `<div id="seg${i}map2D" data-map="map2D" class="lbl-s hide">Expand 1D FX<br> let map2D = `<div id="seg${i}map2D" data-map="map2D" class="lbl-s hide">Expand 1D FX<br>
<div class="sel-p"><select class="sel-p" id="seg${i}mp12" onchange="setMp12(${i})"> <div class="sel-p"><select class="sel-p" id="seg${i}mp12" onchange="setMp12(${i})">
@ -716,7 +716,7 @@ function populateSegments(s)
cn += `<div class="seg lstI ${i==s.mainseg ? 'selected' : ''} ${exp ? "expanded":""}" id="seg${i}"> cn += `<div class="seg lstI ${i==s.mainseg ? 'selected' : ''} ${exp ? "expanded":""}" id="seg${i}">
<label class="check schkl"> <label class="check schkl">
<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}> <input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
<i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});">&#x${inst.frz ? (li.live && li.liveseg==i?'e410':'e0e8') : 'e325'};</i> <i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});">&#x${inst.frz ? (li.live && li.liveseg==i?'e410':'e0e8') : 'e325'};</i>
<div class="segname" onclick="selSegEx(${i})"> <div class="segname" onclick="selSegEx(${i})">
@ -762,7 +762,7 @@ function populateSegments(s)
<label class="check revchkl"> <label class="check revchkl">
${isM?'Transpose':'Mirror effect'} ${isM?'Transpose':'Mirror effect'}
<input type="checkbox" id="seg${i}${isM?'tp':'mi'}" onchange="${(isM?'setTp(':'setMi(')+i})" ${isM?(inst.tp?"checked":""):(inst.mi?"checked":"")}> <input type="checkbox" id="seg${i}${isM?'tp':'mi'}" onchange="${(isM?'setTp(':'setMi(')+i})" ${isM?(inst.tp?"checked":""):(inst.mi?"checked":"")}>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
<div class="del"> <div class="del">
<button class="btn btn-xs" id="segr${i}" title="Repeat until end" onclick="rptSeg(${i})"><i class="icons btn-icon">&#xe22d;</i></button> <button class="btn btn-xs" id="segr${i}" title="Repeat until end" onclick="rptSeg(${i})"><i class="icons btn-icon">&#xe22d;</i></button>
@ -808,16 +808,17 @@ function populateEffects()
for (let i = 0; i < effects.length; i++) { for (let i = 0; i < effects.length; i++) {
// WLEDSR: add slider and color control to setX (used by requestjson) // WLEDSR: add slider and color control to setX (used by requestjson)
if (effects[i].name.indexOf("Reserved") < 0) {
let id = effects[i].id; let id = effects[i].id;
html += generateListItemHtml( let nm = effects[i].name;
'fx', let fd = "";
id, if (Array.isArray(fxdata) && fxdata.length>id) {
effects[i].name, fd = fxdata[id].substr(1);
'setX', var eP = (fd == '')?[]:fd.split(";");
'', var p = (eP.length<3 || eP[2]==='')?[]:eP[2].split(",");
!(Array.isArray(fxdata) && fxdata.length>id) ? '' : fxdata[id].substr(1) if (p.length>0 && p[0].substr(0,1) === "!") nm += " 🎨";
); }
if (effects[i].name.indexOf("Reserved") < 0) {
html += generateListItemHtml('fx',id,nm,'setX','',fd);
} }
} }
@ -918,7 +919,7 @@ function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', e
return `<div class="lstI${id==0?' sticky':''}" data-id="${id}" data-opt="${effectPar}" onClick="${clickAction}(${id})"> return `<div class="lstI${id==0?' sticky':''}" data-id="${id}" data-opt="${effectPar}" onClick="${clickAction}(${id})">
<label class="radio schkl" onclick="event.preventDefault()"> <label class="radio schkl" onclick="event.preventDefault()">
<input type="radio" value="${id}" name="${listName}"> <input type="radio" value="${id}" name="${listName}">
<span class="radiomark schk"></span> <span class="radiomark"></span>
<div class="lstIcontent"> <div class="lstIcontent">
<span class="lstIname"> <span class="lstIname">
${name} ${name}
@ -997,7 +998,7 @@ function updateTrail(e)
var max = e.hasAttribute('max') ? e.attributes.max.value : 255; var max = e.hasAttribute('max') ? e.attributes.max.value : 255;
var perc = Math.round(e.value * 100 / max); var perc = Math.round(e.value * 100 / max);
if (perc < 50) perc += 2; if (perc < 50) perc += 2;
var val = `linear-gradient(90deg, var(--bg) ${perc}%, var(--c-4) ${perc}%)`; var val = `linear-gradient(90deg, var(--bg) ${perc}%, var(--c-6) ${perc}%)`;
sd.style.backgroundImage = val; sd.style.backgroundImage = val;
} }
var b = e.parentNode.parentNode.getElementsByTagName('output')[0]; var b = e.parentNode.parentNode.getElementsByTagName('output')[0];
@ -1355,7 +1356,7 @@ function setEffectParameters(idx)
// set the bottom position of selected effect (sticky) as the top of sliders div // set the bottom position of selected effect (sticky) as the top of sliders div
let top = parseInt(getComputedStyle(gId("sliders")).height); let top = parseInt(getComputedStyle(gId("sliders")).height);
top += 28; // size of tooltip //top += 5; // size of tooltip
let sel = d.querySelector('#fxlist .selected'); let sel = d.querySelector('#fxlist .selected');
if (sel) sel.style.bottom = top + "px"; // we will need to remove this when unselected (in setX()) if (sel) sel.style.bottom = top + "px"; // we will need to remove this when unselected (in setX())
@ -1597,7 +1598,7 @@ function resetUtil()
{ {
// gId('segutil').innerHTML = '<button class="btn btn-s" onclick="makeSeg()"><i class="icons btn-icon">&#xe18a;</i>segment</button>'; // gId('segutil').innerHTML = '<button class="btn btn-s" onclick="makeSeg()"><i class="icons btn-icon">&#xe18a;</i>segment</button>';
gId('segutil').innerHTML = '<div class="seg btn btn-s" style="border-radius:24px;padding:0;">' gId('segutil').innerHTML = '<div class="seg btn btn-s" style="border-radius:24px;padding:0;">'
+ '<label class="check schkl"><input type="checkbox" id="selall" onchange="selSegAll(this)"><span class="checkmark schk"></span></label>' + '<label class="check schkl"><input type="checkbox" id="selall" onchange="selSegAll(this)"><span class="checkmark"></span></label>'
+ '<div class="segname" onclick="makeSeg()"><i class="icons btn-icon">&#xe18a;</i>segment</div></div>'; + '<div class="segname" onclick="makeSeg()"><i class="icons btn-icon">&#xe18a;</i>segment</div></div>';
} }
@ -1694,11 +1695,11 @@ function makeP(i,pl) {
content = content =
`<div id="ple${i}" style="margin-top:10px;"></div><label class="check revchkl">Shuffle `<div id="ple${i}" style="margin-top:10px;"></div><label class="check revchkl">Shuffle
<input type="checkbox" id="pl${i}rtgl" onchange="plR(${i})" ${plJson[i].r||rep<0?"checked":""}> <input type="checkbox" id="pl${i}rtgl" onchange="plR(${i})" ${plJson[i].r||rep<0?"checked":""}>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
<label class="check revchkl">Repeat indefinitely <label class="check revchkl">Repeat indefinitely
<input type="checkbox" id="pl${i}rptgl" onchange="plR(${i})" ${rep>0?"":"checked"}> <input type="checkbox" id="pl${i}rptgl" onchange="plR(${i})" ${rep>0?"":"checked"}>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
<div id="pl${i}o1" style="display:${rep>0?"block":"none"}"> <div id="pl${i}o1" style="display:${rep>0?"block":"none"}">
<div class="c">Repeat <input class="noslide" type="number" id="pl${i}rp" oninput="plR(${i})" max=127 min=0 value=${rep>0?rep:1}> times</div> <div class="c">Repeat <input class="noslide" type="number" id="pl${i}rp" oninput="plR(${i})" max=127 min=0 value=${rep>0?rep:1}> times</div>
@ -1717,21 +1718,21 @@ ${makePlSel(plJson[i].end?plJson[i].end:0, true)}
Include brightness Include brightness
</span> </span>
<input type="checkbox" id="p${i}ibtgl" checked> <input type="checkbox" id="p${i}ibtgl" checked>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
<label class="check revchkl"> <label class="check revchkl">
<span class="lstIname"> <span class="lstIname">
Save segment bounds Save segment bounds
</span> </span>
<input type="checkbox" id="p${i}sbtgl" checked> <input type="checkbox" id="p${i}sbtgl" checked>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
<label class="check revchkl"> <label class="check revchkl">
<span class="lstIname"> <span class="lstIname">
Checked segments only Checked segments only
</span> </span>
<input type="checkbox" id="p${i}sbchk"> <input type="checkbox" id="p${i}sbchk">
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label>`; </label>`;
if (Array.isArray(lastinfo.maps) && lastinfo.maps.length>0) { if (Array.isArray(lastinfo.maps) && lastinfo.maps.length>0) {
content += `<div class="sel">Ledmap:&nbsp;<select class="sel-p" id="p${i}lmp"><option value="">None</option>`; content += `<div class="sel">Ledmap:&nbsp;<select class="sel-p" id="p${i}lmp"><option value="">None</option>`;
@ -1749,7 +1750,7 @@ ${makePlSel(plJson[i].end?plJson[i].end:0, true)}
${pl?"Show playlist editor":(i>0)?"Overwrite with state":"Use current state"} ${pl?"Show playlist editor":(i>0)?"Overwrite with state":"Use current state"}
</span> </span>
<input type="checkbox" id="p${i}cstgl" onchange="tglCs(${i})" ${(i==0||pl)?"checked":""}> <input type="checkbox" id="p${i}cstgl" onchange="tglCs(${i})" ${(i==0||pl)?"checked":""}>
<span class="checkmark schk"></span> <span class="checkmark"></span>
</label> </label>
</div> </div>
<div class="po2" id="p${i}o2"> <div class="po2" id="p${i}o2">
@ -2477,6 +2478,19 @@ function clean(c)
i.value=''; i.value='';
i.focus(); i.focus();
i.dispatchEvent(new Event('input')); i.dispatchEvent(new Event('input'));
if (i.parentElement.id=='fxFind') {
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e)=>{e.checked=false;});
}
}
function filterFx(o)
{
if (!o) return;
let i = gId('fxFind').children[0];
i.value=!o.checked?'':o.dataset.flt;
i.focus();
i.dispatchEvent(new Event('input'));
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e)=>{if(e!==o)e.checked=false;});
} }
// make sure "dur" and "transition" are arrays with at least the length of "ps" // make sure "dur" and "transition" are arrays with at least the length of "ps"

File diff suppressed because it is too large Load Diff