mirror of
https://codeberg.org/icewind/ptouch-api.git
synced 2026-06-03 10:54:07 +02:00
image support
This commit is contained in:
parent
88e6fa3244
commit
25f9e9b0a1
3 changed files with 103 additions and 29 deletions
|
|
@ -14,7 +14,8 @@
|
|||
</tbody>
|
||||
<tfoot>
|
||||
<td>
|
||||
<input type="button" value="Add Text" id="add"/>
|
||||
<input type="button" value="Add Text" id="add-text"/>
|
||||
<input type="button" value="Add Image" id="add-image"/>
|
||||
</td>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
|
|
|||
123
web/label.js
123
web/label.js
|
|
@ -3,7 +3,8 @@ const elementsTable = document.getElementById('elements');
|
|||
const preview = document.getElementById('preview');
|
||||
const renderCtx = preview.getContext("2d");
|
||||
const elementsTableBody = elementsTable.getElementsByTagName('tbody')[0];
|
||||
const addButton = document.getElementById('add');
|
||||
const addTextButton = document.getElementById('add-text');
|
||||
const addImageButton = document.getElementById('add-image');
|
||||
/** @type HTMLInputElement printButton */
|
||||
const printButton = document.getElementById('print');
|
||||
const widthInput = document.getElementById('canvas-width');
|
||||
|
|
@ -14,6 +15,8 @@ let defaultFontSize = 24;
|
|||
let backgroundColor = "white";
|
||||
let textColor = "white";
|
||||
|
||||
let images = new Map();
|
||||
|
||||
const nextElementId = () => {
|
||||
let rows = elementsTableBody.getElementsByTagName('tr');
|
||||
if (rows.length === 0) {
|
||||
|
|
@ -23,20 +26,7 @@ const nextElementId = () => {
|
|||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
const addElementControls = (row) => {
|
||||
{
|
||||
let sizeCol = document.createElement('td');
|
||||
sizeCol.classList.add('size');
|
||||
|
|
@ -44,7 +34,7 @@ const addElement = () => {
|
|||
sizeInput.addEventListener('input', render);
|
||||
sizeInput.type = "number";
|
||||
sizeInput.value = defaultFontSize.toString();
|
||||
sizeCol.appendChild(document.createTextNode("Front size"))
|
||||
sizeCol.appendChild(document.createTextNode("Size"))
|
||||
sizeCol.appendChild(sizeInput);
|
||||
row.appendChild(sizeCol);
|
||||
}
|
||||
|
|
@ -55,12 +45,12 @@ const addElement = () => {
|
|||
let posInputX = document.createElement('input');
|
||||
posInputX.addEventListener('input', render);
|
||||
posInputX.type = "number";
|
||||
posInputX.value = "2";
|
||||
posInputX.value = "0";
|
||||
posInputX.classList.add('pos_x');
|
||||
let posInputY = document.createElement('input');
|
||||
posInputY.addEventListener('input', render);
|
||||
posInputY.type = "number";
|
||||
posInputY.value = "2";
|
||||
posInputY.value = "0";
|
||||
posInputY.classList.add('pos_y');
|
||||
posCol.appendChild(document.createTextNode("Position"))
|
||||
posCol.appendChild(posInputX);
|
||||
|
|
@ -78,15 +68,67 @@ const addElement = () => {
|
|||
removeCol.appendChild(removeInput);
|
||||
row.appendChild(removeCol);
|
||||
}
|
||||
}
|
||||
|
||||
const addTextElement = () => {
|
||||
let id = nextElementId();
|
||||
let row = document.createElement('tr');
|
||||
row.dataset.elementId = id;
|
||||
row.dataset.type = 'text';
|
||||
|
||||
|
||||
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);
|
||||
|
||||
addElementControls(row);
|
||||
elementsTableBody.appendChild(row);
|
||||
|
||||
textInput.focus();
|
||||
};
|
||||
|
||||
const loadImage = (event) => {
|
||||
/** @type HTMLInputElement input */
|
||||
const input = event.target;
|
||||
const row = event.target.parentElement.parentElement;
|
||||
let file = input.files[0];
|
||||
if (file.type.startsWith('image')) {
|
||||
let image = row.getElementsByTagName('img')[0];
|
||||
image.addEventListener('load', render);
|
||||
image.src = URL.createObjectURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const addImageElement = () => {
|
||||
let id = nextElementId();
|
||||
let row = document.createElement('tr');
|
||||
row.dataset.elementId = id;
|
||||
row.dataset.type = 'image';
|
||||
|
||||
|
||||
let imageCol = document.createElement('td');
|
||||
imageCol.classList.add('image');
|
||||
let imageInput = document.createElement('input');
|
||||
imageInput.type = 'file';
|
||||
imageInput.addEventListener('change', loadImage);
|
||||
let imageThumb = document.createElement('img');
|
||||
imageCol.appendChild(imageInput);
|
||||
imageCol.appendChild(imageThumb);
|
||||
row.appendChild(imageCol);
|
||||
|
||||
addElementControls(row);
|
||||
elementsTableBody.appendChild(row);
|
||||
};
|
||||
|
||||
const removeElement = (event) => {
|
||||
let row = event.target.parentElement.parentElement;
|
||||
let id = row.dataset.elementId;
|
||||
row.remove();
|
||||
images.delete(id);
|
||||
render();
|
||||
};
|
||||
|
||||
|
|
@ -94,12 +136,23 @@ 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),
|
||||
});
|
||||
if (row.dataset.type === 'text') {
|
||||
elements.push({
|
||||
type: 'text',
|
||||
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),
|
||||
});
|
||||
} else if (row.dataset.type === 'image') {
|
||||
elements.push({
|
||||
type: 'image',
|
||||
image: row.getElementsByTagName('img')[0],
|
||||
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;
|
||||
}
|
||||
|
|
@ -108,13 +161,26 @@ const render = () => {
|
|||
let elements = getElements();
|
||||
let width = preview.width;
|
||||
let height = preview.height;
|
||||
renderCtx.filter = '';
|
||||
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);
|
||||
if (element.type === 'text') {
|
||||
renderCtx.filter = '';
|
||||
renderCtx.font = `${element.size}px serif`;
|
||||
let textSize = renderCtx.measureText(element.text);
|
||||
let textHeight = textSize.fontBoundingBoxAscent - textSize.emHeightDescent;
|
||||
renderCtx.fillText(element.text, element.x, element.y + textHeight);
|
||||
} else if (element.type === 'image' && element.image.naturalWidth > 0) {
|
||||
renderCtx.filter = 'grayscale() saturate(0%) brightness(70%) contrast(1000%)';
|
||||
if (textColor === 'white') {
|
||||
renderCtx.filter = renderCtx.filter + ' invert()';
|
||||
}
|
||||
let ratio = element.image.naturalWidth / element.image.naturalHeight;
|
||||
renderCtx.drawImage(element.image, element.x, element.y, element.size * ratio, element.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +209,8 @@ const print = () => {
|
|||
}, 'image/png');
|
||||
};
|
||||
|
||||
addButton.addEventListener('click', addElement);
|
||||
addTextButton.addEventListener('click', addTextElement);
|
||||
addImageButton.addEventListener('click', addImageElement);
|
||||
printButton.addEventListener('click', print);
|
||||
widthInput.addEventListener('input', resize);
|
||||
|
||||
|
|
@ -168,5 +235,5 @@ fetch(apiRoot + '/status')
|
|||
textColor = status.text_color;
|
||||
tapeWidthMM = status.media_width;
|
||||
render();
|
||||
addElement();
|
||||
addTextElement();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
:root {
|
||||
--background-color: #1e1e1e;
|
||||
--font-color: #fff;
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -19,4 +20,9 @@ body, input {
|
|||
.pos input {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.image img {
|
||||
height: 32px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue