diff --git a/src/components/PreviewPanel.tsx b/src/components/PreviewPanel.tsx index f4066ae..00dc48b 100644 --- a/src/components/PreviewPanel.tsx +++ b/src/components/PreviewPanel.tsx @@ -13,6 +13,23 @@ import { useEffect, useMemo, useState } from 'react'; export type PreviewDoc = { art: 'brief' | 'umschlag'; svg: string }; +// Vorschau-Optik „Kugelschreiber" – IDENTISCH zu Directus (neuauftrag): blaue +// Tinte, etwas dicker (1.4) + dezenter Wobble (feTurbulence/Displacement) für die +// typische Kuli-Linie. non-scaling-stroke bleibt (Glyphen skalieren per transform), +// weißer Grund. Nur Anzeige/Download – die an die Produktion gehenden SVGs bleiben +// schwarz. Inline-SVGs brauchen eine EINDEUTIGE Filter-ID pro Dokument. +let inkSeq = 0; +const inkify = (svg: string): string => { + if (typeof svg !== 'string') return svg; + const id = `skink${inkSeq++}`; + return svg + .replace(/stroke="#0{3,6}"/gi, 'stroke="#1a2a6c" stroke-opacity="0.95"') + .replace(/stroke-width="0\.6"/gi, 'stroke-width="1.4"') + .replace(/(]*>)/i, `$1`) + .replace(/(]*fill="#FFFFFF"[^>]*\/>)/i, `$1`) + .replace(/<\/svg>\s*$/i, ''); +}; + /** Ein Empfänger-Dokument: Schriftstück + optional zugehöriger Umschlag. */ type Gruppe = { brief?: PreviewDoc; umschlag?: PreviewDoc }; @@ -81,10 +98,12 @@ export default function PreviewPanel({ const m = zoomSvg.match(/viewBox="0 0 ([\d.]+) ([\d.]+)"/); const w = Math.round(m ? Number(m[1]) : 794); const h = Math.round(m ? Number(m[2]) : 1123); - const scale = 2; // für ein scharfes Musterbild - // Gespeicherte Vorschau in Kugelschreiber-Blau (wie die Anzeige); die - // an die Produktion gehenden SVGs bleiben davon unberührt (schwarz). - const inkSvg = zoomSvg.replace(/stroke="#0{3,6}"/gi, 'stroke="#1a2a6c"'); + // Natürliche Größe (nicht 2×): non-scaling-stroke wirkt konstant in + // Gerätepixeln – bei 2× würde die Linie relativ dünn. So sieht das PNG aus + // wie die Großansicht. Gespeicherte Vorschau in Kuli-Optik (wie Anzeige); + // die an die Produktion gehenden SVGs bleiben schwarz. + const scale = 1; + const inkSvg = inkify(zoomSvg); const url = URL.createObjectURL(new Blob([inkSvg], { type: 'image/svg+xml;charset=utf-8' })); const img = new Image(); img.onload = () => { @@ -142,7 +161,7 @@ export default function PreviewPanel({ >
{label}
{/* Das SVG stammt aus unserer eigenen Generierung, nicht aus Nutzereingaben. */} -
+
); @@ -199,7 +218,7 @@ export default function PreviewPanel({ aria-label="Vergrößerte Vorschau">
e.stopPropagation()} - dangerouslySetInnerHTML={{ __html: zoomSvg }} /> + dangerouslySetInnerHTML={{ __html: inkify(zoomSvg) }} />