mirror of
https://codeberg.org/icewind/ptouch-api.git
synced 2026-06-03 10:54:07 +02:00
initial webui work
This commit is contained in:
parent
f7910f967b
commit
71cf4dbcb2
4 changed files with 248 additions and 4 deletions
34
web/index.html
Normal file
34
web/index.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="icon" href="data:;base64,=">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<title>PTouch</title>
|
||||
</head>
|
||||
<body>
|
||||
<table id="elements">
|
||||
<thead>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<td>
|
||||
<input type="button" value="Add" id="add"/>
|
||||
</td>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<label for="canvas-width">Width</label>
|
||||
<input type="number" min="0" id="canvas-width" value="300">
|
||||
<select id="canvas-width-unit">
|
||||
<option value="px" selected>px</option>
|
||||
<option value="mm">mm</option>
|
||||
</select>
|
||||
</p>
|
||||
<canvas id="preview" height="32" width="300"></canvas>
|
||||
|
||||
<script src="label.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
156
web/label.js
Normal file
156
web/label.js
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
const elementsTable = document.getElementById('elements');
|
||||
/** @type HTMLCanvasElement preview */
|
||||
const preview = document.getElementById('preview');
|
||||
const renderCtx = preview.getContext("2d");
|
||||
const elementsTableBody = elementsTable.getElementsByTagName('tbody')[0];
|
||||
const addButton = document.getElementById('add');
|
||||
const widthInput = document.getElementById('canvas-width');
|
||||
const widthUnit = document.getElementById('canvas-width-unit');
|
||||
|
||||
let tapeWidthMM = 0;
|
||||
let defaultFontSize = 24;
|
||||
let backgroundColor = "white";
|
||||
let textColor = "white";
|
||||
|
||||
const nextElementId = () => {
|
||||
let rows = elementsTableBody.getElementsByTagName('tr');
|
||||
if (rows.length === 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return parseInt(rows[0].dataset.elementId, 10) + 1;
|
||||
}
|
||||
};
|
||||
|
||||
const addElement = () => {
|
||||
let id = nextElementId();
|
||||
let row = document.createElement('tr');
|
||||
row.dataset.elementId = id;
|
||||
|
||||
|
||||
let textCol = document.createElement('td');
|
||||
textCol.classList.add('text');
|
||||
let textInput = document.createElement('input');
|
||||
textInput.type = "text";
|
||||
textInput.addEventListener('input', render);
|
||||
textCol.appendChild(textInput);
|
||||
row.appendChild(textCol);
|
||||
|
||||
{
|
||||
let sizeCol = document.createElement('td');
|
||||
sizeCol.classList.add('size');
|
||||
let sizeInput = document.createElement('input');
|
||||
sizeInput.addEventListener('input', render);
|
||||
sizeInput.type = "number";
|
||||
sizeInput.value = defaultFontSize.toString();
|
||||
sizeCol.appendChild(document.createTextNode("Front size"))
|
||||
sizeCol.appendChild(sizeInput);
|
||||
row.appendChild(sizeCol);
|
||||
}
|
||||
|
||||
{
|
||||
let posCol = document.createElement('td');
|
||||
posCol.classList.add('pos');
|
||||
let posInputX = document.createElement('input');
|
||||
posInputX.addEventListener('input', render);
|
||||
posInputX.type = "number";
|
||||
posInputX.value = "2";
|
||||
posInputX.classList.add('pos_x');
|
||||
let posInputY = document.createElement('input');
|
||||
posInputY.addEventListener('input', render);
|
||||
posInputY.type = "number";
|
||||
posInputY.value = "2";
|
||||
posInputY.classList.add('pos_y');
|
||||
posCol.appendChild(document.createTextNode("Position"))
|
||||
posCol.appendChild(posInputX);
|
||||
posCol.appendChild(posInputY);
|
||||
row.appendChild(posCol);
|
||||
}
|
||||
|
||||
{
|
||||
let removeCol = document.createElement('td');
|
||||
removeCol.classList.add('delete');
|
||||
let removeInput = document.createElement('input');
|
||||
removeInput.type = "button";
|
||||
removeInput.value = "×";
|
||||
removeInput.addEventListener('click', removeElement);
|
||||
removeCol.appendChild(removeInput);
|
||||
row.appendChild(removeCol);
|
||||
}
|
||||
|
||||
elementsTableBody.appendChild(row);
|
||||
|
||||
textInput.focus();
|
||||
};
|
||||
|
||||
const removeElement = (event) => {
|
||||
let row = event.target.parentElement.parentElement;
|
||||
row.remove();
|
||||
render();
|
||||
};
|
||||
|
||||
const getElements = () => {
|
||||
let rows = elementsTableBody.getElementsByTagName('tr');
|
||||
let elements = [];
|
||||
for (let row of rows) {
|
||||
elements.push({
|
||||
text: row.querySelector('.text input').value,
|
||||
size: parseInt(row.querySelector('.size input').value, 10),
|
||||
x: parseInt(row.querySelector('.pos_x').value, 10),
|
||||
y: parseInt(row.querySelector('.pos_y').value, 10),
|
||||
});
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
const render = () => {
|
||||
let elements = getElements();
|
||||
let width = preview.width;
|
||||
let height = preview.height;
|
||||
renderCtx.fillStyle = backgroundColor;
|
||||
renderCtx.fillRect(0, 0, width, height);
|
||||
|
||||
renderCtx.fillStyle = textColor;
|
||||
for (let element of elements) {
|
||||
renderCtx.font = `${element.size}px serif`;
|
||||
renderCtx.fillText(element.text, element.x, height - element.y);
|
||||
}
|
||||
}
|
||||
|
||||
const resize = () => {
|
||||
let width = parseInt(widthInput.value, 10);
|
||||
const pxPerMM = preview.height / tapeWidthMM;
|
||||
if (widthUnit.value === "mm") {
|
||||
preview.width = width * pxPerMM;
|
||||
} else {
|
||||
preview.width = width;
|
||||
}
|
||||
|
||||
render()
|
||||
};
|
||||
|
||||
addButton.addEventListener('click', addElement);
|
||||
widthInput.addEventListener('input', resize);
|
||||
|
||||
widthUnit.addEventListener('change', () => {
|
||||
const pxPerMM = preview.height / tapeWidthMM;
|
||||
if (widthUnit.value === "mm") {
|
||||
widthInput.value = (preview.width / pxPerMM).toFixed(0);
|
||||
} else {
|
||||
widthInput.value = preview.width;
|
||||
}
|
||||
});
|
||||
|
||||
const apiRoot = "";
|
||||
|
||||
fetch(apiRoot + '/status')
|
||||
.then(res => res.json())
|
||||
/** @param {{pixel_width: number, media_width: number, margin_width: number, tape_color: string, text_color: string}} status */
|
||||
.then(status => {
|
||||
preview.height = status.pixel_width;
|
||||
defaultFontSize = status.pixel_width;
|
||||
backgroundColor = status.tape_color;
|
||||
textColor = status.text_color;
|
||||
tapeWidthMM = status.media_width;
|
||||
render();
|
||||
addElement();
|
||||
})
|
||||
22
web/style.css
Normal file
22
web/style.css
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
:root {
|
||||
--background-color: #959595;
|
||||
--font-color: #000000;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background-color: #1e1e1e;
|
||||
--font-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
body, input {
|
||||
background: var(--background-color);
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
#elements {
|
||||
.pos input {
|
||||
width: 60px;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue