diff --git a/.env.example b/.env.example
index 9716867..b2d1f72 100644
--- a/.env.example
+++ b/.env.example
@@ -1,2 +1,15 @@
# Your Google Cloud OAuth 2.0 Client ID
VITE_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
+VITE_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
+VITE_FACE_OFFSET_X=0.0
+VITE_FACE_OFFSET_Y=-0.1
+
+# Crop scale multiplier based on face width
+# 1.0 = crop width equals face width, 2.0 = crop is 2x face width
+VITE_CROP_SCALE=2.5
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index a69ccc3..0e8ba3a 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -2,7 +2,11 @@
- You are a helpful AI assistant that helps developers write code.
- This code is written in Svelte 5
- It's important to only use modern Svelte 5 syntax, runes, and features.
+ - Do not use $:, do not use eventDispatching as they are both deprecated
+ - User $effect, $state, $derived
+ - Pass fucntions as props instead od dispatching events
- Use styling from ".github/styling.md" for any UI components.
- Refer to the ".github/core-instructions.md" for the overall structure of the application.
- Generate ".github/done.md" file to see what is done and what is not. Check it when you start and finish a task.
-- Remain consistent in styling and code structure.
\ No newline at end of file
+- Remain consistent in styling and code structure.
+- Avoid unncessary iterations. If problems is mostly solved, stop.
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 86a51c0..4ed9931 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "esn-card-generator",
"version": "0.0.1",
"dependencies": {
+ "@tensorflow-models/blazeface": "^0.1.0",
"@tensorflow/tfjs": "^4.22.0",
"@tensorflow/tfjs-backend-webgl": "^4.22.0",
"@types/gapi": "^0.0.47",
@@ -1349,6 +1350,16 @@
"vite": "^5.2.0 || ^6 || ^7"
}
},
+ "node_modules/@tensorflow-models/blazeface": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@tensorflow-models/blazeface/-/blazeface-0.1.0.tgz",
+ "integrity": "sha512-Qc5Wii8/OE5beC7XfehkhF9SEFLaPbVKnxxalV0T9JXsUynXqvLommc9Eko7b8zXKy4SJ1BtVlcX2cmCzQrn9A==",
+ "license": "Apache-2.0",
+ "peerDependencies": {
+ "@tensorflow/tfjs-converter": "^4.10.0",
+ "@tensorflow/tfjs-core": "^4.10.0"
+ }
+ },
"node_modules/@tensorflow/tfjs": {
"version": "4.22.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.22.0.tgz",
diff --git a/package.json b/package.json
index 829bc70..56af0b8 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
"dependencies": {
"@tensorflow/tfjs": "^4.22.0",
"@tensorflow/tfjs-backend-webgl": "^4.22.0",
+ "@tensorflow-models/blazeface": "^0.1.0",
"@types/gapi": "^0.0.47",
"@types/gapi.client.drive": "^3.0.15",
"@types/gapi.client.sheets": "^4.0.20201031",
diff --git a/src/app.html b/src/app.html
index 1391f88..e810908 100644
--- a/src/app.html
+++ b/src/app.html
@@ -1,6 +1,7 @@
+ Drag the crop area to move it, or drag the corner handles to resize.
+ The selected area will be used for the member card.
+
+ Aspect Ratio: {cropRatio.toFixed(1)}:1 {cropRatio === 1.0 ? '(Square)' : cropRatio === 1.5 ? '(3:2)' : ''}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/components/Wizard.svelte b/src/lib/components/Wizard.svelte
index d6bbc2f..13af3c4 100644
--- a/src/lib/components/Wizard.svelte
+++ b/src/lib/components/Wizard.svelte
@@ -4,20 +4,23 @@
import StepSheetSearch from './wizard/StepSheetSearch.svelte';
import StepColumnMap from './wizard/StepColumnMap.svelte';
import StepRowFilter from './wizard/StepRowFilter.svelte';
+ import StepGallery from './wizard/StepGallery.svelte';
// Additional steps to be added as they are implemented
const steps = [
StepAuth,
StepSheetSearch,
StepColumnMap,
- StepRowFilter
+ StepRowFilter,
+ StepGallery
];
const stepTitles = [
'Authenticate',
'Select Sheet',
'Map Columns',
- 'Filter Rows'
+ 'Filter Rows',
+ 'Review Photos'
];
function goToPreviousStep() {
diff --git a/src/lib/components/wizard/StepGallery.svelte b/src/lib/components/wizard/StepGallery.svelte
index 9696c76..ebb43bc 100644
--- a/src/lib/components/wizard/StepGallery.svelte
+++ b/src/lib/components/wizard/StepGallery.svelte
@@ -1,4 +1,402 @@
+
+
-
Review Photos
-
Photo gallery and review functionality will be implemented here.
+
+
+
+ Review & Crop Photos
+
+
+
+ Photos are automatically cropped using face detection. Click the pen icon to manually adjust the crop area.
+