Fine-tuning the layout
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
PUBLIC_GOOGLE_CLIENT_ID="YOUR_GOOGLE_CLIENT_ID_HERE"
|
||||
|
||||
# Face Detection Crop Configuration
|
||||
# Crop aspect ratio (width:height) - e.g., 1.0 for square, 1.5 for 3:2 ratio
|
||||
PUBLIC_CROP_RATIO=1.0
|
||||
|
||||
# Face offset from center (as percentage of crop dimensions)
|
||||
# Positive values move the face toward bottom-right, negative toward top-left
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { PHOTO_DIMENSIONS } from '$lib/pdfSettings';
|
||||
import { columnMapping, sheetData, currentStep, pictures, cropRects } from '$lib/stores';
|
||||
import { downloadDriveImage, isGoogleDriveUrl, createImageObjectUrl, ensureToken } from '$lib/google';
|
||||
import Navigator from './subcomponents/Navigator.svelte';
|
||||
@@ -339,7 +340,8 @@ async function createPreviewBlob(original: Blob, maxSide = 1200, quality = 0.85)
|
||||
const faceCenterX = (x1 + (x2 - x1) / 2) * scaleX;
|
||||
const faceCenterY = (y1 + (y2 - y1) / 2) * scaleY;
|
||||
|
||||
const cropRatio = parseFloat(env.PUBLIC_CROP_RATIO || '1.0');
|
||||
// Use the photo card aspect ratio from PDF settings (width / height)
|
||||
const cropRatio = PHOTO_DIMENSIONS.width / PHOTO_DIMENSIONS.height;
|
||||
const offsetX = parseFloat(env.PUBLIC_FACE_OFFSET_X || '0.0');
|
||||
const offsetY = parseFloat(env.PUBLIC_FACE_OFFSET_Y || '0.0');
|
||||
const cropScale = parseFloat(env.PUBLIC_CROP_SCALE || '2.5');
|
||||
|
||||
@@ -201,21 +201,21 @@
|
||||
let m = trimmed.match(/^(\d{4})[\/\-](\d{2})[\/\-](\d{2})$/);
|
||||
if (m) {
|
||||
const [, y, mo, d] = m;
|
||||
return `${d} ${mo} ${y.slice(-2)}`;
|
||||
return `${d} ${mo} ${y.slice(-2)}`;
|
||||
}
|
||||
|
||||
// DMY with separators: DD.MM.YYYY or DD/MM/YYYY or DD-MM-YYYY
|
||||
m = trimmed.match(/^(\d{2})[.\/-](\d{2})[.\/-](\d{4})$/);
|
||||
if (m) {
|
||||
const [, d, mo, y] = m;
|
||||
return `${d} ${mo} ${y.slice(-2)}`;
|
||||
return `${d} ${mo} ${y.slice(-2)}`;
|
||||
}
|
||||
|
||||
// DMY two-digit year: DD.MM.YY or DD/MM/YY or DD-MM-YY
|
||||
m = trimmed.match(/^(\d{2})[.\/-](\d{2})[.\/-](\d{2})$/);
|
||||
if (m) {
|
||||
const [, d, mo, y2] = m;
|
||||
return `${d} ${mo} ${y2}`;
|
||||
return `${d} ${mo} ${y2}`;
|
||||
}
|
||||
|
||||
// Try native Date parsing as a last resort
|
||||
@@ -224,7 +224,7 @@
|
||||
const dd = String(parsed.getDate()).padStart(2, '0');
|
||||
const mm = String(parsed.getMonth() + 1).padStart(2, '0');
|
||||
const yy = String(parsed.getFullYear()).slice(-2);
|
||||
return `${dd} ${mm} ${yy}`;
|
||||
return `${dd} ${mm} ${yy}`;
|
||||
}
|
||||
|
||||
// Handle plain numeric serials (e.g., Google/Excel serial days since 1899-12-30)
|
||||
@@ -235,7 +235,7 @@
|
||||
const dd = String(base.getUTCDate()).padStart(2, '0');
|
||||
const mm = String(base.getUTCMonth() + 1).padStart(2, '0');
|
||||
const yy = String(base.getUTCFullYear()).slice(-2);
|
||||
return `${dd} ${mm} ${yy}`;
|
||||
return `${dd} ${mm} ${yy}`;
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
@@ -392,6 +392,8 @@
|
||||
const birthdayFmt = formatDateDDMMYY(birthday);
|
||||
const validityStartFmt = formatDateDDMMYY(validityStart);
|
||||
|
||||
console.log(birthday, validityStart)
|
||||
|
||||
// Row 1: Name
|
||||
const namePos = getAbsolutePositionPt(
|
||||
cellX_mm,
|
||||
|
||||
@@ -173,7 +173,6 @@
|
||||
<p class="text-sm text-gray-700">
|
||||
Review your data and select which rows to include. Select a batch of max 200 items by using the top checkbox.
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 mt-1">Note: Processing of cards is allowed only in batches of 200.</p>
|
||||
<p class="text-sm text-gray-700">
|
||||
Already printed or invalid data is marked in the status column.
|
||||
</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { PHOTO_DIMENSIONS } from '$lib/pdfSettings';
|
||||
|
||||
let { imageUrl, personName, initialCropData, onCropUpdated, onClose } = $props<{
|
||||
imageUrl: string;
|
||||
@@ -35,8 +35,8 @@
|
||||
let canvasWidth = 600;
|
||||
let canvasHeight = 400;
|
||||
|
||||
// Get crop ratio from environment
|
||||
const cropRatio = parseFloat(env.PUBLIC_CROP_RATIO || '1.0');
|
||||
// Use the photo card aspect ratio from PDF settings (width / height)
|
||||
const cropRatio = PHOTO_DIMENSIONS.width / PHOTO_DIMENSIONS.height;
|
||||
|
||||
onMount(() => {
|
||||
ctx = canvas.getContext('2d')!;
|
||||
|
||||
@@ -27,14 +27,14 @@ export const TEXT_CARD_DIMENSIONS: CardDimensions = {
|
||||
|
||||
// Dimensions for a single card in the photo PDF.
|
||||
export const PHOTO_CARD_DIMENSIONS: CardDimensions = {
|
||||
width: 27,
|
||||
height: 39
|
||||
width: 29,
|
||||
height: 41
|
||||
};
|
||||
|
||||
// Photo dimensions within the photo card
|
||||
export const PHOTO_DIMENSIONS = {
|
||||
width: 25, // mm
|
||||
height: 35 // mm
|
||||
width: 26, // mm
|
||||
height: 36 // mm
|
||||
};
|
||||
|
||||
export interface TextPosition {
|
||||
@@ -69,12 +69,12 @@ const FONT_SIZE = 8; // pt
|
||||
// Text PDF Field Positions (in mm, relative to cell top-left)
|
||||
export const TEXT_FIELD_LAYOUT: TextFieldLayout = {
|
||||
name: {
|
||||
x: 3,
|
||||
y: 5,
|
||||
size: FONT_SIZE // font size in points
|
||||
x: 2,
|
||||
y: 4,
|
||||
size: FONT_SIZE
|
||||
},
|
||||
nationality: {
|
||||
x: 3,
|
||||
x: 2,
|
||||
y: 12,
|
||||
size: FONT_SIZE
|
||||
},
|
||||
@@ -84,12 +84,12 @@ export const TEXT_FIELD_LAYOUT: TextFieldLayout = {
|
||||
size: FONT_SIZE
|
||||
},
|
||||
studiesAt: {
|
||||
x: 3,
|
||||
x: 2,
|
||||
y: 20,
|
||||
size: FONT_SIZE
|
||||
},
|
||||
esnSection: {
|
||||
x: 3,
|
||||
x: 2,
|
||||
y: 28,
|
||||
size: FONT_SIZE
|
||||
},
|
||||
@@ -111,6 +111,6 @@ export const PHOTO_FIELD_LAYOUT: PhotoFieldLayout = {
|
||||
name: {
|
||||
x: 2,
|
||||
y: PHOTO_DIMENSIONS.height + 4,
|
||||
size: FONT_SIZE
|
||||
size: 6
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user