ba6e2f0a54
Updated pxmagic
918 lines
46 KiB
HTML
918 lines
46 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="pt_BR">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<link
|
|
rel="shortcut icon"
|
|
href="data:image/png;base64,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"
|
|
/>
|
|
<title>Pixel Magic Tool - @ajotanc</title>
|
|
</head>
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
::selection {
|
|
background: #1982c4;
|
|
color: #ffffff;
|
|
}
|
|
|
|
html {
|
|
scroll-behavior: smooth;
|
|
}
|
|
|
|
body {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
margin: 0;
|
|
font-size: 12px;
|
|
font-family: "Tahoma", monospace;
|
|
}
|
|
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5,
|
|
h6 {
|
|
margin: 0;
|
|
}
|
|
|
|
h3 {
|
|
color: #5f5f5f;
|
|
}
|
|
|
|
.divider {
|
|
width: calc(100% - 10px);
|
|
height: 1px;
|
|
background: #ececec;
|
|
margin: 20px auto;
|
|
}
|
|
|
|
.container {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.content {
|
|
width: 100%;
|
|
min-width: 540px;
|
|
max-width: 900px;
|
|
margin: 20px;
|
|
}
|
|
|
|
#response,
|
|
#preview,
|
|
#image,
|
|
form,
|
|
canvas {
|
|
width: 100%;
|
|
}
|
|
|
|
form {
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
background-color: #f8f8f8;
|
|
border-radius: 8px;
|
|
border: 1px solid #cccccc;
|
|
}
|
|
|
|
.row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
margin: 20px 0 0;
|
|
}
|
|
|
|
.row:nth-child(2) {
|
|
margin: 0;
|
|
}
|
|
|
|
.column {
|
|
flex-basis: calc(50% - 10px);
|
|
|
|
position: relative;
|
|
padding: 0 5px;
|
|
}
|
|
|
|
label {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
button {
|
|
font-family: "Tahoma", monospace;
|
|
}
|
|
|
|
input[type="text"],
|
|
input[type="number"],
|
|
input[type="email"],
|
|
input[type="tel"],
|
|
select,
|
|
textarea {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border-radius: 5px;
|
|
border: none;
|
|
background-color: #f0f0f0;
|
|
font-size: 12px;
|
|
display: inline-block;
|
|
font-family: "Tahoma", monospace;
|
|
outline: none;
|
|
}
|
|
|
|
input[type="color"] {
|
|
width: 32px;
|
|
height: 32px;
|
|
cursor: pointer;
|
|
padding: 0px 1px;
|
|
outline: none;
|
|
}
|
|
|
|
.input-group {
|
|
display: flex;
|
|
}
|
|
|
|
.input-group input {
|
|
border-radius: 5px 0 0 5px;
|
|
}
|
|
|
|
.input-description {
|
|
padding: 10px;
|
|
font-size: 14px;
|
|
color: #626262;
|
|
background: #d9d9d9;
|
|
border-radius: 0px 5px 5px 0;
|
|
}
|
|
|
|
select {
|
|
appearance: none;
|
|
-webkit-appearance: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath d='M.6 2.6L4 6l3.4-3.4L8 3.2 4 7.2.1 3.3z'/%3E%3C/svg%3E");
|
|
background-repeat: no-repeat;
|
|
background-position: right 10px center;
|
|
background-size: 10px 10px;
|
|
}
|
|
|
|
textarea {
|
|
resize: vertical;
|
|
min-height: 120px;
|
|
margin: 0 0 10px;
|
|
}
|
|
|
|
input[type="submit"] {
|
|
padding: 10px 20px;
|
|
border: none;
|
|
border-radius: 5px;
|
|
background-color: #4caf50;
|
|
color: #fff;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dropzone {
|
|
width: 100%;
|
|
border: 1px dashed #a9a9a9;
|
|
background-color: #f5f5f5;
|
|
color: #666;
|
|
font-size: 12px;
|
|
text-align: center;
|
|
padding: 40px 10px;
|
|
border-radius: 5px;
|
|
margin: 20px 0;
|
|
transition: all 0.5s ease-in-out;
|
|
}
|
|
|
|
.dropzone p {
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.dropzone:hover {
|
|
cursor: pointer;
|
|
background-color: #eee;
|
|
}
|
|
|
|
.dropzone.dragover {
|
|
background-color: #ddd;
|
|
}
|
|
|
|
.range-slider {
|
|
appearance: none;
|
|
background-color: #ddd;
|
|
height: 8px;
|
|
width: 100%;
|
|
border-radius: 10px;
|
|
outline: none;
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.range-slider::-webkit-slider-thumb {
|
|
appearance: none;
|
|
height: 16px;
|
|
width: 16px;
|
|
background-color: #4caf50;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
border: 0;
|
|
}
|
|
|
|
.range-slider::-moz-range-thumb {
|
|
appearance: none;
|
|
height: 16px;
|
|
width: 16px;
|
|
background-color: #4caf50;
|
|
border-radius: 50%;
|
|
cursor: pointer;
|
|
border: 0;
|
|
}
|
|
|
|
.switch {
|
|
position: relative;
|
|
display: inline-block;
|
|
width: 38px;
|
|
height: 20px;
|
|
}
|
|
|
|
.switch input {
|
|
outline: none;
|
|
display: none;
|
|
}
|
|
|
|
.switch-slider {
|
|
position: absolute;
|
|
cursor: pointer;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: #ccc;
|
|
border-radius: 34px;
|
|
transition: 0.4s;
|
|
}
|
|
|
|
.switch-slider:before {
|
|
position: absolute;
|
|
content: "";
|
|
height: 14px;
|
|
width: 14px;
|
|
left: 3px;
|
|
bottom: 3px;
|
|
background-color: white;
|
|
border-radius: 50%;
|
|
transition: 0.4s;
|
|
}
|
|
|
|
input:checked + .switch-slider {
|
|
background-color: #4caf50;
|
|
}
|
|
|
|
input:focus + .switch-slider {
|
|
box-shadow: 0 0 1px #4caf50;
|
|
}
|
|
|
|
input:checked + .switch-slider:before {
|
|
transform: translateX(18px);
|
|
}
|
|
|
|
#toast-container {
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
z-index: 9999;
|
|
}
|
|
|
|
.toast {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: max-content;
|
|
padding: 6px 12px;
|
|
margin: 10px 0 0;
|
|
border-radius: 8px;
|
|
color: #fff;
|
|
font-size: 12px;
|
|
transform: translateY(30px);
|
|
opacity: 0;
|
|
visibility: hidden;
|
|
}
|
|
|
|
.toast .toast-body {
|
|
padding: 8px 0;
|
|
color: #fdfdfd;
|
|
}
|
|
|
|
.toast.success {
|
|
background-color: #8ac926;
|
|
}
|
|
|
|
.toast.error {
|
|
background-color: #ff595e;
|
|
}
|
|
|
|
.toast.warning {
|
|
background-color: #ffca3a;
|
|
}
|
|
|
|
.toast-progress {
|
|
position: absolute;
|
|
left: 4px;
|
|
bottom: 4px;
|
|
width: calc(100% - 8px);
|
|
height: 3px;
|
|
transform: scaleX(0);
|
|
transform-origin: left;
|
|
border-radius: inherit;
|
|
}
|
|
|
|
.toast.success .toast-progress {
|
|
background: linear-gradient(to right, #8ac926, #c5ca30);
|
|
}
|
|
|
|
.toast.error .toast-progress {
|
|
background: linear-gradient(to right, #ff595e, #e23c4e);
|
|
}
|
|
|
|
.toast.warning .toast-progress {
|
|
background: linear-gradient(to right, #ffca3a, #ffda3d);
|
|
}
|
|
|
|
#multipleCanvas {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
position: relative;
|
|
}
|
|
|
|
#multipleCanvas .carousel {
|
|
display: flex;
|
|
height: 100%;
|
|
width: 100%;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#multipleCanvas .carousel img {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
margin-right: 20px;
|
|
border: 0;
|
|
}
|
|
|
|
#multipleCanvas .carousel img:last-child {
|
|
margin-right: 0;
|
|
}
|
|
|
|
.button {
|
|
width: 100%;
|
|
border: 0;
|
|
padding: 10px 18px;
|
|
border-radius: 4px;
|
|
color: #fdfdfd;
|
|
cursor: pointer;
|
|
margin: 0 0 10px;
|
|
background: #1982c4;
|
|
transition: all 0.5s ease-in-out;
|
|
}
|
|
|
|
.button:hover {
|
|
background: #4267ac;
|
|
}
|
|
|
|
.button:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.buttons {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
}
|
|
|
|
.buttonRainbow {
|
|
width: 100%;
|
|
border: 0;
|
|
padding: 10px 18px;
|
|
border-radius: 4px;
|
|
color: #fdfdfd;
|
|
cursor: pointer;
|
|
background: linear-gradient(
|
|
to right,
|
|
#ff595e,
|
|
#ffca3a,
|
|
#8ac926,
|
|
#1982c4,
|
|
#6a4c93
|
|
);
|
|
}
|
|
|
|
.buttonRainbow:hover {
|
|
animation-play-state: paused;
|
|
}
|
|
|
|
#preview {
|
|
border: 1px solid #cccccc;
|
|
padding: 20px;
|
|
margin: 20px 0;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
#preview .buttons {
|
|
margin: 0 0 20px;
|
|
}
|
|
|
|
.w-full {
|
|
flex-basis: 100% !important;
|
|
}
|
|
|
|
.margin-zero {
|
|
margin: 0;
|
|
}
|
|
|
|
#overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
display: none;
|
|
}
|
|
|
|
#overlay.loading::after {
|
|
content: "";
|
|
display: block;
|
|
position: absolute;
|
|
top: calc(50% - 19px);
|
|
left: calc(50% - 19px);
|
|
width: 26px;
|
|
height: 26px;
|
|
border: 6px solid rgba(255, 255, 255, 0.5);
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
input.invalid,
|
|
select.invalid,
|
|
textarea.invalid {
|
|
border: 1px solid #df1f1f;
|
|
}
|
|
|
|
input.invalid + .error-message,
|
|
select.invalid + .error-message,
|
|
textarea.invalid + .error-message {
|
|
display: block;
|
|
color: #df1f1f;
|
|
padding: 4px 0;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.slide-container {
|
|
width: 100%;
|
|
display: flex;
|
|
overflow-x: auto;
|
|
scroll-snap-type: x mandatory;
|
|
}
|
|
|
|
.slide {
|
|
scroll-snap-align: center;
|
|
}
|
|
|
|
.header {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 0 30px;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.header .brand {
|
|
width: 100%;
|
|
max-width: 200px;
|
|
height: 100%;
|
|
display: block;
|
|
outline: none;
|
|
border: 0;
|
|
}
|
|
|
|
#alert {
|
|
padding: 10px 20px;
|
|
border: 1px solid #ffe69c;
|
|
background: #fff3cd;
|
|
border-radius: 8px;
|
|
margin: 20px 0 0;
|
|
font-size: 14px;
|
|
font-weight: bold;
|
|
color: #664d03;
|
|
}
|
|
|
|
.subtitle {
|
|
display: block;
|
|
font-size: 11px;
|
|
font-weight: 400;
|
|
margin: 2px 0 5px;
|
|
color: #1982c4;
|
|
}
|
|
|
|
.subtitle a {
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
color: #1982c4;
|
|
}
|
|
|
|
.subtitle a:hover,
|
|
.subtitle a:focus,
|
|
.subtitle a:active {
|
|
color: #1982c4;
|
|
}
|
|
|
|
@media (max-width: 767px) {
|
|
.content {
|
|
min-width: 0;
|
|
}
|
|
|
|
.row {
|
|
flex-direction: column;
|
|
margin: 0;
|
|
}
|
|
|
|
.column {
|
|
flex-basis: 100%;
|
|
margin: 20px 0 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.divider {
|
|
margin: 20px auto 0;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.row {
|
|
flex-wrap: nowrap;
|
|
}
|
|
}
|
|
|
|
@keyframes progress {
|
|
to {
|
|
transform: scaleX(1);
|
|
}
|
|
}
|
|
|
|
@keyframes spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
0% {
|
|
border-top-color: #ff595e;
|
|
}
|
|
25% {
|
|
border-top-color: #ffca3a;
|
|
}
|
|
50% {
|
|
border-top-color: #8ac926;
|
|
}
|
|
75% {
|
|
border-top-color: #1982c4;
|
|
}
|
|
100% {
|
|
border-top-color: #6a4c93;
|
|
}
|
|
}
|
|
|
|
@keyframes rainbow {
|
|
0% {
|
|
background-position: 0% 0%;
|
|
}
|
|
50% {
|
|
background-position: 100% 100%;
|
|
}
|
|
100% {
|
|
background-position: 0% 0%;
|
|
}
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
5% {
|
|
opacity: 1;
|
|
visibility: visible;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
95% {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|
|
<body>
|
|
<div class="container">
|
|
<div class="content">
|
|
<form id="formGenerate" novalidate>
|
|
<div class="header">
|
|
<img
|
|
class="brand"
|
|
src="data:image/png;base64,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"
|
|
alt="Pixel Magic Tool"
|
|
title="Pixel Magic Tool"
|
|
/>
|
|
</div>
|
|
<div class="row">
|
|
<div class="column valitade">
|
|
<label for="hostname">Hostname</label>
|
|
<input type="text" name="hostname" id="hostname" required />
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="name">Preset Name</label>
|
|
<input
|
|
type="text"
|
|
name="name"
|
|
id="name"
|
|
value="New Preset"
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="column valitade">
|
|
<label for="pattern">Pattern</label>
|
|
<select name="pattern" id="pattern" required>
|
|
<option value="">Select a choice</option>
|
|
<option value="1" title="['ffffff']" selected>
|
|
Individual
|
|
</option>
|
|
<option value="2" title="[0, 'ffffff']">Index</option>
|
|
<option value="3" title="[0, 5, 'ffffff']">Range</option>
|
|
</select>
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="output">Output</label>
|
|
<select name="output" id="output" required>
|
|
<option value="">Select a choice</option>
|
|
<option value="json" selected>WLED JSON</option>
|
|
<option value="ha">Home Assistant</option>
|
|
<option value="curl">CURL</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="row output" style="display: none">
|
|
<div class="column valitade">
|
|
<label for="device">Device</label>
|
|
<input type="text" name="device" id="device" required />
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="uniqueId">Unique Id</label>
|
|
<input type="text" name="uniqueId" id="uniqueId" required />
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="friendlyName">Friendly Name</label>
|
|
<input
|
|
type="text"
|
|
name="friendlyName"
|
|
id="friendlyName"
|
|
required
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="column valitade">
|
|
<label for="segments">Segment Id</label>
|
|
<select name="segments" id="segments" required>
|
|
<option value="">Select a choice</option>
|
|
</select>
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="brightness">Brightness</label>
|
|
<input
|
|
type="range"
|
|
name="brightness"
|
|
id="brightness"
|
|
min="0"
|
|
max="255"
|
|
value="128"
|
|
class="range-slider"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="column valitade">
|
|
<label for="animation">Animation</label>
|
|
<label class="switch">
|
|
<input type="checkbox" name="animation" id="animation" />
|
|
<span class="switch-slider"></span>
|
|
</label>
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="transparentImage">Transparent Image</label>
|
|
<label class="switch">
|
|
<input
|
|
type="checkbox"
|
|
name="transparentImage"
|
|
id="transparentImage"
|
|
/>
|
|
<span class="switch-slider"></span>
|
|
</label>
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="resizeImage">Resize Image</label>
|
|
<label class="switch">
|
|
<input type="checkbox" name="resizeImage" id="resizeImage" />
|
|
<span class="switch-slider"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="row resizeImage" style="display: none">
|
|
<div class="column valitade">
|
|
<label for="width">Width</label>
|
|
<input type="number" name="width" id="width" value="32" />
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="height">Height</label>
|
|
<input type="number" name="height" id="height" value="32" />
|
|
</div>
|
|
</div>
|
|
<div class="row animation" style="display: none">
|
|
<div class="column valitade">
|
|
<label for="frames">Frames</label>
|
|
<input type="number" name="frames" id="frames" value="4" />
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="duration">Duration</label>
|
|
<div class="input-group">
|
|
<input
|
|
type="number"
|
|
name="duration"
|
|
id="duration"
|
|
value="0.5"
|
|
required="required"
|
|
min="0"
|
|
step="0.1"
|
|
inputmode="numeric"
|
|
/>
|
|
<div class="input-description">sec</div>
|
|
</div>
|
|
</div>
|
|
<div class="column valitade">
|
|
<label for="transition">Transition</label>
|
|
<div class="input-group">
|
|
<input
|
|
type="number"
|
|
name="transition"
|
|
id="transition"
|
|
value="0.2"
|
|
required="required"
|
|
min="0"
|
|
step="0.1"
|
|
inputmode="numeric"
|
|
/>
|
|
<div class="input-description">sec</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row transparentImage" style="display: none">
|
|
<div class="column valitade w-full">
|
|
<label for="color">Choose a color</label>
|
|
<small class="subtitle"
|
|
>Color that will replace the
|
|
<strong>transparent pixels</strong> in the image</small
|
|
>
|
|
<input type="color" name="color" id="color" value="#ffffff" />
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="column valitade w-full">
|
|
<label for="images">Images</label>
|
|
<small class="subtitle"
|
|
>Images uploaded to
|
|
<a href="http://[wled-ip]/edit" target="_blank">WLED</a>
|
|
or upload image</small
|
|
>
|
|
<select name="images" id="images" required>
|
|
<option value="">Select a choice</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div id="alert" style="display: none">
|
|
<span
|
|
>To define a large number of colors. 32x32 or larger matrix
|
|
presets need to be split into multiple requests at the same
|
|
time!</span
|
|
>
|
|
</div>
|
|
<div id="dropzone" class="dropzone valitade" style="display: none">
|
|
<p id="dropzoneLabel">
|
|
Drag and drop a file here or click to select a file
|
|
</p>
|
|
<input
|
|
type="file"
|
|
name="source"
|
|
id="source"
|
|
accept="image/*"
|
|
style="display: none"
|
|
/>
|
|
</div>
|
|
<div class="row">
|
|
<div class="column w-full">
|
|
<button type="button" class="buttonRainbow" id="btnGenerate">
|
|
Generate
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<div id="preview" style="display: none">
|
|
<div class="row margin-zero">
|
|
<div class="column w-full">
|
|
<textarea
|
|
name="response"
|
|
id="response"
|
|
cols="30"
|
|
rows="10"
|
|
readonly="readonly"
|
|
></textarea>
|
|
</div>
|
|
</div>
|
|
<div id="isNotAnimation">
|
|
<div class="buttons">
|
|
<div class="row margin-zero">
|
|
<div class="column">
|
|
<button type="button" class="button" id="btnCopyToClipboard">
|
|
Copy to Clipboard
|
|
</button>
|
|
</div>
|
|
<div class="column">
|
|
<button type="button" class="button" id="btnDownloadPreset">
|
|
Download
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="divider"></div>
|
|
<div class="row margin-zero" id="notBigData">
|
|
<div class="column">
|
|
<button type="button" class="button" id="btnSimulatePreset">
|
|
Simulate
|
|
</button>
|
|
</div>
|
|
<div class="column">
|
|
<button type="button" class="button" id="btnSavePreset">
|
|
Save
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="row margin-zero" id="bigData">
|
|
<div class="column w-full">
|
|
<button
|
|
type="button"
|
|
class="button"
|
|
id="btnSimulatePresetBigData"
|
|
>
|
|
Simulate
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="singleCanvas"></div>
|
|
</div>
|
|
<div id="isAnimation">
|
|
<div class="buttons">
|
|
<div class="row margin-zero">
|
|
<div class="column">
|
|
<button type="button" class="button" id="btnCopyToClipboard">
|
|
Copy to Clipboard
|
|
</button>
|
|
</div>
|
|
<div class="column">
|
|
<button type="button" class="button" id="btnDownloadPreset">
|
|
Download
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="divider"></div>
|
|
<div class="row margin-zero">
|
|
<div class="column w-full">
|
|
<button type="button" class="button" id="btnSavePlaylist">
|
|
Save
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="multipleCanvas"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="toast-container"></div>
|
|
<div id="overlay"></div>
|
|
</body>
|
|
<script>
|
|
const e="file:"===window.location.protocol?"http:":window.location.protocol,t=window.location.host||"0.0.0.0";let n=`${e}//${t}`;const a=document.getElementById("hostname");a.value=t,a.addEventListener("change",(async()=>{n=`${e}//${a.value}`,await r(),await d(),l()}));let o=[],s={},c=[];function l(){const e=document.getElementById("images").parentNode.querySelector("a");e.href=e.href.replace("[wled-ip]",a.value)}async function i(e,t=!1,a=5e3){const o=`${n}/presets.json`,s=`${n}/json`;let c=0;B();const l=e.map((async e=>new Promise(((t,n)=>{setTimeout((async()=>{try{const t=await fetch(o),n=await t.json(),a=Object.keys(n),c=a.find((t=>"object"==typeof n[t]&&!n[t].playlist&&n[t].n===e.n))||parseInt(a.pop())+1,l=Object.assign(e,{psave:c}),i={method:"POST",body:JSON.stringify(l)};try{const t=await fetch(s,i),{success:n}=await t.json();n&&I(`Preset "${e.n}" save successfully!`)}catch(e){I(`Error saving preset: ${e}`,"error")}}catch(e){I(e,"error")}finally{t()}}),a*c++)}))));await Promise.all(l),t?setTimeout((async()=>{await async function(){const{value:e}=document.getElementById("duration"),{value:t}=document.getElementById("transition"),{value:a}=document.getElementById("name"),o=`${n}/presets.json`,s=`${n}/json`;try{const n=await fetch(o),c=await n.json(),l=Object.keys(c),i=l.filter((e=>"object"==typeof c[e]&&!c[e].playlist&&c[e].n&&c[e].n.includes(a))),d={psave:l.find((e=>"object"==typeof c[e]&&c[e].playlist&&c[e].n&&c[e].n===a))||parseInt(l.pop())+1,n:a,on:!0,o:!1,playlist:{ps:i,dur:Array.from({length:i.length},(()=>10*e)),transition:Array.from({length:i.length},(()=>10*t)),repeat:0,end:0}},r={method:"POST",body:JSON.stringify(d)};try{const e=await fetch(s,r),{success:t}=await e.json();t&&I(`Playlist "${a}" save successfully!`)}catch(e){I(`Error saving preset: ${e}`,"error")}}catch(e){I(e,"error")}}().then((()=>{w()})).catch((()=>{w()}))}),a):w()}async function d(){const e=`${n}/edit?list=/`,t=document.getElementById("images");t.innerHTML="";[{text:"Select a choice",value:""},{text:"Upload",value:"upload"}].forEach((({text:e,value:n})=>{const a=new Option(e,n);t.appendChild(a)})),B();try{const a=await fetch(e),o=await a.json(),s=["jpeg","jpg","png","gif"];o.filter((e=>{const{name:t}=e,[n,a]=t.split(".");return e.name=t.replace("/",""),s.includes(a)})).map((e=>{const{name:a}=e,o=document.createElement("option");o.text=a,o.value=`${n}/${a}`,t.add(o)}))}catch(e){I(e,"error")}finally{w()}}async function r(){const e=document.getElementById("segments"),t=document.getElementById("width"),a=document.getElementById("height"),o=`${n}/json/state`;e.innerHTML="";[{text:"Select a choice",value:""}].forEach((({text:t,value:n})=>{const a=new Option(t,n);e.appendChild(a)})),B();try{const n=await fetch(o),{seg:s}=await n.json();s&&s.forEach((function({id:n,n:o,stop:s,stopY:c},l){const i=document.createElement("option");i.text=o||`Segment ${n}`,i.value=n,i.setAttribute("data-width",s),i.setAttribute("data-height",c),0===l&&(i.selected=!0,t.value=s,a.value=c),e.add(i)}))}catch(e){I(e,"error")}finally{w()}}!async function(){await r(),await d(),l()}();const m=document.getElementById("dropzone"),u=document.getElementById("source");function y(e){return new Promise(((t,n)=>{const a=new Image;a.addEventListener("load",(function(){t(a)})),a.addEventListener("error",(function(){n(new Error("Error loading image"))})),a.src=e}))}function g(e){const{value:t}=document.getElementById("pattern"),{value:n}=document.getElementById("segments"),{value:a}=document.getElementById("brightness"),{value:o}=document.getElementById("width"),{value:s}=document.getElementById("height"),{checked:c}=document.getElementById("resizeImage"),l=48,i=o*l,d=s*l,r=i<=768?14:18,m=o*s,u=[];let y=[];const{ctx:g}=E(o,s);g.drawImage(e,0,0,o,s);const h=g.getImageData(0,0,o,s).data,{canvas:v,ctx:I}=E(i,d);for(let e=0;e<s;e++)for(let t=0;t<o;t++){const n=e*o+t,a=p(h[4*n],h[4*n+1],h[4*n+2],h[4*n+3]),{r:s,g:c,b:i}=f(a);u.push(a);let d=t*l,m=e*l;I.fillStyle=`rgb(${s}, ${c}, ${i})`,I.fillRect(d,m,l,l),I.lineWidth=1,I.strokeStyle="#ffffff",I.strokeRect(d,m,l,l);let y=d+24,g=m+24;I.font=`${r}px Arial`,I.fillStyle="ffffff"==a?"#252525":"#ffffff",I.textAlign="center",I.textBaseline="middle",I.fillText(n+1,y,g)}switch(t){case"1":y=u;break;case"2":y=function(e){const t=[];return e.forEach(((e,n)=>{t.push(n,e)})),t}(u);break;case"3":y=function(e,t,n){let a=0,o=0,s=e[0],c=[];if(n&&t>512){const t=function(e){return e.reduce(((e,t,n)=>(n%512==0?e.push([{index:n,color:t}]):e[e.length-1].push({index:n,color:t}),e)),[])}(e);t.forEach(((n,l)=>{const i=[];n.forEach(((e,t)=>{const{index:n,color:c}=e;c!==s&&(o=n,i.push(a,o,s),a=n),s=c})),c.push(i),l===t.length-1&&i.push(a,e.length,s)}))}else e.forEach(((e,t)=>{e!==s&&(o=t,c.push(a,o,s),a=t),s=e})),c.push(a,e.length,s);return c}(u,m,c)}return{canvas:v,bri:a,id:n,i:y,length:m}}function p(e,t,n,a){const{checked:o}=document.getElementById("transparentImage"),{value:s}=document.getElementById("color");return 0===a?o?s.replace("#","").toLowerCase():h(255,255,255):h(e,t,n)}function f(e){3===(e=e.replace("#","")).length&&(e=e.replace(/(.)/g,"$1$1"));const[t,n,a]=e.match(/.{2}/g).map((e=>parseInt(e,16)));return{r:t,g:n,b:a}}function h(e,t,n){return("000000"+(e<<16|t<<8|n).toString(16)).slice(-6)}function E(e,t){const n=document.createElement("canvas");n.width=e,n.height=t;const a=n.getContext("2d",{willReadFrequently:!0});return a.imageSmoothingQuality="high",a.imageSmoothingEnabled=!1,{canvas:n,ctx:a}}function v(e,t){return"ha"===e?function(e){const{value:t}=document.getElementById("device"),{value:n}=document.getElementById("friendlyName"),{value:a}=document.getElementById("uniqueId"),{value:o}=document.getElementById("hostname");if(t){return function(e){function t(e,t){return"object"!=typeof e||Array.isArray(e)?e:n(e,t+1)}function n(e,a=0){const o=" ".repeat(a);return Object.entries(e).map((([e,s])=>"object"!=typeof s||Array.isArray(s)?`${o}${e}: ${t(s,a)}`:`${o}${e}:\n${n(s,a+1)}`)).join("\n")}return n(e)}({switches:{[t]:{friendly_name:n,unique_id:a,command_on:`curl -X POST "http://${o}/json/state" -d '${e}' -H "Content-Type: application/json"`,command_off:`curl -X POST "http://${o}/json/state" -d '{"on":false}' -H "Content-Type: application/json"`}}})}}(t):"curl"===e?function(e){const{value:t}=document.getElementById("hostname");return`curl -X POST "http://${t}/json/state" -d '${e}' -H "Content-Type: application/json"`}(t):t}function I(e,t="success",n=2e3,a="preview"){const o=document.getElementById(a),s=document.createElement("div");s.style.animation="fadeIn",s.style.animationDuration=`${n+100}ms`,s.style.animationTimingFunction="linear",s.classList.add("toast",t);const c=document.createElement("span");c.classList.add("toast-body"),c.textContent=e,s.appendChild(c);const l=document.createElement("div");l.classList.add("toast-progress"),l.style.animation="progress",l.style.animationDuration=`${n+100}ms`,l.style.animationDelay="0s",s.appendChild(l),document.getElementById("toast-container").appendChild(s),setTimeout((()=>{s.style.opacity=0,setTimeout((()=>{s.remove()}),100)}),n),"error"===t&&(o.style.display="none")}function B(){const e=document.getElementById("overlay");e.classList.add("loading"),e.style.display="block",e.style.cursor="not-allowed",document.body.style.overflow="hidden"}function w(){const e=document.getElementById("overlay");e.classList.remove("loading"),e.style.display="none",e.style.cursor="default",document.body.style.overflow="auto"}function b(e){e.preventDefault();const t=document.getElementById("formGenerate").querySelectorAll("input, select, textarea");let n=!0;const a=navigator.language||navigator.userLanguage;return t.forEach((e=>{const t=e.closest(".valitade");if(!t)return;let o=!0,s=t;for(;s!==document.body;){const e=window.getComputedStyle(s);if("none"===e.display||"hidden"===e.display){o=!1;break}s=s.parentNode}if(o&&(!e.checkValidity()||"file"===e.type&&0===e.files.length)){e.classList.add("invalid");const o=e.dataset.errorMessage||e.validationMessage||function(e){e.includes("-")&&(e=e.split("-")[1]);const t={en:"This field is required.",br:"Este campo é obrigatório.",pt:"Este campo é obrigatório.",es:"¡Este campo es obligatorio.",fr:"Ce champ est obligatoire.",de:"Dieses Feld ist erforderlich.",it:"Questo campo è obbligatorio."};return t[e.toLowerCase()]||t.en}(a);let s=t.querySelector(".error-message");s||(s=document.createElement("div"),s.classList.add("error-message"),t.appendChild(s)),s.innerText=o,n=!1}else{e.classList.remove("invalid");const n=t.querySelector(".error-message");n&&t.removeChild(n)}})),n}function $(){const{checked:e}=document.getElementById("animation"),t=e?["gif"]:["jpeg","jpg","png","gif"],n=document.getElementById("source").files[0],a=document.getElementById("images"),{value:o}=a.selectedOptions[0],s="upload"===o?n.name.split(".").pop():o.split(".").pop();return!!t.includes(s)||(I(e?"Image format is not valid, select a GIF!":"Image format is not valid","error"),!1)}m.addEventListener("dragover",(e=>{e.preventDefault()})),m.addEventListener("drop",(e=>{e.preventDefault();const t=document.getElementById("dropzoneLabel");u.files=e.dataTransfer.files;const{name:n}=u.files[0];t.textContent=`Image ${n} selected!`,b(e)})),m.addEventListener("click",(()=>{u.click()})),u.addEventListener("change",(e=>{const t=document.getElementById("dropzoneLabel"),{name:n}=e.target.files[0];t.textContent=`Image ${n} selected!`,b(e)})),document.getElementById("btnSimulatePresetBigData").addEventListener("click",(async()=>{const e=`${n}/json/state`;B();const t=c.map((async(t,n)=>new Promise((async(a,o)=>{setTimeout((async()=>{try{const a={method:"POST",body:JSON.stringify(t)},o=await fetch(e,a),{success:s}=await o.json();n===c.length-1&&s&&I("Preset sent successfully!")}catch(e){I(e,"error")}finally{w()}}),100)}))));await Promise.all(t)})),document.getElementById("btnSimulatePreset").addEventListener("click",(async()=>{const e=`${n}/json/state`,t={method:"POST",body:JSON.stringify(s)};B();try{const n=await fetch(e,t),{success:a}=await n.json();a&&I("Preset sent successfully!")}catch(e){I(e,"error")}finally{w()}})),document.getElementById("btnSavePreset").addEventListener("click",(async()=>{const{value:e}=document.getElementById("name");o.splice(0),o.push(Object.assign({},s,{n:e,o:!1})),await i(o)})),document.getElementById("btnSavePlaylist").addEventListener("click",(async()=>{await i(o,!0)})),document.querySelectorAll("#btnCopyToClipboard").forEach((e=>{e.addEventListener("click",(async()=>{const e=document.getElementById("response");e.select();try{await navigator.clipboard.writeText(e.value),I("Text copied to clipboard")}catch(e){try{await document.execCommand("copy"),I("Text copied to clipboard")}catch(e){I(e,"error")}}}))})),document.querySelectorAll("#btnDownloadPreset").forEach((e=>{e.addEventListener("click",(()=>{const{value:e}=document.getElementById("response"),{value:t}=document.getElementById("output");!function(e,t,n){let a,o;switch(n){case"json":a="application/json",o="json";break;case"ha":a="application/x-yaml",o="yaml";break;case"curl":a="text/plain",o="txt"}const s=new Blob([e],{type:a}),c=URL.createObjectURL(s),l=document.createElement("a");l.href=c,l.download=`${t}.${o}`,l.click(),URL.revokeObjectURL(c)}(e,`WLED_${(new Date).getTime()}`,t)}))})),document.getElementById("segments").addEventListener("change",(e=>{const t=document.getElementById("width"),n=document.getElementById("height"),a=e.target.selectedOptions[0],o=a.getAttribute("data-width"),s=a.getAttribute("data-height");t.value=o,n.value=s})),document.getElementById("output").addEventListener("change",(e=>{const t=document.getElementsByClassName("output"),{value:n}=e.target.selectedOptions[0];Array.from(t).forEach((function(e){e.style.display="ha"===n?"flex":"none"}))})),document.getElementById("images").addEventListener("change",(e=>{const t=document.getElementById("dropzone"),{value:n}=e.target.selectedOptions[0];if("upload"===n){const e=document.getElementById("dropzoneLabel"),n=document.getElementById("source");e.textContent="Drag and drop a file here or click to select a file",n.value="",t.style.display="block"}else t.style.display="none"})),document.getElementById("transparentImage").addEventListener("change",(e=>{const t=document.getElementsByClassName("transparentImage"),{checked:n}=e.target;Array.from(t).forEach((function(e){e.style.display=n?"flex":"none"}))})),document.getElementById("resizeImage").addEventListener("change",(e=>{const t=document.getElementsByClassName("resizeImage"),n=document.getElementById("pattern"),{checked:a}=e.target;Array.from(t).forEach((function(e){a?(n.value=3,e.style.display="flex"):(n.value=1,e.style.display="none")}))})),document.getElementById("animation").addEventListener("change",(e=>{const t=document.getElementsByClassName("animation"),n=document.getElementById("pattern"),{checked:a}=e.target;Array.from(t).forEach((function(e){a?(I('If you want all frames in the image, set it to "0"',"warning",5e3),e.style.display="flex",n.value=3):(e.style.display="none",n.value=1)}))})),document.getElementById("btnGenerate").addEventListener("click",(async e=>{const{checked:t}=document.getElementById("animation"),n=document.getElementById("preview"),a=document.getElementById("isNotAnimation"),l=document.getElementById("singleCanvas"),i=document.getElementById("isAnimation"),d=document.getElementById("multipleCanvas");b(e)&&(e.preventDefault(),o.splice(0),c.splice(0),n.style.display="block",t?(i.style.display="block",a.style.display="none",l.innerHTML="",await async function(){if($()){const e=document.getElementById("source").files[0],t=document.getElementById("images"),n=(document.getElementById("preview"),document.getElementById("response")),{value:a}=document.getElementById("name"),{value:s}=document.getElementById("frames"),{value:c}=document.getElementById("output"),{value:l}=document.getElementById("duration"),{text:i,value:d}=t.selectedOptions[0];B();try{const t=new FormData;if("upload"===d)t.append("image",e);else{const e=await fetch(d),n=await e.blob(),a=new File([n],i,{type:n.type});t.append("image",a)}const r=await fetch(`https://pixelmagictool.vercel.app/api/wled/frames?amount=${s}`,{method:"POST",body:t}),{message:m,frames:u}=await r.json();if(!r.ok)return void I(m,"error");o=[];const p=[],f=[],h=1e3*l,E=u.map((async(e,t)=>{const n=await y(e),{canvas:s,bri:c,id:l,i:i}=g(n),d={on:!0,bri:c,seg:{id:l,i:i}},r=`${a} ${t+1}`;p.push(`${r}|${JSON.stringify(d)}`),f.push(s),o.push(Object.assign(d,{n:r,o:!0}))}));await Promise.all(E);const B=p.map((e=>{const[t,n]=e.split("|"),a=v(c,n);return`${["ha","curl"].includes(c)?"#":"//"} ${t}\n${a}`}));n.value=B.join("\n"),I(m),function(e,t,n=3e3){let a=0;const o=document.createElement("div");o.classList.add("carousel"),t.forEach(((e,t)=>{t===a||(e.style.display="none"),o.appendChild(e)}));const s=document.getElementById(e);let c;function l(){clearTimeout(c),c=setTimeout((()=>{next(),0===a&&o.scrollTo(0,0)}),n)}s.innerHTML="",s.appendChild(o),l(),o.addEventListener("mouseover",(()=>{clearTimeout(c)})),o.addEventListener("mouseout",(()=>{l()}))}("multipleCanvas",f,h)}catch(e){I(e,"error")}finally{w()}}}()):(i.style.display="none",a.style.display="block",d.innerHTML="",await async function(){if($()){const e=document.getElementById("source").files[0],{value:t}=document.getElementById("images"),{value:n}=document.getElementById("output");B();try{const a=document.getElementById("response"),o=document.getElementById("notBigData"),l=document.getElementById("bigData"),i=document.getElementById("alert"),d=document.getElementById("singleCanvas");d.innerHTML="";const r="upload"===t?URL.createObjectURL(e):t,m=await y(r),{canvas:u,bri:p,id:f,i:h,length:E}=g(m);let I=null;if(E>512){o.style.display="none",l.style.display="flex",i.style.display="flex";const e=h.map((e=>{const t={on:!0,bri:p,seg:{id:f,i:e}};c.push(t)}));await Promise.all(e);const t=c.map((e=>v(n,JSON.stringify(e))));I=["json","ha"].includes(n)?t.join("\n"):t.join(" && ")}else{o.style.display="flex",l.style.display="none",i.style.display="none",await new Promise((e=>{Object.assign(s,{on:!0,bri:p,seg:{id:f,i:h}}),e()}));const e=JSON.stringify(s);I=v(n,e)}a.value=I,d.appendChild(u)}catch(e){I(e,"error")}finally{w()}}}()))}));
|
|
</script>
|
|
</html>
|