feat: add crop marks variant for print finishing
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 24s
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🧪 QA (push) Has been cancelled
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 24s
Build & Deploy / 🏗️ Build (push) Has been cancelled
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
Build & Deploy / 🧪 QA (push) Has been cancelled
This commit is contained in:
@@ -48,12 +48,12 @@ export interface PDFBusinessCardProps {
|
||||
variant?: 'blue' | 'white' | 'black';
|
||||
isViaprinto?: boolean;
|
||||
withTruck?: boolean;
|
||||
withCropMarks?: boolean;
|
||||
}
|
||||
|
||||
// Die Buchstaben K, L, Z im SVG (inklusive dem kleinen Stück vom Z oben links)
|
||||
export const KLZ_PATHS = [25, 26, 27, 28, 29];
|
||||
|
||||
// Mintel Aesthetics Colors - EXACT PROD COLORS
|
||||
const COLORS = {
|
||||
primary: '#011dff', // Brand Royal Blue
|
||||
blue: '#000a66',
|
||||
@@ -66,6 +66,98 @@ const COLORS = {
|
||||
lightGray: '#f8f9fa',
|
||||
};
|
||||
|
||||
const CropMarks = () => (
|
||||
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, zIndex: 9999 }}>
|
||||
{/* Top Left */}
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '13mm',
|
||||
top: '0mm',
|
||||
width: '0.25pt',
|
||||
height: '10mm',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '0mm',
|
||||
top: '13mm',
|
||||
width: '10mm',
|
||||
height: '0.25pt',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Top Right */}
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '13mm',
|
||||
top: '0mm',
|
||||
width: '0.25pt',
|
||||
height: '10mm',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '0mm',
|
||||
top: '13mm',
|
||||
width: '10mm',
|
||||
height: '0.25pt',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Bottom Left */}
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '13mm',
|
||||
bottom: '0mm',
|
||||
width: '0.25pt',
|
||||
height: '10mm',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '0mm',
|
||||
bottom: '13mm',
|
||||
width: '10mm',
|
||||
height: '0.25pt',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Bottom Right */}
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '13mm',
|
||||
bottom: '0mm',
|
||||
width: '0.25pt',
|
||||
height: '10mm',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '0mm',
|
||||
bottom: '13mm',
|
||||
width: '10mm',
|
||||
height: '0.25pt',
|
||||
backgroundColor: '#000',
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
pageBleed: {
|
||||
width: '91mm',
|
||||
@@ -694,6 +786,7 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
|
||||
variant = 'blue',
|
||||
isViaprinto = false,
|
||||
withTruck = true,
|
||||
withCropMarks = false,
|
||||
}) => {
|
||||
const isWhiteVariant = variant === 'white' || variant === 'black';
|
||||
|
||||
@@ -730,6 +823,26 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
|
||||
? path.join(process.cwd(), 'public', 'media', 'cable_drums_truck.png')
|
||||
: path.join(process.cwd(), 'public', 'cable_drums_bg.png');
|
||||
|
||||
const renderPageWrapper = (children: React.ReactNode, bleedStyle: any) => {
|
||||
if (withCropMarks) {
|
||||
return (
|
||||
<Page size={[315, 230]} style={{ backgroundColor: '#ffffff' }}>
|
||||
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
||||
<CropMarks />
|
||||
<View style={[bleedStyle, { overflow: 'hidden', position: 'relative' }]}>
|
||||
{children}
|
||||
</View>
|
||||
</View>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Page size={[258, 173]} style={bleedStyle}>
|
||||
{children}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Document
|
||||
title={`Business Card - ${person.name}`}
|
||||
@@ -737,86 +850,85 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
|
||||
creator="KLZ Print Engine"
|
||||
>
|
||||
{/* VORDERSEITE (Blue page with logo, truck and tagline) */}
|
||||
<Page
|
||||
size={[258, 173]}
|
||||
style={[styles.pageBleed, isWhiteVariant && { backgroundColor: '#ffffff' }]}
|
||||
>
|
||||
{withTruck && (
|
||||
<View style={styles.truckWrapper}>
|
||||
<TruckBlueprint
|
||||
style={styles.frontBackgroundImage}
|
||||
opacity={isWhiteVariant ? 0.2 : 0.25}
|
||||
backgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.frontFooterArea}>
|
||||
<Text style={[styles.frontTaglineBar, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Von 0,6/1,0 kV bis 64/110 kV
|
||||
</Text>
|
||||
<View style={styles.frontIconsGroup}>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconLowVoltage
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
{renderPageWrapper(
|
||||
<>
|
||||
{withTruck && (
|
||||
<View style={styles.truckWrapper}>
|
||||
<TruckBlueprint
|
||||
style={styles.frontBackgroundImage}
|
||||
opacity={isWhiteVariant ? 0.2 : 0.25}
|
||||
backgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Niederspannung
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconMediumVoltage
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Mittelspannung
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconHighVoltage
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Hochspannung
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconSolar
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Solar
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.frontContainer}>
|
||||
{/* Base Logo: text is white, truck is green. Fill KLZ background to hide truck, keep outline white */}
|
||||
<VectorLogo
|
||||
paths={getFrontLogoPaths()}
|
||||
style={styles.frontLogo}
|
||||
solidPaths={KLZ_PATHS}
|
||||
solidBackgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
|
||||
/>
|
||||
|
||||
{/* Letterpress Mask Layer: We use #ff00fe as a marker color. Only the "KLZ" letters! */}
|
||||
{isViaprinto && (
|
||||
<VectorLogo
|
||||
paths={getFrontLogoPaths().filter((_, i) => KLZ_PATHS.includes(i))}
|
||||
style={[styles.frontLogo, { position: 'absolute' }]}
|
||||
overrideColor="#ff00fe"
|
||||
solidPaths={KLZ_PATHS.map((_, i) => i)}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</Page>
|
||||
<View style={styles.frontFooterArea}>
|
||||
<Text style={[styles.frontTaglineBar, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Von 0,6/1,0 kV bis 64/110 kV
|
||||
</Text>
|
||||
<View style={styles.frontIconsGroup}>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconLowVoltage
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Niederspannung
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconMediumVoltage
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Mittelspannung
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconHighVoltage
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Hochspannung
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* VORDERSEITE (White page with contact info) */}
|
||||
<Page size={[258, 173]} style={styles.pageBleedBack}>
|
||||
<View style={styles.frontBrandIconWrapper}>
|
||||
<IconSolar
|
||||
style={styles.frontBrandIcon}
|
||||
color={isWhiteVariant ? COLORS.black : 'white'}
|
||||
/>
|
||||
<Text style={[styles.frontBrandText, isWhiteVariant && { color: COLORS.black }]}>
|
||||
Solar
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.frontContainer}>
|
||||
{/* Base Logo: text is white, truck is green. Fill KLZ background to hide truck, keep outline white */}
|
||||
<VectorLogo
|
||||
paths={getFrontLogoPaths()}
|
||||
style={styles.frontLogo}
|
||||
solidPaths={KLZ_PATHS}
|
||||
solidBackgroundColor={isWhiteVariant ? '#ffffff' : '#011dff'}
|
||||
/>
|
||||
|
||||
{/* Letterpress Mask Layer: We use #ff00fe as a marker color. Only the "KLZ" letters! */}
|
||||
{isViaprinto && (
|
||||
<VectorLogo
|
||||
paths={getFrontLogoPaths().filter((_, i) => KLZ_PATHS.includes(i))}
|
||||
style={[styles.frontLogo, { position: 'absolute' }]}
|
||||
overrideColor="#ff00fe"
|
||||
solidPaths={KLZ_PATHS.map((_, i) => i)}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</>,
|
||||
[styles.pageBleed, isWhiteVariant && { backgroundColor: '#ffffff' }],
|
||||
)}
|
||||
|
||||
{renderPageWrapper(
|
||||
<View style={styles.backContainer}>
|
||||
<View style={styles.backHeader}>
|
||||
<VectorLogo
|
||||
@@ -876,14 +988,15 @@ export const PDFBusinessCard: React.FC<PDFBusinessCardProps> = ({
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.addressFooter}>
|
||||
<Text style={styles.addressFooterText}>
|
||||
KLZ Vertriebs GmbH · Raiffeisenstraße 22 · 73630 Remshalden
|
||||
</Text>
|
||||
</View>
|
||||
</Page>
|
||||
<View style={styles.addressFooter}>
|
||||
<Text style={styles.addressFooterText}>
|
||||
KLZ Vertriebs GmbH · Raiffeisenstraße 22 · 73630 Remshalden
|
||||
</Text>
|
||||
</View>
|
||||
</View>,
|
||||
styles.pageBleed,
|
||||
)}
|
||||
</Document>
|
||||
);
|
||||
};
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
public/downloads/business-cards/test_page_1_crop.png
Normal file
BIN
public/downloads/business-cards/test_page_1_crop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -143,7 +143,26 @@ END:VCARD`;
|
||||
const gsNoTruckCommand = `gs -dNoOutputFonts -sDEVICE=pdfwrite -o "${finalNoTruckPath}" "${tempNoTruckPath}"`;
|
||||
execSync(gsNoTruckCommand, { stdio: 'inherit' });
|
||||
fs.unlinkSync(tempNoTruckPath);
|
||||
console.log(`✓ No Truck Print File generated: ${noTruckFileName}`);
|
||||
// 4. CROP MARKS PDF (RGB)
|
||||
console.log(`- Rendering Crop Marks Variant (RGB)...`);
|
||||
const cropMarksFileName = `KLZ_Visitenkarte_${safeName}_CropMarks.pdf`;
|
||||
const tempCropMarksPath = path.join(CONFIG.outputDir, `temp_${cropMarksFileName}`);
|
||||
const finalCropMarksPath = path.join(CONFIG.outputDir, cropMarksFileName);
|
||||
|
||||
buffer = await renderToBuffer(
|
||||
React.createElement(PDFBusinessCard, {
|
||||
person,
|
||||
qrCodeDataUrl,
|
||||
variant: 'blue',
|
||||
isViaprinto: false,
|
||||
withCropMarks: true,
|
||||
}),
|
||||
);
|
||||
fs.writeFileSync(tempCropMarksPath, buffer);
|
||||
const gsCropMarksCommand = `gs -dNoOutputFonts -sDEVICE=pdfwrite -o "${finalCropMarksPath}" "${tempCropMarksPath}"`;
|
||||
execSync(gsCropMarksCommand, { stdio: 'inherit' });
|
||||
fs.unlinkSync(tempCropMarksPath);
|
||||
console.log(`✓ Crop Marks Print File generated: ${cropMarksFileName}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user