Add mobile mode and print cut controls

This commit is contained in:
Mikei386
2026-06-22 06:46:52 +02:00
parent 7029ee9519
commit a6025eef47
10 changed files with 303 additions and 48 deletions
+44 -7
View File
@@ -1,4 +1,12 @@
const MM_TO_SCREEN = 6;
const PRINTABLE_TAPE_PX = {
3.5: 24,
6: 32,
9: 52,
12: 76,
18: 120,
24: 128,
};
const STORAGE_KEY = "ptouch-web-layout";
const state = {
@@ -10,6 +18,8 @@ const state = {
lengthMm: 70,
marginMm: 2,
orientation: "landscape",
cutMode: "auto",
halfcut: "on",
objects: [],
},
};
@@ -22,6 +32,8 @@ const controls = {
tapeWidth: document.getElementById("tapeWidth"),
lengthMm: document.getElementById("lengthMm"),
marginMm: document.getElementById("marginMm"),
cutMode: document.getElementById("cutMode"),
halfcut: document.getElementById("halfcut"),
copies: document.getElementById("copies"),
zoomLabel: document.getElementById("zoomLabel"),
previewImage: document.getElementById("previewImage"),
@@ -64,6 +76,11 @@ function pxToMm(v) {
return v / scale();
}
function printablePxPerMm() {
const tape = Number(state.design.tapeWidthMm);
return (PRINTABLE_TAPE_PX[tape] || (tape * 180) / 25.4) / tape;
}
function selected() {
return state.design.objects.find((obj) => obj.id === state.selectedId) || null;
}
@@ -77,6 +94,8 @@ function syncDesignControls() {
state.design.tapeWidthMm = Number(controls.tapeWidth.value);
state.design.lengthMm = Number(controls.lengthMm.value);
state.design.marginMm = Number(controls.marginMm.value);
state.design.cutMode = controls.cutMode.value;
state.design.halfcut = controls.halfcut.value;
state.design.orientation = document.querySelector("input[name='orientation']:checked").value;
}
@@ -84,6 +103,8 @@ function applyDesignControls() {
controls.tapeWidth.value = state.design.tapeWidthMm;
controls.lengthMm.value = state.design.lengthMm;
controls.marginMm.value = state.design.marginMm;
controls.cutMode.value = state.design.cutMode || "auto";
controls.halfcut.value = state.design.halfcut || "on";
document.querySelector(`input[name='orientation'][value='${state.design.orientation}']`).checked = true;
}
@@ -114,21 +135,25 @@ function drawRulers() {
function drawTextObject(obj) {
ctx.save();
ctx.fillStyle = "#000";
ctx.font = `${obj.bold ? "700 " : ""}${mmToPx(obj.fontSizeMm || 5)}px system-ui, sans-serif`;
ctx.textBaseline = "middle";
ctx.textAlign = obj.align || "left";
const x = mmToPx(obj.x);
const y = mmToPx(obj.y);
const w = mmToPx(obj.w);
const h = mmToPx(obj.h);
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.clip();
ctx.fillStyle = "#000";
const fontPx = (obj.fontSizeMm || 5) * printablePxPerMm() * state.zoom;
ctx.font = `${obj.bold ? "700 " : ""}${fontPx}px DejaVu Sans, Arial, system-ui, sans-serif`;
ctx.textBaseline = "middle";
ctx.textAlign = obj.align || "left";
const lines = String(obj.text || "").split("\n");
const lineHeight = mmToPx((obj.fontSizeMm || 5) * 1.15);
const lineHeight = fontPx * 1.15;
const total = lineHeight * lines.length;
let cy = y + h / 2 - total / 2 + lineHeight / 2;
const tx = obj.align === "center" ? x + w / 2 : obj.align === "right" ? x + w : x;
for (const line of lines) {
ctx.fillText(line, tx, cy, w);
ctx.fillText(line, tx, cy);
cy += lineHeight;
}
ctx.restore();
@@ -212,6 +237,18 @@ function draw() {
ctx.setLineDash([]);
for (const obj of state.design.objects) drawObject(obj);
if (state.design.cutMode === "cutmark" || state.design.cutMode === "cutmark-chain") {
ctx.strokeStyle = "#111";
ctx.setLineDash([4, 4]);
const x = canvas.width - mmToPx(1.5);
ctx.beginPath();
ctx.moveTo(x, 0);
ctx.lineTo(x, canvas.height);
ctx.stroke();
ctx.setLineDash([]);
}
drawRulers();
controls.zoomLabel.textContent = `${Math.round(state.zoom * 100)}%`;
updateProps();
@@ -376,7 +413,7 @@ window.addEventListener("keydown", (event) => {
}
});
["tapeWidth", "lengthMm", "marginMm"].forEach((id) => document.getElementById(id).addEventListener("input", draw));
["tapeWidth", "lengthMm", "marginMm", "cutMode", "halfcut"].forEach((id) => document.getElementById(id).addEventListener("input", draw));
document.querySelectorAll("input[name='orientation']").forEach((input) => input.addEventListener("change", draw));
Object.values(controls).forEach((control) => {
if (control && control.id && control.id.startsWith("prop")) control.addEventListener("input", applyProps);