diff --git a/src/components/PrintApp.tsx b/src/components/PrintApp.tsx index 9afa0fd..07315a3 100644 --- a/src/components/PrintApp.tsx +++ b/src/components/PrintApp.tsx @@ -35,6 +35,10 @@ interface Cell { const uid = () => (crypto.randomUUID ? crypto.randomUUID() : String(Math.random()).slice(2)); +/** Farbwerte aus fremden Vorlagen landen in style — nur echte Hex-Werte zulassen. */ +const safeColor = (v: unknown): string => + typeof v === 'string' && /^#[0-9a-fA-F]{6}$/.test(v) ? v : '#ffffff'; + /** Größter Ausschnitt im Zielverhältnis — füllt das Format aus, schneidet ab. */ function coverCrop(natW: number, natH: number, aspect: number, around?: CropRel): CropRel { const imgA = natW / natH; @@ -292,7 +296,7 @@ export default function PrintApp() { const apply = (cell: Cell, f: any): Cell => { const next = { ...cell, id: cell.id, sizeId: f.sizeId, customSize: f.customSize || '', landscape: !!f.landscape, count: f.count || 1, allowRotate: f.allowRotate !== false, - fit: (f.fit === 'contain' ? 'contain' : 'cover') as FitMode, bg: f.bg || '#ffffff' }; + fit: (f.fit === 'contain' ? 'contain' : 'cover') as FitMode, bg: safeColor(f.bg) }; const a = aspectOf(next); if (a) next.crop = baseCrop(next.natW, next.natH, a, next.fit, cell.crop); return next; }; @@ -405,6 +409,14 @@ export default function PrintApp() { : marks === 'grid' ? 'Durchgehende Hilfslinien über den ganzen Bogen — für Schneidelineal und Schlagschere.' : 'Keine Linien — Kanten selbst anlegen.'} + {marks === 'corner' && marginMm < markOff + markLen && ( +
Bei {marginMm} mm Rand ist außerhalb der Bilder kein Platz für die Marken — + sie werden abgeschnitten. Rand auf mindestens {Math.ceil(markOff + markLen)} mm setzen.
+ )} + {marks === 'grid' && new Set(ready.map((c) => { const s = sizeOfCell(c); return s ? `${s.w}x${s.h}` : ''; })).size > 1 && ( +
Durchgehende Linien passen nur zu einem Bildmaß. Bei gemischten Größen + werden sie unterbrochen — ein Schnitt über das ganze Blatt würde andere Bilder treffen. Besser Eckmarken.
+ )} {marks === 'corner' && (