/*! * Tectum * Copyright © 2026 Machiel Heinen. * Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming. * Zie LICENTIE.md. */ window.PdfSheet = (() => { const COLORS = { RED: [190, 25, 25], BLUE: [25, 50, 180], BLACK: [0, 0, 0], GREY: [130, 130, 130] }; const PROJECT_DOM_IDS = { naam: 'inp-proj-naam', plaats: 'inp-proj-plaats', straat: 'inp-proj-straat', nummer: 'inp-proj-nummer', tekenaar: 'inp-proj-tekenaar', titel: 'inp-proj-titel', element: 'inp-proj-element', opmerking: 'inp-proj-opmerking' }; // generate() is synchroon: afbeeldingen vooraf laden met preloadImage. const imageCache = {}; function preloadImage(url) { if (!url || url in imageCache || typeof Image === 'undefined' || typeof document === 'undefined') return; imageCache[url] = null; const img = new Image(); img.onload = () => { try { const c = document.createElement('canvas'); c.width = img.naturalWidth; c.height = img.naturalHeight; c.getContext('2d').drawImage(img, 0, 0); imageCache[url] = c.toDataURL('image/png'); } catch (e) { } }; img.src = url; } const imageData = (url) => (url && imageCache[url]) || null; function createDoc() { const { jsPDF } = window.jspdf; return new jsPDF({ orientation: 'landscape', unit: 'mm', format: 'a3' }); } function readProjectFromDom() { const project = {}; Object.entries(PROJECT_DOM_IDS).forEach(([key, id]) => { const el = document.getElementById(id); project[key] = (el && el.value) || ''; }); return project; } const DIM_TICK = 1.5; function dimLine(doc, x1, y1, x2, y2) { doc.line(x1, y1, x2, y2); const dx = x2 - x1, dy = y2 - y1; const len = Math.hypot(dx, dy) || 1; const tx = (-dy / len) * (DIM_TICK / 2), ty = (dx / len) * (DIM_TICK / 2); doc.line(x1 - tx, y1 - ty, x1 + tx, y1 + ty); doc.line(x2 - tx, y2 - ty, x2 + tx, y2 + ty); } function titleBlock(doc, project, opts) { const { BLACK, GREY } = COLORS; const p = project || {}; const o = opts || {}; const tbW = 118, tbH = 36; const tbX0 = 290, tbY0 = 289 - tbH; doc.setDrawColor(...BLACK); doc.setLineWidth(0.25); doc.rect(tbX0, tbY0, tbW, tbH, 'S'); const today = new Date().toLocaleDateString('nl-NL'); const columns = [ [['Projectnaam:', p.naam], ['Plaats:', p.plaats], ['Straat:', p.straat], ['Projectnummer:', p.nummer], ['Tekenaar:', p.tekenaar]], [['Titel:', o.titel], ['Element nummer:', o.element], ['Datum getekend:', today], ['Schaal:', '1:1'], ['Opmerking:', p.opmerking]] ]; const colW = tbW / 2, labelW = 19; doc.setFontSize(6.2); columns.forEach((rows, c) => { const x = tbX0 + 3 + c * colW; let rowY = tbY0 + 5; rows.forEach(([label, value]) => { doc.setTextColor(...GREY); doc.text(label, x, rowY); doc.setTextColor(...BLACK); const text = String(value || '-'); doc.text(doc.splitTextToSize(text, colW - labelW - 5)[0], x + labelW, rowY); rowY += 4.2; }); }); const stripY = tbY0 + 25; doc.setDrawColor(...GREY); doc.setLineWidth(0.15); doc.line(tbX0, stripY, tbX0 + tbW, stripY); if (o.blad) { doc.setTextColor(...GREY); doc.setFontSize(6); doc.text('Blad ' + o.blad, tbX0 + 3, tbY0 + tbH - 3.5); } const logoH = 7.5, logoW = logoH * (window.TECTUM_LOGO ? window.TECTUM_LOGO.aspect : 4.55); if (window.TECTUM_LOGO) { doc.addImage(window.TECTUM_LOGO.png, 'PNG', tbX0 + tbW - 3 - logoW, tbY0 + tbH - 2 - logoH, logoW, logoH, 'tectum-logo', 'FAST'); // alias: logo 1x in het bestand } else { doc.setTextColor(...GREY); doc.setFontSize(6); doc.text('Van Emous Mantelzorgwoningen', tbX0 + tbW - 3, tbY0 + tbH - 3.5, { align: 'right' }); } } function table(doc, x, y, colX, headers, rows, opts) { const { BLACK, GREY } = COLORS; const o = opts || {}; const rowH = o.rowH || 4.3; doc.setTextColor(...BLACK); if (o.title) { doc.setFontSize(o.titleSize || 9); doc.text(o.title, x, y); y += 6; } doc.setFontSize(o.fontSize || 6.5); headers.forEach((h, i) => doc.text(h, x + colX[i], y)); y += 1.5; doc.setDrawColor(...GREY); doc.setLineWidth(0.15); doc.line(x, y, x + colX[colX.length - 1] + (o.lastColW || 14), y); y += 4; rows.forEach(r => { if (o.maxY && y > o.maxY) return; r.forEach((v, i) => doc.text(String(v), x + colX[i], y, i > 0 && o.alignRight ? { align: 'right' } : undefined)); y += rowH; }); return y; } return { COLORS, preloadImage, imageData, createDoc, readProjectFromDom, dimLine, titleBlock, table }; })();