Custom palettes now editable
This commit is contained in:
parent
480e1e17c8
commit
92f9c908f6
@ -102,14 +102,62 @@
|
|||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: 100px;
|
margin-top: 10px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.wrap{
|
||||||
|
width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.palette{
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.paletteGradients{
|
||||||
|
flex: 1;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.palettesMain {
|
||||||
|
margin-top: 50px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#palTop{
|
||||||
|
height: fit-content;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.palGradientParent{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: fit-content;
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
.buttonsDiv{
|
||||||
|
display: inline-flex;
|
||||||
|
margin-left: 5px;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
.sendSpan{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.editSpan{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="wrap" style="max-width: 800px;">
|
<div id="wrap" class="wrap">
|
||||||
<div style="display: flex; justify-content: center;">
|
<div style="display: flex; justify-content: center;">
|
||||||
<h1 style="display: flex; align-items: center;">
|
<h1 style="display: flex; align-items: center;">
|
||||||
<svg style="width:36px;height:36px;margin-right:6px;" viewBox="0 0 32 32">
|
<svg style="width:36px;height:36px;margin-right:6px;" viewBox="0 0 32 32">
|
||||||
@ -118,21 +166,19 @@
|
|||||||
<rect style="fill:#003FFF" x="18" y="10" width="4" height="8"/>
|
<rect style="fill:#003FFF" x="18" y="10" width="4" height="8"/>
|
||||||
<rect style="fill:#003FFF" x="22" y="6" width="8" height="4"/>
|
<rect style="fill:#003FFF" x="22" y="6" width="8" height="4"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span id="head">WLED Custom Palette Creator</span>
|
<span id="head">WLED Custom Palette Editor</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="parent-container">
|
<div id="parent-container">
|
||||||
<div id="gradient-box"></div>
|
<div id="gradient-box"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display: flex; justify-content: center;">
|
<div style="display: flex; justify-content: center;">
|
||||||
<div id="bottomContainer">
|
<div id="palettes" class="palettesMain">
|
||||||
<span id="idSpan">
|
<div id="palTop">
|
||||||
<label for="palId">Palette#: </label>
|
Currently in use custom palettes
|
||||||
<input id="palId" type="number" min="0" max="9" style="background-color: #111; color: #fff; border: none; font-weight: bold; text-align: center; width: 40px;" value="0">
|
</div>
|
||||||
</span>
|
|
||||||
<span id="sendSpan" onclick="initiateUpload()"></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -142,7 +188,6 @@
|
|||||||
<br>
|
<br>
|
||||||
Currently in use Custom Palette IDs are 0 to <span id="cpaltx">-1</span>. Note!, IDs <u>must</u> be in uninterupted sequece from 0 and cannot excede 9. This number will only be updated on WLED reboot (or equivalent).
|
Currently in use Custom Palette IDs are 0 to <span id="cpaltx">-1</span>. Note!, IDs <u>must</u> be in uninterupted sequece from 0 and cannot excede 9. This number will only be updated on WLED reboot (or equivalent).
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; justify-content: center;"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
@ -156,12 +201,14 @@
|
|||||||
var rect = gradientBox.getBoundingClientRect();
|
var rect = gradientBox.getBoundingClientRect();
|
||||||
var gradientLength = rect.width;
|
var gradientLength = rect.width;
|
||||||
var mOffs = Math.round((gradientLength / 256) / 2) - 5;
|
var mOffs = Math.round((gradientLength / 256) / 2) - 5;
|
||||||
|
var paletteArray = []; //Holds the palettes after load.
|
||||||
|
var svgSave = '<svg style="width:25px;height:25px" viewBox="0 0 24 24"><path fill=#fff d="M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M7,12L12,17V14H16V10H12V7L7,12Z"/></svg>'
|
||||||
|
var svgEdit = '<svg style="width:25px;height:25px" viewBox="0 0 24 24"><path fill=#fff d="M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M15.1,7.07C15.24,7.07 15.38,7.12 15.5,7.23L16.77,8.5C17,8.72 17,9.07 16.77,9.28L15.77,10.28L13.72,8.23L14.72,7.23C14.82,7.12 14.96,7.07 15.1,7.07M13.13,8.81L15.19,10.87L9.13,16.93H7.07V14.87L13.13,8.81Z"/></svg>'
|
||||||
|
|
||||||
function recOf() {
|
function recOf() {
|
||||||
rect = gradientBox.getBoundingClientRect();
|
rect = gradientBox.getBoundingClientRect();
|
||||||
gradientLength = rect.width;
|
gradientLength = rect.width;
|
||||||
mOffs = Math.round((gradientLength / 256) / 2) - 5;
|
mOffs = Math.round((gradientLength / 256) / 2) - 5;
|
||||||
console.log(mOffs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Initiation
|
//Initiation
|
||||||
@ -170,9 +217,7 @@
|
|||||||
window.addEventListener('resize', chkW);
|
window.addEventListener('resize', chkW);
|
||||||
|
|
||||||
gradientBox.addEventListener("click", clikOnGradient);
|
gradientBox.addEventListener("click", clikOnGradient);
|
||||||
gId("sendSpan").innerHTML =
|
|
||||||
'<svg class="svg-icon" style="width:36px;height:36px" viewBox="0 0 24 24"> <path id=sendSvgP fill="#fff" 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>';
|
|
||||||
|
|
||||||
//Sets start and stop, mandatory
|
//Sets start and stop, mandatory
|
||||||
addC(0);
|
addC(0);
|
||||||
addC(255);
|
addC(255);
|
||||||
@ -185,7 +230,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////// Add a new colorMarker
|
///////// Add a new colorMarker
|
||||||
function addC(truePos){
|
function addC(truePos, thisColor = ''){
|
||||||
let position = -1;
|
let position = -1;
|
||||||
let iExist = false;
|
let iExist = false;
|
||||||
const colorMarkers = gradientBox.querySelectorAll('.color-marker');
|
const colorMarkers = gradientBox.querySelectorAll('.color-marker');
|
||||||
@ -209,8 +254,9 @@
|
|||||||
} else{
|
} else{
|
||||||
position = truePos;
|
position = truePos;
|
||||||
}
|
}
|
||||||
|
if (thisColor == ''){
|
||||||
const thisColor = `#${(Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, '0')}`;// set random color as default
|
thisColor = `#${(Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, '0')}`;// set random color as default
|
||||||
|
}
|
||||||
|
|
||||||
const colorMarker = cE('span'); // create a marker for the color position
|
const colorMarker = cE('span'); // create a marker for the color position
|
||||||
colorMarker.className = 'color-marker';
|
colorMarker.className = 'color-marker';
|
||||||
@ -301,7 +347,6 @@
|
|||||||
function cpClk(e){
|
function cpClk(e){
|
||||||
removeTrashcan(event)
|
removeTrashcan(event)
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
console.log(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//This neat little function makes any element draggable on the X-axis.
|
//This neat little function makes any element draggable on the X-axis.
|
||||||
@ -428,32 +473,30 @@
|
|||||||
return rStr;
|
return rStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function initiateUpload() {
|
function initiateUpload(idx) {
|
||||||
const data = calcJSON();
|
const data = calcJSON();
|
||||||
const fileName = '/palette' + gId('palId').value + '.json';
|
const fileName = `/palette${idx}.json`;
|
||||||
uploadJSON(data, fileName);
|
uploadJSON(data, fileName);
|
||||||
console.log('File: ', fileName, 'JSON: ', data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadJSON(jsonString, fileName) {
|
function uploadJSON(jsonString, fileName) {
|
||||||
const ss = gId('sendSvgP');
|
//Some indication on "I'm working"
|
||||||
ss.setAttribute('fill', '#555');
|
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
var blob = new Blob([jsonString], {type: "application/json"});
|
var blob = new Blob([jsonString], {type: "application/json"});
|
||||||
req.addEventListener('load', ()=>{
|
req.addEventListener('load', ()=>{
|
||||||
console.log(this.responseText, ' - ', this.status)
|
console.log(this.responseText, ' - ', this.status)
|
||||||
ss.setAttribute('fill', '#056b0a');
|
|
||||||
localStorage.removeItem('wledPalx');
|
localStorage.removeItem('wledPalx');
|
||||||
setTimeout(()=>{
|
//setTimeout(()=>{
|
||||||
ss.setAttribute('fill', '#fff');
|
// ss.setAttribute('fill', '#fff');
|
||||||
}, 1000);
|
//}, 1000);
|
||||||
setTimeout(()=>{window.location.href='/';},2000);
|
//setTimeout(()=>{window.location.href='/';},2000);
|
||||||
|
window.location.href = '/'; //Guessing we want to return ASAP when we get confirmation save is done
|
||||||
});
|
});
|
||||||
req.addEventListener('error', (e)=>{
|
req.addEventListener('error', (e)=>{
|
||||||
console.log('Error: ', e); console.log(' Status: ', this.status);
|
console.log('Error: ', e); console.log(' Status: ', this.status);
|
||||||
ss.setAttribute('fill', '#6b050c');
|
//Show some error notification for some time
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
ss.setAttribute('fill', '#fff');
|
//Remove it when time has pased
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
req.open("POST", "/upload");
|
req.open("POST", "/upload");
|
||||||
@ -472,7 +515,9 @@
|
|||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
cpalc = json.cpalcount;
|
cpalc = json.cpalcount;
|
||||||
gId('cpaltx').innerHTML = cpalc-1;
|
gId('cpaltx').innerHTML = cpalc-1;
|
||||||
|
fetchPalettes(cpalc-1);
|
||||||
console.log('cpalc: ', cpalc);
|
console.log('cpalc: ', cpalc);
|
||||||
|
console.log(paletteArray);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -480,5 +525,137 @@
|
|||||||
console.error('cannot identify host');
|
console.error('cannot identify host');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchPalettes(lastPal) {
|
||||||
|
paletteArray.length = 0;
|
||||||
|
for (let i = 0; i <= lastPal; i++) {
|
||||||
|
const url = `http://${hst}/palette${i}.json`;
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
const json = await response.json();
|
||||||
|
paletteArray.push(json);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error fetching JSON from ${url}: `, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
generatePaletteDivs();
|
||||||
|
}
|
||||||
|
|
||||||
|
function generatePaletteDivs() {
|
||||||
|
const palettesDiv = document.getElementById("palettes");
|
||||||
|
const paletteDivs = Array.from(palettesDiv.children).filter((child) => {
|
||||||
|
return child.id.match(/^palette\d$/); // match only elements with id starting with "palette" followed by a single digit
|
||||||
|
});
|
||||||
|
if (paletteArray.length < 10){
|
||||||
|
//Room for one more :)
|
||||||
|
paletteArray.push({"palette":[0,70,70,70,255,70,70,70]});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const div of paletteDivs) {
|
||||||
|
palettesDiv.removeChild(div); // remove each div that matches the above selector
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < paletteArray.length; i++) {
|
||||||
|
const palette = paletteArray[i];
|
||||||
|
const paletteDiv = document.createElement("div");
|
||||||
|
paletteDiv.id = `palette${i}`;
|
||||||
|
paletteDiv.classList.add("palette");
|
||||||
|
paletteDiv.dataset.colarray = JSON.stringify(palette.palette);
|
||||||
|
|
||||||
|
const gradientDiv = document.createElement("div");
|
||||||
|
gradientDiv.id = `paletteGradient${i}`
|
||||||
|
const buttonsDiv = document.createElement("div");
|
||||||
|
buttonsDiv.id = `buttonsDiv${i}`;
|
||||||
|
buttonsDiv.classList.add("buttonsDiv")
|
||||||
|
|
||||||
|
const sendSpan = document.createElement("span");
|
||||||
|
sendSpan.id = `sendSpan${i}`;
|
||||||
|
sendSpan.onclick = function() {initiateUpload(i)};
|
||||||
|
sendSpan.setAttribute('title', `Send current editor to slot ${i}`);
|
||||||
|
sendSpan.innerHTML = svgSave;
|
||||||
|
sendSpan.classList.add("sendSpan")
|
||||||
|
const editSpan = document.createElement("span");
|
||||||
|
editSpan.id = `editSpan${i}`;
|
||||||
|
editSpan.onclick = function() {loadForEdit(i)};
|
||||||
|
editSpan.setAttribute('title', `Copy slot ${i} palette to editor`);
|
||||||
|
editSpan.innerHTML = svgEdit;
|
||||||
|
editSpan.classList.add("editSpan")
|
||||||
|
|
||||||
|
gradientDiv.classList.add("paletteGradients");
|
||||||
|
let gradientColors = "";
|
||||||
|
for (let j = 0; j < palette.palette.length; j += 4) {
|
||||||
|
const position = palette.palette[j];
|
||||||
|
const red = palette.palette[j + 1];
|
||||||
|
const green = palette.palette[j + 2];
|
||||||
|
const blue = palette.palette[j + 3];
|
||||||
|
gradientColors += `rgba(${red}, ${green}, ${blue}, 1) ${position/255*100}%, `;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradientColors = gradientColors.slice(0, -2); // remove the last comma and space
|
||||||
|
gradientDiv.style.backgroundImage = `linear-gradient(to right, ${gradientColors})`;
|
||||||
|
paletteDiv.className = "palGradientParent";
|
||||||
|
buttonsDiv.appendChild(sendSpan);
|
||||||
|
if(i<cpalc){
|
||||||
|
buttonsDiv.appendChild(editSpan); //Dont offer to edit the empty spot
|
||||||
|
}
|
||||||
|
paletteDiv.appendChild(gradientDiv);
|
||||||
|
paletteDiv.appendChild(buttonsDiv);
|
||||||
|
|
||||||
|
palettesDiv.appendChild(paletteDiv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadForEdit(i){
|
||||||
|
console.log("Lets edit no: ", i);
|
||||||
|
document.querySelectorAll('input[id^="colorPicker"]').forEach((input) => {
|
||||||
|
input.parentNode.removeChild(input);
|
||||||
|
});
|
||||||
|
document.querySelectorAll('span[id^="colorMarker"], span[id^="colorPickerMarker"], span[id^="deleteMarker"]').forEach((span) => {
|
||||||
|
span.parentNode.removeChild(span);
|
||||||
|
});
|
||||||
|
|
||||||
|
let colArray = JSON.parse(gId(`palette${i}`).getAttribute("data-colarray"));
|
||||||
|
|
||||||
|
for (let j = 0; j < colArray.length; j += 4) {
|
||||||
|
const position = colArray[j];
|
||||||
|
const red = colArray[j + 1];
|
||||||
|
const green = colArray[j + 2];
|
||||||
|
const blue = colArray[j + 3];
|
||||||
|
const hex = rgbToHex(red, green, blue);
|
||||||
|
console.log(position, hex)
|
||||||
|
addC(position, hex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function rgbToHex(r, g, b) {
|
||||||
|
const hex = ((r << 16) | (g << 8) | b).toString(16);
|
||||||
|
return "#" + "0".repeat(6 - hex.length) + hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalStorageData(){
|
||||||
|
// Retrieve the "wledPalx" JSON from local storage
|
||||||
|
const wledPalx = JSON.parse(localStorage.getItem('wledPalx'));
|
||||||
|
|
||||||
|
// Initialize an empty array to store the extracted arrays
|
||||||
|
const result = [];
|
||||||
|
|
||||||
|
// Loop through the "p" object in the "wledPalx" JSON
|
||||||
|
for (const key in wledPalx.p) {
|
||||||
|
if (wledPalx.p.hasOwnProperty(key)) {
|
||||||
|
// Check if the key is between 246 and 255
|
||||||
|
const numKey = parseInt(key, 10);
|
||||||
|
if (numKey >= 246 && numKey <= 255) {
|
||||||
|
// Replace the key with a new key that follows the mapping
|
||||||
|
const newKey = 255 - numKey;
|
||||||
|
// Add the array to the result array with the new key as the index
|
||||||
|
result[newKey] = wledPalx.p[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The "result" array now contains arrays with the new keys
|
||||||
|
console.log(result);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user