allaw-ui 5.1.3 → 5.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -56,15 +56,29 @@ var FileUploader = function (_a) {
|
|
|
56
56
|
var progressIntervalRef = useRef(null);
|
|
57
57
|
var fileInputRef = useRef(null);
|
|
58
58
|
var _z = useState(originalFileName), currentFileName = _z[0], setCurrentFileName = _z[1];
|
|
59
|
+
// Garder une référence à l'image originale pour permettre les recrops
|
|
60
|
+
var originalImageUrlRef = useRef(null);
|
|
61
|
+
var originalFileRef = useRef(null);
|
|
59
62
|
useEffect(function () {
|
|
60
63
|
if (initialFile) {
|
|
61
64
|
setSelectedFile(initialFile);
|
|
65
|
+
originalFileRef.current = initialFile;
|
|
62
66
|
initialFile.arrayBuffer().then(function (content) {
|
|
63
67
|
setFileContent(content);
|
|
64
68
|
});
|
|
69
|
+
// Créer une URL pour l'image originale si c'est une image
|
|
70
|
+
if (isImageFile(initialFile) && !originalImageUrlRef.current) {
|
|
71
|
+
var url = URL.createObjectURL(initialFile);
|
|
72
|
+
originalImageUrlRef.current = url;
|
|
73
|
+
}
|
|
65
74
|
}
|
|
66
75
|
if (initialPreviewUrl) {
|
|
67
76
|
setPreviewUrl(initialPreviewUrl);
|
|
77
|
+
// Pour initialPreviewUrl, on ne peut pas créer de File depuis l'URL
|
|
78
|
+
// originalFileRef restera null, mais on peut utiliser l'URL pour le crop
|
|
79
|
+
if (!originalImageUrlRef.current) {
|
|
80
|
+
originalImageUrlRef.current = initialPreviewUrl;
|
|
81
|
+
}
|
|
68
82
|
}
|
|
69
83
|
if (initialCropMetadata) {
|
|
70
84
|
setCropMetadata(initialCropMetadata);
|
|
@@ -78,6 +92,10 @@ var FileUploader = function (_a) {
|
|
|
78
92
|
if (previewUrl && !initialPreviewUrl) {
|
|
79
93
|
URL.revokeObjectURL(previewUrl);
|
|
80
94
|
}
|
|
95
|
+
// Nettoyer aussi la référence à l'image originale
|
|
96
|
+
if (originalImageUrlRef.current && !initialPreviewUrl) {
|
|
97
|
+
URL.revokeObjectURL(originalImageUrlRef.current);
|
|
98
|
+
}
|
|
81
99
|
};
|
|
82
100
|
}, [previewUrl, initialPreviewUrl]);
|
|
83
101
|
var startProgressSimulation = function () {
|
|
@@ -169,6 +187,12 @@ var FileUploader = function (_a) {
|
|
|
169
187
|
if (isImageFile(file)) {
|
|
170
188
|
url = URL.createObjectURL(file);
|
|
171
189
|
setPreviewUrl(url);
|
|
190
|
+
// Conserver la référence à l'image originale pour les recrops
|
|
191
|
+
if (originalImageUrlRef.current && !initialPreviewUrl) {
|
|
192
|
+
URL.revokeObjectURL(originalImageUrlRef.current);
|
|
193
|
+
}
|
|
194
|
+
originalImageUrlRef.current = url;
|
|
195
|
+
originalFileRef.current = file;
|
|
172
196
|
if (!enableCropping) {
|
|
173
197
|
setCropMetadata({
|
|
174
198
|
zoom: 1,
|
|
@@ -181,6 +205,10 @@ var FileUploader = function (_a) {
|
|
|
181
205
|
else {
|
|
182
206
|
setPreviewUrl(null);
|
|
183
207
|
setCropMetadata(null);
|
|
208
|
+
if (originalImageUrlRef.current && !initialPreviewUrl) {
|
|
209
|
+
URL.revokeObjectURL(originalImageUrlRef.current);
|
|
210
|
+
}
|
|
211
|
+
originalImageUrlRef.current = null;
|
|
184
212
|
}
|
|
185
213
|
if (autoManageProgress && !(enableCropping && isImageFile(file))) {
|
|
186
214
|
startProgressSimulation();
|
|
@@ -207,9 +235,28 @@ var FileUploader = function (_a) {
|
|
|
207
235
|
});
|
|
208
236
|
}); };
|
|
209
237
|
var openCropModal = function () {
|
|
210
|
-
|
|
238
|
+
var _a, _b;
|
|
239
|
+
// Si on a un fichier original, ouvrir le modal de crop pour recropper
|
|
240
|
+
// Sinon, si on n'a pas de fichier original (image déjà croppée), ouvrir le sélecteur de fichier
|
|
241
|
+
if (originalFileRef.current && isImageFile(originalFileRef.current)) {
|
|
242
|
+
// S'assurer qu'on a une URL pour l'image originale
|
|
243
|
+
if (!originalImageUrlRef.current) {
|
|
244
|
+
var url = URL.createObjectURL(originalFileRef.current);
|
|
245
|
+
originalImageUrlRef.current = url;
|
|
246
|
+
}
|
|
247
|
+
// Utiliser le fichier original pour le modal de crop
|
|
248
|
+
setSelectedFile(originalFileRef.current);
|
|
211
249
|
setShowCropper(true);
|
|
212
250
|
}
|
|
251
|
+
else if (selectedFile && isImageFile(selectedFile)) {
|
|
252
|
+
// Si on a un selectedFile mais pas d'original, c'est probablement une image déjà croppée
|
|
253
|
+
// Ouvrir le sélecteur de fichier pour charger une nouvelle image
|
|
254
|
+
(_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// Pas de fichier, ouvrir le sélecteur
|
|
258
|
+
(_b = fileInputRef.current) === null || _b === void 0 ? void 0 : _b.click();
|
|
259
|
+
}
|
|
213
260
|
};
|
|
214
261
|
/**
|
|
215
262
|
* Crop l'image côté client et retourne un Blob
|
|
@@ -239,35 +286,45 @@ var FileUploader = function (_a) {
|
|
|
239
286
|
cropAreaWidth = 320;
|
|
240
287
|
cropAreaHeight = 60;
|
|
241
288
|
}
|
|
242
|
-
// Le zoom dans cropMetadata est
|
|
243
|
-
//
|
|
289
|
+
// Le zoom dans cropMetadata est le zoom total (baseZoom * zoom relatif)
|
|
290
|
+
// baseZoom est calculé dans le modal comme Math.max(cropWidth / imgWidth, cropHeight / imgHeight)
|
|
291
|
+
// puis multiplié par le zoom relatif (1-3) pour obtenir le zoom total
|
|
244
292
|
var totalZoom = cropMetadata.zoom;
|
|
245
|
-
//
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
//
|
|
256
|
-
//
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
var
|
|
262
|
-
|
|
263
|
-
//
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
var
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
var
|
|
293
|
+
// Dans le modal, la transform CSS est appliquée sur le container de l'image :
|
|
294
|
+
// transform: translate(offsetX, offsetY) scale(totalZoom)
|
|
295
|
+
// transform-origin: center
|
|
296
|
+
//
|
|
297
|
+
// L'ordre d'application est : scale d'abord (depuis le centre), puis translate
|
|
298
|
+
// Géométriquement, cela signifie :
|
|
299
|
+
// 1. L'image est agrandie avec scale(totalZoom) depuis son centre
|
|
300
|
+
// 2. L'image agrandie est déplacée de (offsetX, offsetY)
|
|
301
|
+
//
|
|
302
|
+
// La cropArea est fixe et centrée dans le container
|
|
303
|
+
// Pour trouver quelle partie de l'image originale correspond à la cropArea :
|
|
304
|
+
// - Le centre de la cropArea correspond au point (0, 0) dans le système de coordonnées du container
|
|
305
|
+
// - Ce point (0, 0) dans l'image transformée correspond à (-offsetX, -offsetY) dans l'image agrandie
|
|
306
|
+
// - Ce point dans l'image agrandie correspond à (-offsetX/totalZoom, -offsetY/totalZoom) dans l'image originale
|
|
307
|
+
// Centre de l'image originale
|
|
308
|
+
var imgCenterX = img.width / 2;
|
|
309
|
+
var imgCenterY = img.height / 2;
|
|
310
|
+
// Position du centre de la cropArea dans l'image originale
|
|
311
|
+
// Si l'image transformée est déplacée de offsetX vers la droite,
|
|
312
|
+
// alors le centre de la cropArea (qui reste au centre du container)
|
|
313
|
+
// correspond à un point qui est offsetX pixels à gauche du centre de l'image transformée
|
|
314
|
+
// Converti en coordonnées de l'image originale :
|
|
315
|
+
var cropCenterXInOriginal = imgCenterX - cropMetadata.offsetX / totalZoom;
|
|
316
|
+
var cropCenterYInOriginal = imgCenterY - cropMetadata.offsetY / totalZoom;
|
|
317
|
+
// Dimensions de la zone de crop dans l'image originale
|
|
318
|
+
var cropWidthInOriginal = cropAreaWidth / totalZoom;
|
|
319
|
+
var cropHeightInOriginal = cropAreaHeight / totalZoom;
|
|
320
|
+
// Coordonnées du coin supérieur gauche de la zone à cropper dans l'image originale
|
|
321
|
+
var sourceX = cropCenterXInOriginal - cropWidthInOriginal / 2;
|
|
322
|
+
var sourceY = cropCenterYInOriginal - cropHeightInOriginal / 2;
|
|
323
|
+
var sourceWidth = cropWidthInOriginal;
|
|
324
|
+
var sourceHeight = cropHeightInOriginal;
|
|
325
|
+
// S'assurer que les coordonnées sont valides (pas en dehors de l'image)
|
|
326
|
+
var clampedSourceX = Math.max(0, Math.min(sourceX, img.width - 1));
|
|
327
|
+
var clampedSourceY = Math.max(0, Math.min(sourceY, img.height - 1));
|
|
271
328
|
var clampedSourceWidth = Math.min(sourceWidth, img.width - clampedSourceX);
|
|
272
329
|
var clampedSourceHeight = Math.min(sourceHeight, img.height - clampedSourceY);
|
|
273
330
|
// Dessiner l'image croppée sur le canvas
|
|
@@ -315,7 +372,7 @@ var FileUploader = function (_a) {
|
|
|
315
372
|
setShowCropper(false);
|
|
316
373
|
};
|
|
317
374
|
var handleCropConfirm = function (cropMetadata) { return __awaiter(void 0, void 0, void 0, function () {
|
|
318
|
-
var dimensions, croppedBlob, croppedFile, croppedContent, croppedUrl, error_2;
|
|
375
|
+
var dimensions, imageToCrop, croppedBlob, croppedFile, croppedContent, croppedUrl, error_2;
|
|
319
376
|
return __generator(this, function (_a) {
|
|
320
377
|
switch (_a.label) {
|
|
321
378
|
case 0:
|
|
@@ -330,9 +387,9 @@ var FileUploader = function (_a) {
|
|
|
330
387
|
case 1:
|
|
331
388
|
_a.trys.push([1, 4, , 5]);
|
|
332
389
|
dimensions = cropOutputDimensions[cropMetadata.shape] ||
|
|
333
|
-
cropOutputDimensions.square ||
|
|
334
|
-
|
|
335
|
-
return [4 /*yield*/, cropImageToBlob(
|
|
390
|
+
cropOutputDimensions.square || { width: 200, height: 200 };
|
|
391
|
+
imageToCrop = originalImageUrlRef.current || previewUrl;
|
|
392
|
+
return [4 /*yield*/, cropImageToBlob(imageToCrop, cropMetadata, dimensions.width, dimensions.height)];
|
|
336
393
|
case 2:
|
|
337
394
|
croppedBlob = _a.sent();
|
|
338
395
|
croppedFile = new File([croppedBlob], selectedFile.name.replace(/\.[^/.]+$/, ".png"), // Remplacer l'extension par .png
|
|
@@ -348,6 +405,9 @@ var FileUploader = function (_a) {
|
|
|
348
405
|
setSelectedFile(croppedFile);
|
|
349
406
|
setFileContent(croppedContent);
|
|
350
407
|
setCurrentFileName(croppedFile.name);
|
|
408
|
+
// Réinitialiser cropMetadata car l'image est déjà croppée
|
|
409
|
+
// Plus besoin d'appliquer les transformations CSS
|
|
410
|
+
setCropMetadata(null);
|
|
351
411
|
// Appeler onFileRead avec le fichier croppé (pas de cropMetadata car déjà croppé)
|
|
352
412
|
onFileRead === null || onFileRead === void 0 ? void 0 : onFileRead(croppedFile, croppedContent);
|
|
353
413
|
return [3 /*break*/, 5];
|
|
@@ -370,6 +430,12 @@ var FileUploader = function (_a) {
|
|
|
370
430
|
if (previewUrl && !initialPreviewUrl) {
|
|
371
431
|
URL.revokeObjectURL(previewUrl);
|
|
372
432
|
}
|
|
433
|
+
// Nettoyer la référence à l'image originale
|
|
434
|
+
if (originalImageUrlRef.current && !initialPreviewUrl) {
|
|
435
|
+
URL.revokeObjectURL(originalImageUrlRef.current);
|
|
436
|
+
}
|
|
437
|
+
originalImageUrlRef.current = null;
|
|
438
|
+
originalFileRef.current = null;
|
|
373
439
|
if (autoManageProgress) {
|
|
374
440
|
stopProgressSimulation();
|
|
375
441
|
setInternalProgress(0);
|