From 92f9c908f63e4bc189456ffe33220425e76abd24 Mon Sep 17 00:00:00 2001 From: Henrik Date: Sun, 23 Apr 2023 21:32:52 +0200 Subject: [PATCH] Custom palettes now editable --- wled00/data/cpal/cpal.htm | 239 +++++++++++++++++++++++++++++++++----- 1 file changed, 208 insertions(+), 31 deletions(-) diff --git a/wled00/data/cpal/cpal.htm b/wled00/data/cpal/cpal.htm index c18af81a..39ae8c6f 100644 --- a/wled00/data/cpal/cpal.htm +++ b/wled00/data/cpal/cpal.htm @@ -102,14 +102,62 @@ font-family: Arial, sans-serif; font-size: 12px; position: relative; - margin-top: 100px; + margin-top: 10px; 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; + } -
+

@@ -118,21 +166,19 @@ - WLED Custom Palette Creator + WLED Custom Palette Editor

-
-
- - - - - +
+
+ Currently in use custom palettes +
+
@@ -142,7 +188,6 @@
Currently in use Custom Palette IDs are 0 to -1. Note!, IDs must be in uninterupted sequece from 0 and cannot excede 9. This number will only be updated on WLED reboot (or equivalent).
-
@@ -156,12 +201,14 @@ var rect = gradientBox.getBoundingClientRect(); var gradientLength = rect.width; var mOffs = Math.round((gradientLength / 256) / 2) - 5; + var paletteArray = []; //Holds the palettes after load. + var svgSave = '' + var svgEdit = '' function recOf() { rect = gradientBox.getBoundingClientRect(); gradientLength = rect.width; mOffs = Math.round((gradientLength / 256) / 2) - 5; - console.log(mOffs) } //Initiation @@ -170,9 +217,7 @@ window.addEventListener('resize', chkW); gradientBox.addEventListener("click", clikOnGradient); - gId("sendSpan").innerHTML = - ' '; - + //Sets start and stop, mandatory addC(0); addC(255); @@ -185,7 +230,7 @@ } ///////// Add a new colorMarker - function addC(truePos){ + function addC(truePos, thisColor = ''){ let position = -1; let iExist = false; const colorMarkers = gradientBox.querySelectorAll('.color-marker'); @@ -209,8 +254,9 @@ } else{ position = truePos; } - - const thisColor = `#${(Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, '0')}`;// set random color as default + if (thisColor == ''){ + 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 colorMarker.className = 'color-marker'; @@ -301,7 +347,6 @@ function cpClk(e){ removeTrashcan(event) e.stopPropagation(); - console.log(e); } //This neat little function makes any element draggable on the X-axis. @@ -428,32 +473,30 @@ return rStr; } - function initiateUpload() { + function initiateUpload(idx) { const data = calcJSON(); - const fileName = '/palette' + gId('palId').value + '.json'; + const fileName = `/palette${idx}.json`; uploadJSON(data, fileName); - console.log('File: ', fileName, 'JSON: ', data); } function uploadJSON(jsonString, fileName) { - const ss = gId('sendSvgP'); - ss.setAttribute('fill', '#555'); + //Some indication on "I'm working" var req = new XMLHttpRequest(); var blob = new Blob([jsonString], {type: "application/json"}); req.addEventListener('load', ()=>{ console.log(this.responseText, ' - ', this.status) - ss.setAttribute('fill', '#056b0a'); localStorage.removeItem('wledPalx'); - setTimeout(()=>{ - ss.setAttribute('fill', '#fff'); - }, 1000); - setTimeout(()=>{window.location.href='/';},2000); + //setTimeout(()=>{ + // ss.setAttribute('fill', '#fff'); + //}, 1000); + //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)=>{ console.log('Error: ', e); console.log(' Status: ', this.status); - ss.setAttribute('fill', '#6b050c'); + //Show some error notification for some time setTimeout(()=>{ - ss.setAttribute('fill', '#fff'); + //Remove it when time has pased }, 1000); }); req.open("POST", "/upload"); @@ -472,7 +515,9 @@ const json = await response.json(); cpalc = json.cpalcount; gId('cpaltx').innerHTML = cpalc-1; + fetchPalettes(cpalc-1); console.log('cpalc: ', cpalc); + console.log(paletteArray); } catch (error) { console.error(error); } @@ -480,5 +525,137 @@ 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 { + 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); + } + +