feat: scaffold projet avec stubs et test runner navigateur
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Convertisseur Images — Matériaux Destock</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/heic2any@0.0.4/dist/heic2any.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
</head>
|
||||
<body class="bg-gray-50 min-h-screen font-sans">
|
||||
<div x-data="imageApp()" class="max-w-6xl mx-auto px-4 py-8">
|
||||
<h1 class="text-2xl font-bold text-gray-800 mb-6">
|
||||
Convertisseur Images Shopify
|
||||
</h1>
|
||||
|
||||
<!-- Zone 1: Upload -->
|
||||
<div id="upload-zone" class="mb-8">
|
||||
<p class="text-gray-500 text-center">Zone d'upload (à construire)</p>
|
||||
</div>
|
||||
|
||||
<!-- Zone 2: Grille -->
|
||||
<div id="grid-zone" class="mb-8">
|
||||
<p class="text-gray-500 text-center">Grille d'images (à construire)</p>
|
||||
</div>
|
||||
|
||||
<!-- Zone 3: Export -->
|
||||
<div id="export-zone">
|
||||
<p class="text-gray-500 text-center">Zone d'export (à construire)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import { convertHeicToJpeg } from './js/heicConverter.js';
|
||||
import { removeBackground, pickColorFromCanvas } from './js/bgRemover.js';
|
||||
import { processBatch } from './js/imageProcessor.js';
|
||||
import { downloadAllAsZip } from './js/zipExporter.js';
|
||||
|
||||
// Helper: charge un Blob comme Image sur un Canvas, applique removeBackground, retourne un Blob JPEG
|
||||
async function processImage(blob, seedColor, tolerance) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
canvas.getContext('2d').drawImage(img, 0, 0);
|
||||
try {
|
||||
removeBackground(canvas, seedColor ?? null, tolerance);
|
||||
canvas.toBlob(b => {
|
||||
URL.revokeObjectURL(img.src);
|
||||
b ? resolve(b) : reject(new Error('canvas.toBlob a retourné null'));
|
||||
}, 'image/jpeg', 0.92);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
};
|
||||
img.onerror = () => reject(new Error("Impossible de charger l'image"));
|
||||
img.src = URL.createObjectURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
window.imageApp = function () {
|
||||
return {
|
||||
files: [],
|
||||
globalTolerance: 30,
|
||||
|
||||
get readyCount() {
|
||||
return this.files.filter(f => f.status === 'done').length;
|
||||
},
|
||||
|
||||
async handleFiles(fileList) {
|
||||
// TODO: Tâche 7
|
||||
},
|
||||
|
||||
async reprocess(file) {
|
||||
// TODO: Tâche 8
|
||||
},
|
||||
|
||||
async startColorPick(file) {
|
||||
// TODO: Tâche 8
|
||||
},
|
||||
|
||||
async downloadAll() {
|
||||
// TODO: Tâche 9
|
||||
},
|
||||
};
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user