662 lines
22 KiB
HTML
662 lines
22 KiB
HTML
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
<meta http-equiv="Pragma" content="no-cache">
|
|
<meta http-equiv="Expires" content="0">
|
|
<title>WLED Custom Palette Editor</title>
|
|
<script type="text/javascript">
|
|
var d = document;
|
|
function gId(e) {return d.getElementById(e);}
|
|
function cE(e) {return d.createElement(e);}
|
|
</script>
|
|
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
background-color: #111;
|
|
font-size: 16px;
|
|
color: #ddd;
|
|
margin: 0 10px;
|
|
font-family: Arial, sans-serif;
|
|
line-height: 0.5;
|
|
}
|
|
#parent-container {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 20px;
|
|
|
|
}
|
|
|
|
#bottomContainer {
|
|
position: absolute;
|
|
margin-top: 50px;
|
|
|
|
}
|
|
|
|
#gradient-box {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.color-marker {
|
|
position: absolute;
|
|
height: 30px;
|
|
width: 7px;
|
|
border-radius: 3px;
|
|
background-color: rgb(192, 192, 192);
|
|
border: 2px solid rgba(68, 68, 68, 0.5);
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
z-index: 2;
|
|
}
|
|
.color-picker-marker {
|
|
position: absolute;
|
|
height: 7px;
|
|
width: 7px;
|
|
border-radius: 3px;
|
|
background-color: rgb(192, 192, 192);
|
|
border: 2px solid rgba(68, 68, 68, 0.5);
|
|
top: 150%;
|
|
z-index: 2;
|
|
}
|
|
.delete-marker {
|
|
position: absolute;
|
|
height: 5px;
|
|
width: 5px;
|
|
border-radius: 3px;
|
|
background-color: rgb(255, 255, 255);
|
|
border: 3px solid rgb(155, 40, 40);
|
|
top: 220%;
|
|
z-index: 2;
|
|
}
|
|
.color-picker{
|
|
position: absolute;
|
|
height: 1px;
|
|
width: 1px;
|
|
border: 1px;
|
|
top: 150%;
|
|
z-index: 1;
|
|
border-color: #111;
|
|
background-color: #111;
|
|
}
|
|
.buttonclass {
|
|
padding: 0,0,0,0px;
|
|
margin: 0,0,0,0px;
|
|
vertical-align: bottom;
|
|
background-color: #111;
|
|
}
|
|
#bottomContainer span {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
color: #fff;
|
|
font-family: Arial, sans-serif;
|
|
font-size: 12px;
|
|
vertical-align: middle;
|
|
}
|
|
#info {
|
|
display: "";
|
|
text-align: center;
|
|
color: #fff;
|
|
font-family: Arial, sans-serif;
|
|
font-size: 12px;
|
|
position: relative;
|
|
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;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="wrap" class="wrap">
|
|
<div style="display: flex; justify-content: center;">
|
|
<h1 style="display: flex; align-items: center;">
|
|
<svg style="width:36px;height:36px;margin-right:6px;" viewBox="0 0 32 32">
|
|
<rect style="fill:#003FFF" x="6" y="22" width="8" height="4"/>
|
|
<rect style="fill:#003FFF" x="14" y="14" 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"/>
|
|
</svg>
|
|
<span id="head">WLED Custom Palette Editor</span>
|
|
</h1>
|
|
</div>
|
|
|
|
<div id="parent-container">
|
|
<div id="gradient-box"></div>
|
|
</div>
|
|
<div style="display: flex; justify-content: center;">
|
|
<div id="palettes" class="palettesMain">
|
|
<div id="palTop">
|
|
Currently in use custom palettes
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; justify-content: center;">
|
|
<div id="info">
|
|
Click on the gradient to add new color slider. Click the colored box below the slider to change color. Click the red box below indicator (and confirm) to delete. Select palette number. Click the cloud icon to upload.
|
|
<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).
|
|
</div>
|
|
</div>
|
|
|
|
</body>
|
|
|
|
<script type="text/javascript">
|
|
//global variables
|
|
var gradientBox = gId('gradient-box');
|
|
var cpalc = -1;
|
|
var pxCol = {};
|
|
var tCol = {};
|
|
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 = '<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() {
|
|
rect = gradientBox.getBoundingClientRect();
|
|
gradientLength = rect.width;
|
|
mOffs = Math.round((gradientLength / 256) / 2) - 5;
|
|
}
|
|
|
|
//Initiation
|
|
getInfo();
|
|
window.addEventListener('load', chkW);
|
|
window.addEventListener('resize', chkW);
|
|
|
|
gradientBox.addEventListener("click", clikOnGradient);
|
|
|
|
//Sets start and stop, mandatory
|
|
addC(0);
|
|
addC(255);
|
|
|
|
updateGradient(); //Sets the gradient at startup
|
|
|
|
function clikOnGradient(e){
|
|
removeTrashcan(e);
|
|
addC(Math.round((e.offsetX/gradientLength)*256));
|
|
}
|
|
|
|
///////// Add a new colorMarker
|
|
function addC(truePos, thisColor = ''){
|
|
let position = -1;
|
|
let iExist = false;
|
|
const colorMarkers = gradientBox.querySelectorAll('.color-marker');
|
|
|
|
colorMarkers.forEach((colorMarker, i) => {
|
|
if (colorMarker.getAttribute("data-truepos") == truePos) {
|
|
iExist = true;
|
|
}
|
|
});
|
|
|
|
if (colorMarkers.length > 17) iExist = true;
|
|
if (iExist) return; // Exit the function early if iExist is true
|
|
|
|
if (truePos > 0 && truePos < 255) {
|
|
//calculate first available > 0
|
|
for (var i = 1; i <= 16 && position < 1; i++) {
|
|
if (!gId("colorMarker"+i)) {
|
|
position = i;
|
|
}
|
|
}
|
|
} else{
|
|
position = truePos;
|
|
}
|
|
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';
|
|
colorMarker.id = 'colorMarker' + position.toString();
|
|
colorMarker.setAttribute("data-truepos", truePos); //Used to always have a true position no matter what screen or percentage we use
|
|
colorMarker.setAttribute("data-truecol", thisColor); //Used to hold the color of the position in the gradient connected to a true position
|
|
colorMarker.setAttribute("data-offset", mOffs);
|
|
colorMarker.addEventListener('click', stopFurtherProp); //Added to prevent the gradient click to fire when covered by a marker
|
|
colorMarker.style.left = `${Math.round((gradientLength / 256) * truePos)+mOffs}px`;
|
|
|
|
const colorPicker = cE('input');
|
|
colorPicker.type = 'color';
|
|
colorPicker.value = thisColor;
|
|
colorPicker.className = 'color-picker';
|
|
colorPicker.id = 'colorPicker' + position.toString();
|
|
colorPicker.addEventListener('input', updateGradient);
|
|
colorPicker.addEventListener('click',cpClk)
|
|
|
|
const colorPickerMarker = cE('span'); // create a marker for the color position
|
|
colorPickerMarker.className = 'color-picker-marker';
|
|
colorPickerMarker.id = 'colorPickerMarker' + position.toString();
|
|
colorPickerMarker.addEventListener('click', colClk);
|
|
colorPickerMarker.style.left = colorMarker.style.left;
|
|
colorPicker.style.left = colorMarker.style.left;
|
|
|
|
const deleteMarker = cE('span'); // create a delete marker for the color position
|
|
if (position > 0 && position < 255) {
|
|
deleteMarker.className = 'delete-marker';
|
|
deleteMarker.id = 'deleteMarker' + position.toString();
|
|
deleteMarker.addEventListener('click', (e) => {
|
|
deleteColor(e);
|
|
});
|
|
deleteMarker.style.left = colorMarker.style.left
|
|
}
|
|
|
|
colorMarker.style.backgroundColor = colorPicker.value; // set marker color to match color picker
|
|
colorPickerMarker.style.backgroundColor = colorPicker.value;
|
|
|
|
gradientBox.appendChild(colorPicker);
|
|
gradientBox.appendChild(colorMarker);
|
|
gradientBox.appendChild(colorPickerMarker);
|
|
if (position != 0 && position != 255) gradientBox.appendChild(deleteMarker); // append the marker if not start or end
|
|
//make markers slidable IF they are not the first or last slider
|
|
if (position > 0 && position < 255) makeMeDrag(gId(colorMarker.id));
|
|
|
|
setTooltipMarker(gId(colorMarker.id));
|
|
|
|
updateGradient();
|
|
}
|
|
|
|
///////// Update Gradient
|
|
function updateGradient() {
|
|
const colorMarkers = gradientBox.querySelectorAll('.color-marker');
|
|
pxCol = {};
|
|
tCol = {}
|
|
colorMarkers.forEach((colorMarker, index) => {
|
|
const thisColorPicker = gId(colorMarkers[index].id.replace('colorMarker', 'colorPicker'));
|
|
const colorToSet = thisColorPicker.value;
|
|
gId(colorMarkers[index].id.replace('colorMarker', 'colorPickerMarker')).style.backgroundColor = colorToSet;
|
|
colorMarkers[index].style.backgroundColor = colorToSet;
|
|
colorMarkers[index].setAttribute("data-truecol", colorToSet);
|
|
const tPos = colorMarkers[index].getAttribute("data-truepos");
|
|
const gradientPos = Math.round((gradientLength / 256)*tPos);
|
|
pxCol[gradientPos] = colorToSet;
|
|
tCol[tPos] = colorToSet;
|
|
});
|
|
gradientString = 'linear-gradient(to right';
|
|
Object.entries(pxCol).forEach(([p, c]) => {
|
|
gradientString += `, ${c} ${p}px`;
|
|
});
|
|
gradientString += ')';
|
|
gradientBox.style.background = gradientString;
|
|
//gId("jsonstring").innerHTML = calcJSON();
|
|
}
|
|
|
|
|
|
function stopFurtherProp(e){
|
|
e.stopPropagation();
|
|
}
|
|
|
|
function colClk(e){
|
|
removeTrashcan(e)
|
|
e.stopPropagation();
|
|
let cp = gId(e.srcElement.id.replace("Marker",""));
|
|
cp.click();
|
|
}
|
|
|
|
function cpClk(e){
|
|
removeTrashcan(event)
|
|
e.stopPropagation();
|
|
}
|
|
|
|
//This neat little function makes any element draggable on the X-axis.
|
|
//Just call: makeMeDrag(myElement); And you are good to go.
|
|
function makeMeDrag(elmnt) {
|
|
var posNew = 0, mousePos = 0, mouseOffset = 0
|
|
|
|
//Set these to whatever you want to limit your movement to
|
|
var rect = gradientBox.getBoundingClientRect();
|
|
var maxX = rect.right; // maximum X coordinate
|
|
var minX = rect.left; // minimum X coordinate i.e. also offset from left of screen
|
|
var gradientLength = maxX - minX + 1;
|
|
|
|
elmnt.onmousedown = dragMouseDown;
|
|
|
|
function dragMouseDown(e) {
|
|
removeTrashcan(event)
|
|
e = e || window.event;
|
|
e.preventDefault();
|
|
// get the mouse cursor position at startup:
|
|
mousePos = e.clientX;
|
|
d.onmouseup = closeDragElement;
|
|
// call a function whenever the cursor moves:
|
|
d.onmousemove = elementDrag;
|
|
}
|
|
|
|
function elementDrag(e) {
|
|
e = e || window.event;
|
|
e.preventDefault();
|
|
// calculate the new cursor position:
|
|
posNew = mousePos - e.clientX;
|
|
mousePos = e.clientX;
|
|
mousePosInGradient = mousePos - (minX + 1)
|
|
|
|
truePos = Math.round((mousePosInGradient/gradientLength)*256);
|
|
oldTruePos = elmnt.getAttribute("data-truepos");
|
|
// set the element's new position if new position within min/max limits:
|
|
if (truePos > 0 && truePos < 255 && oldTruePos != truePos) {
|
|
if (truePos < 64) {
|
|
thisOffset = 0;
|
|
} else if (truePos > 192) {
|
|
thisOffset = 7;
|
|
} else {
|
|
thisOffset=3;
|
|
}
|
|
elmnt.style.left = (Math.round((gradientLength/256)*truePos)+mOffs) + "px";
|
|
gId(elmnt.id.replace('colorMarker', 'colorPickerMarker')).style.left = elmnt.style.left;
|
|
gId(elmnt.id.replace('colorMarker', 'deleteMarker')).style.left = elmnt.style.left;
|
|
gId(elmnt.id.replace('colorMarker', 'colorPicker')).style.left = elmnt.style.left;
|
|
elmnt.setAttribute("data-truepos", truePos);
|
|
setTooltipMarker(elmnt);
|
|
updateGradient();
|
|
}
|
|
}
|
|
|
|
function closeDragElement() {
|
|
/* stop moving when mouse button is released:*/
|
|
d.onmouseup = null;
|
|
d.onmousemove = null;
|
|
}
|
|
}
|
|
|
|
function setTooltipMarker(elmnt){
|
|
elmnt.setAttribute('title', `${elmnt.getAttribute("data-truepos")} : ${elmnt.getAttribute("data-truecol")}`)
|
|
}
|
|
|
|
function deleteColor(e) {
|
|
var trash = cE("div");
|
|
thisDeleteMarker = e.srcElement;
|
|
thisColorMarker = gId(thisDeleteMarker.id.replace("delete", "color"));
|
|
thisColorPickerMarker = gId(thisDeleteMarker.id.replace("delete", "colorPicker"));
|
|
thisColorPicker = gId(thisDeleteMarker.id.replace("deleteMarker", "colorPicker"));
|
|
renderOffsetX = 15 - 5;
|
|
renderX = e.srcElement.getBoundingClientRect().x - renderOffsetX;
|
|
renderY = e.srcElement.getBoundingClientRect().y + 13;
|
|
|
|
trash.id = "trash";
|
|
trash.innerHTML = '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" width="30px" height="30px"><path style="fill:#880000; stroke: #888888; stroke-width: -2px;stroke-dasharray: 0.1, 8;" d="M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M7,6H17V19H7V6M9,8V17H11V8H9M13,8V17H15V8H13Z"/></svg>';
|
|
trash.style.position = "absolute";
|
|
trash.style.left = (renderX) + "px";
|
|
trash.style.top = (renderY) + "px";
|
|
d.body.appendChild(trash);
|
|
|
|
trash.addEventListener("click", (e)=>{
|
|
trash.parentNode.removeChild(trash);
|
|
thisDeleteMarker.parentNode.removeChild(thisDeleteMarker);
|
|
thisColorPickerMarker.parentNode.removeChild(thisColorPickerMarker);
|
|
thisColorMarker.parentNode.removeChild(thisColorMarker);
|
|
thisColorPicker.parentNode.removeChild(thisColorPicker);
|
|
updateGradient();
|
|
});
|
|
e.stopPropagation();
|
|
// Add event listener to close the trashcan on outside click
|
|
d.addEventListener("click", removeTrashcan);
|
|
e.stopPropagation();
|
|
}
|
|
|
|
function removeTrashcan(event) {
|
|
trash = gId("trash");
|
|
if (event.target != trash && trash) {
|
|
trash.parentNode.removeChild(trash);
|
|
d.removeEventListener("click", removeTrashcan);
|
|
}
|
|
}
|
|
|
|
function chkW() {
|
|
//Possibly add more code that recalculates the gradient... Massive job ;)
|
|
const wrap = gId('wrap');
|
|
const head = gId('head');
|
|
if (wrap.offsetWidth < 600) {
|
|
head.style.display = 'none';
|
|
} else {
|
|
head.style.display = 'inline';
|
|
}
|
|
}
|
|
|
|
function calcJSON() {
|
|
let rStr = '{"palette":['
|
|
Object.entries(tCol).forEach(([p, c]) => {
|
|
if (p > 0) rStr += ',';
|
|
rStr += `${p},${parseInt(c.slice(1, 3), 16)},${parseInt(c.slice(3, 5), 16)},${parseInt(c.slice(5, 7), 16)}`;
|
|
});
|
|
rStr += ']}';
|
|
return rStr;
|
|
}
|
|
|
|
function initiateUpload(idx) {
|
|
const data = calcJSON();
|
|
const fileName = `/palette${idx}.json`;
|
|
uploadJSON(data, fileName);
|
|
}
|
|
|
|
function uploadJSON(jsonString, fileName) {
|
|
//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)
|
|
localStorage.removeItem('wledPalx');
|
|
//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);
|
|
//Show some error notification for some time
|
|
setTimeout(()=>{
|
|
//Remove it when time has pased
|
|
}, 1000);
|
|
});
|
|
req.open("POST", "/upload");
|
|
var formData = new FormData();
|
|
formData.append("data", blob, fileName);
|
|
req.send(formData);
|
|
return false;
|
|
}
|
|
|
|
async function getInfo() {
|
|
hst = location.host;
|
|
if (hst.length > 0 ){
|
|
try {
|
|
var arr = [];
|
|
const response = await fetch('http://'+hst+'/json/info');
|
|
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);
|
|
}
|
|
} else {
|
|
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>
|
|
|
|
|
|
|