mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-11 17:26:45 +02:00
Adjust image editing to accurately capture original dimensions
Fixes an issue where image dimensions were incorrectly scaled, causing overlays to misalign. This commit modifies the image capture process to utilize the image's natural dimensions, ensuring accurate placement of text, ribbons, and price badges. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ae4037a0-2a6f-4530-9bac-79b543286bda Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/397bca8c-984f-43ff-841a-10897aeb8140/ae4037a0-2a6f-4530-9bac-79b543286bda/Hpj2VzR
This commit is contained in:
1 parent
efd479dbcb
commit
48452300e8
2 files changed
+75
-37
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
@@ -100,50 +100,88 @@ export default function ImageEditor() {
|
|||||||
throw new Error("Aucune image sélectionnée");
|
throw new Error("Aucune image sélectionnée");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for fonts and styles to load
|
// Load the image to get its natural dimensions
|
||||||
await document.fonts.ready;
|
const img = new Image();
|
||||||
|
img.crossOrigin = 'anonymous';
|
||||||
|
img.src = previewUrl || selectedMedia.originalUrl;
|
||||||
|
|
||||||
// Capture the preview container as canvas (including CSS overlays)
|
await new Promise((resolve, reject) => {
|
||||||
const canvas = await html2canvas(previewRef.current, {
|
img.onload = resolve;
|
||||||
|
img.onerror = reject;
|
||||||
|
});
|
||||||
|
|
||||||
|
const naturalWidth = img.naturalWidth;
|
||||||
|
const naturalHeight = img.naturalHeight;
|
||||||
|
|
||||||
|
// Create a temporary container at natural image size
|
||||||
|
const tempContainer = document.createElement('div');
|
||||||
|
tempContainer.style.position = 'absolute';
|
||||||
|
tempContainer.style.top = '-10000px';
|
||||||
|
tempContainer.style.left = '-10000px';
|
||||||
|
tempContainer.style.width = `${naturalWidth}px`;
|
||||||
|
tempContainer.style.height = `${naturalHeight}px`;
|
||||||
|
document.body.appendChild(tempContainer);
|
||||||
|
|
||||||
|
// Clone and append image
|
||||||
|
const imgClone = img.cloneNode() as HTMLImageElement;
|
||||||
|
imgClone.style.width = '100%';
|
||||||
|
imgClone.style.height = '100%';
|
||||||
|
imgClone.style.objectFit = 'contain';
|
||||||
|
tempContainer.appendChild(imgClone);
|
||||||
|
|
||||||
|
// Add ribbon if enabled
|
||||||
|
if (ribbon.enabled && ribbon.text) {
|
||||||
|
const ribbonContainer = document.createElement('div');
|
||||||
|
ribbonContainer.className = `ribbon-container ${ribbon.position}`;
|
||||||
|
|
||||||
|
const ribbonTriangle = document.createElement('div');
|
||||||
|
ribbonTriangle.className = `ribbon-triangle ${ribbon.color}`;
|
||||||
|
ribbonContainer.appendChild(ribbonTriangle);
|
||||||
|
|
||||||
|
const ribbonTextElem = document.createElement('div');
|
||||||
|
ribbonTextElem.className = 'ribbon-text';
|
||||||
|
ribbonTextElem.textContent = ribbon.text;
|
||||||
|
ribbonTextElem.style.fontSize = ribbon.text.length <= 5 ? '22px' :
|
||||||
|
ribbon.text.length <= 8 ? '18px' :
|
||||||
|
ribbon.text.length <= 11 ? '15px' : '12px';
|
||||||
|
ribbonContainer.appendChild(ribbonTextElem);
|
||||||
|
|
||||||
|
tempContainer.appendChild(ribbonContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add price badge if enabled
|
||||||
|
if (priceBadge.enabled && priceBadge.price) {
|
||||||
|
const badge = document.createElement('div');
|
||||||
|
badge.className = `absolute ${
|
||||||
|
priceBadge.position === "north_east" ? "top-4 right-4" :
|
||||||
|
priceBadge.position === "south_east" ? "bottom-4 right-4" :
|
||||||
|
priceBadge.position === "south_west" ? "bottom-4 left-4" :
|
||||||
|
"top-4 left-4"
|
||||||
|
} px-4 py-2 rounded-full text-white font-bold z-10 flex items-center justify-center ${
|
||||||
|
priceBadge.color === "red" ? "bg-red-600" : "bg-yellow-500"
|
||||||
|
}`;
|
||||||
|
badge.style.fontSize = `${priceBadge.size}px`;
|
||||||
|
badge.textContent = `€${priceBadge.price}`;
|
||||||
|
tempContainer.appendChild(badge);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for styles to apply
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
|
// Capture the temporary container
|
||||||
|
const canvas = await html2canvas(tempContainer, {
|
||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
scale: 2, // Higher quality
|
scale: 1,
|
||||||
useCORS: true,
|
useCORS: true,
|
||||||
allowTaint: true,
|
allowTaint: true,
|
||||||
logging: false,
|
logging: false,
|
||||||
width: previewRef.current.offsetWidth,
|
width: naturalWidth,
|
||||||
height: previewRef.current.offsetHeight,
|
height: naturalHeight
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
onclone: (clonedDoc) => {
|
|
||||||
// Fix ribbon text positioning in cloned document
|
|
||||||
const ribbonText = clonedDoc.querySelector('.ribbon-text');
|
|
||||||
if (ribbonText instanceof HTMLElement) {
|
|
||||||
const parent = ribbonText.parentElement;
|
|
||||||
if (parent) {
|
|
||||||
const parentRect = parent.getBoundingClientRect();
|
|
||||||
// Calculate center position for ribbon text
|
|
||||||
ribbonText.style.transform = 'rotate(-45deg)';
|
|
||||||
ribbonText.style.position = 'absolute';
|
|
||||||
ribbonText.style.top = '50%';
|
|
||||||
ribbonText.style.left = '50%';
|
|
||||||
ribbonText.style.transformOrigin = 'center';
|
|
||||||
ribbonText.style.marginTop = '-0.6em';
|
|
||||||
ribbonText.style.marginLeft = `${-ribbonText.offsetWidth / 2}px`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure price badge text is properly positioned
|
|
||||||
const priceBadges = clonedDoc.querySelectorAll('[data-badge-price]');
|
|
||||||
priceBadges.forEach(badge => {
|
|
||||||
if (badge instanceof HTMLElement) {
|
|
||||||
badge.style.display = 'flex';
|
|
||||||
badge.style.alignItems = 'center';
|
|
||||||
badge.style.justifyContent = 'center';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
document.body.removeChild(tempContainer);
|
||||||
|
|
||||||
// Convert canvas to blob
|
// Convert canvas to blob
|
||||||
const blob = await new Promise<Blob>((resolve) => {
|
const blob = await new Promise<Blob>((resolve) => {
|
||||||
canvas.toBlob((blob) => resolve(blob!), 'image/jpeg', 0.95);
|
canvas.toBlob((blob) => resolve(blob!), 'image/jpeg', 0.95);
|
||||||
|
|||||||
Reference in new issue
Block a user