const fields = { text: document.getElementById("mobileText"), tape: document.getElementById("mobileTape"), margin: document.getElementById("mobileMargin"), font: document.getElementById("mobileFont"), copies: document.getElementById("mobileCopies"), align: document.getElementById("mobileAlign"), bold: document.getElementById("mobileBold"), frame: document.getElementById("mobileFrame"), preview: document.getElementById("mobilePreview"), message: document.getElementById("mobileMessage"), }; function estimateTextLengthMm(text, fontSize, margin, frame) { const lines = String(text || " ").split("\n"); const longest = lines.reduce((max, line) => Math.max(max, line.length), 0); const textWidth = Math.max(8, longest * fontSize * 0.62); return Math.min(300, Math.max(20, Math.ceil(textWidth + margin * 2 + (frame ? 4 : 0)))); } function setMessage(text, type = "") { fields.message.textContent = text; fields.message.className = `message ${type}`; } function mobileDesign() { const tapeWidth = Number(fields.tape.value); const margin = Number(fields.margin.value); const text = fields.text.value.trim() || " "; const fontSize = Number(fields.font.value); const length = estimateTextLengthMm(text, fontSize, margin, fields.frame.checked); const objects = []; if (fields.frame.checked) { objects.push({ id: "frame", type: "shape", x: margin, y: margin, w: Math.max(2, length - margin * 2), h: Math.max(2, tapeWidth - margin * 2), lineMm: 0.25, fill: false, }); } objects.push({ id: "text", type: "text", x: margin + (fields.frame.checked ? 1 : 0), y: margin, w: Math.max(2, length - margin * 2 - (fields.frame.checked ? 2 : 0)), h: Math.max(2, tapeWidth - margin * 2), text, fontSizeMm: fontSize, bold: fields.bold.checked, align: fields.align.value, valign: "middle", }); return { tapeWidthMm: tapeWidth, lengthMm: length, autoLength: true, marginMm: margin, orientation: "landscape", cutMode: "auto", halfcut: "off", objects, }; } async function send(url) { setMessage("Rendere Etikett..."); const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ design: mobileDesign(), copies: Number(fields.copies.value) || 1 }), }); const payload = await response.json(); if (!payload.ok) { setMessage(payload.error || "Fehler", "error"); return; } fields.preview.src = `${payload.image}?t=${Date.now()}`; setMessage(payload.message || "Vorschau erstellt.", "success"); } document.getElementById("mobilePreviewBtn").addEventListener("click", () => send("/api/preview")); document.getElementById("mobilePrintBtn").addEventListener("click", () => send("/api/print")); document.getElementById("mobileDetect").addEventListener("click", async () => { setMessage("Erkenne Band..."); const response = await fetch("/api/tape-info"); const payload = await response.json(); if (!payload.ok) { setMessage(payload.error || "Band konnte nicht erkannt werden.", "error"); return; } fields.tape.value = String(payload.width); setMessage(`Band erkannt: ${payload.width} mm`, "success"); }); ["text", "font", "margin", "frame", "bold", "align", "tape"].forEach((name) => { fields[name].addEventListener("input", () => { mobileDesign(); }); }); mobileDesign();