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"), tapeInfo: document.getElementById("mobileTapeInfo"), tapeInfoType: document.getElementById("mobileTapeInfoType"), tapePrintableWidth: document.getElementById("mobileTapePrintableWidth"), tapeBgSwatch: document.getElementById("mobileTapeBgSwatch"), tapeBgText: document.getElementById("mobileTapeBgText"), tapeTextSwatch: document.getElementById("mobileTapeTextSwatch"), tapeTextText: document.getElementById("mobileTapeTextText"), 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 updateTapeInfo(info) { fields.tapeInfo.hidden = !info; if (!info) return; const media = info.mediaType?.name || "Unbekannt"; const bg = info.tapeColor || { name: "Unbekannt", css: "#d1d5db" }; const text = info.textColor || { name: "Unbekannt", css: "#111111" }; fields.tapeInfoType.textContent = `${info.width} mm ยท ${media}${info.mediaType?.code ? ` (${info.mediaType.code})` : ""}`; fields.tapePrintableWidth.textContent = info.printableWidthPx ? `${info.printableWidthPx} px` : "-"; fields.tapeBgText.textContent = `${bg.name}${bg.code ? ` (${bg.code})` : ""}`; fields.tapeBgSwatch.style.background = bg.css; fields.tapeTextText.textContent = `${text.name}${text.code ? ` (${text.code})` : ""}`; fields.tapeTextSwatch.style.background = text.css; } 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); updateTapeInfo(payload); const bg = payload.tapeColor?.name ? `, ${payload.tapeColor.name}` : ""; const text = payload.textColor?.name ? ` / ${payload.textColor.name}` : ""; setMessage(`Band erkannt: ${payload.width} mm${bg}${text}`, "success"); }); ["text", "font", "margin", "frame", "bold", "align", "tape"].forEach((name) => { fields[name].addEventListener("input", () => { mobileDesign(); }); }); mobileDesign();