remove background
This commit is contained in:
@@ -17,7 +17,8 @@ type Props = {
|
||||
isReset?: boolean,
|
||||
useUploadService?: boolean,
|
||||
onUploadComplete?: (urls: string[]) => void,
|
||||
onUploadError?: (error: Error) => void
|
||||
onUploadError?: (error: Error) => void,
|
||||
onDelete?: () => void
|
||||
}
|
||||
|
||||
const UploadBoxDraggble: FC<Props> = (props: Props) => {
|
||||
@@ -100,6 +101,9 @@ const UploadBoxDraggble: FC<Props> = (props: Props) => {
|
||||
if (props.onChangePreview) {
|
||||
props.onChangePreview(array);
|
||||
}
|
||||
if (props.onDelete) {
|
||||
props.onDelete()
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -112,12 +112,8 @@ const Setting: FC = () => {
|
||||
const screenshotFile = await capturePersonalityScreenshot(templateName)
|
||||
setIsCapturingScreenshot(false)
|
||||
|
||||
if (!screenshotFile) {
|
||||
toast('خطا در گرفتن اسکرینشات', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
const thumbnailUrl = await singleUpload(screenshotFile)
|
||||
const thumbnailUrl = screenshotFile ? await singleUpload(screenshotFile) : undefined
|
||||
|
||||
if (isEditMode) {
|
||||
updateTemplate({
|
||||
@@ -126,7 +122,7 @@ const Setting: FC = () => {
|
||||
name: templateName,
|
||||
rawHtml: html,
|
||||
structure: data,
|
||||
thumbnailUrl: thumbnailUrl?.data?.url
|
||||
thumbnailUrl: thumbnailUrl?.data?.url || undefined
|
||||
}
|
||||
}, {
|
||||
onSuccess: (data) => {
|
||||
@@ -141,7 +137,7 @@ const Setting: FC = () => {
|
||||
name: templateName,
|
||||
rawHtml: html,
|
||||
structure: data,
|
||||
thumbnailUrl: thumbnailUrl?.data?.url
|
||||
thumbnailUrl: thumbnailUrl?.data?.url || undefined
|
||||
}, {
|
||||
onSuccess: (data) => {
|
||||
toast(data?.data?.message || 'قالب با موفقیت ایجاد شد', 'success')
|
||||
|
||||
@@ -160,6 +160,8 @@ const SettingSideBar: FC = () => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
console.log(data[activeSection]);
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -211,6 +213,12 @@ const SettingSideBar: FC = () => {
|
||||
<UploadBoxDraggble
|
||||
label={isUploading ? 'در حال آپلود...' : t('setting.upload_background')}
|
||||
onChange={handleUploadBackground}
|
||||
preview={data?.[activeSection]?.items?.[0]?.backgroundImage ? [data?.[activeSection]?.items?.[0]?.backgroundImage] : undefined}
|
||||
onDelete={() => {
|
||||
updateActiveItem({
|
||||
backgroundImage: undefined
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,59 @@
|
||||
import domtoimage from "dom-to-image";
|
||||
|
||||
/**
|
||||
* تبدیل تصاویر خارجی به data URL برای حل مشکل CORS
|
||||
*/
|
||||
const convertImagesToDataUrl = async (element: HTMLElement): Promise<void> => {
|
||||
const images = element.querySelectorAll("img");
|
||||
const promises = Array.from(images).map(async (img) => {
|
||||
try {
|
||||
// فقط تصاویر خارجی را پردازش کن
|
||||
if (
|
||||
!img.src.startsWith(window.location.origin) &&
|
||||
!img.src.startsWith("data:")
|
||||
) {
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
if (ctx) {
|
||||
// ایجاد image جدید با crossOrigin
|
||||
const tempImg = new Image();
|
||||
tempImg.crossOrigin = "anonymous";
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
tempImg.onload = () => {
|
||||
canvas.width = tempImg.width;
|
||||
canvas.height = tempImg.height;
|
||||
ctx.drawImage(tempImg, 0, 0);
|
||||
|
||||
try {
|
||||
const dataUrl = canvas.toDataURL("image/png");
|
||||
img.src = dataUrl;
|
||||
resolve(void 0);
|
||||
} catch (error) {
|
||||
// اگر نتوانست تبدیل کند، URL اصلی را حفظ کن
|
||||
console.warn("نمیتوان تصویر را تبدیل کرد:", img.src, error);
|
||||
resolve(void 0);
|
||||
}
|
||||
};
|
||||
|
||||
tempImg.onerror = () => {
|
||||
console.warn("نمیتوان تصویر را بارگذاری کرد:", img.src);
|
||||
resolve(void 0);
|
||||
};
|
||||
|
||||
tempImg.src = img.src;
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("خطا در تبدیل تصویر:", img.src, error);
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.allSettled(promises);
|
||||
};
|
||||
|
||||
/**
|
||||
* گرفتن اسکرینشات با dom-to-image و برگرداندن فایل برای آپلود
|
||||
*/
|
||||
@@ -23,8 +77,12 @@ export const captureScreenshotAsFile = async (
|
||||
htmlElement.style.transform = "scale(1)";
|
||||
htmlElement.style.position = "relative";
|
||||
|
||||
// تبدیل تصاویر خارجی به data URL
|
||||
console.log("🔄 Converting external images to data URLs...");
|
||||
await convertImagesToDataUrl(htmlElement);
|
||||
|
||||
// صبر برای render کامل
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
|
||||
const options = {
|
||||
quality: 1,
|
||||
@@ -35,9 +93,51 @@ export const captureScreenshotAsFile = async (
|
||||
transform: "scale(1)",
|
||||
transformOrigin: "top left",
|
||||
},
|
||||
// تنظیمات CORS برای تصاویر خارجی
|
||||
filter: (node: Node) => {
|
||||
// اگر node یک img element است، crossOrigin را چک کن
|
||||
if (node.nodeName === "IMG") {
|
||||
const img = node as HTMLImageElement;
|
||||
// تنظیم crossOrigin برای تصاویر که از دامین خارجی هستند
|
||||
if (img.src && !img.src.startsWith(window.location.origin)) {
|
||||
img.crossOrigin = "anonymous";
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// امکان استفاده از تصاویر که CORS ندارند
|
||||
allowTaint: true,
|
||||
useCORS: true,
|
||||
};
|
||||
|
||||
const dataUrl = await domtoimage.toPng(element, options);
|
||||
let dataUrl: string;
|
||||
|
||||
try {
|
||||
console.log("📸 Attempting screenshot with enhanced options...");
|
||||
dataUrl = await domtoimage.toPng(element, options);
|
||||
} catch (error) {
|
||||
console.warn("⚠️ Enhanced method failed, trying fallback...", error);
|
||||
|
||||
// Fallback: استفاده از تنظیمات سادهتر
|
||||
const fallbackOptions = {
|
||||
quality: 0.8,
|
||||
bgcolor: "#ffffff",
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight,
|
||||
// حذف filter و تنظیمات پیچیده
|
||||
imagePlaceholder:
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==",
|
||||
};
|
||||
|
||||
try {
|
||||
dataUrl = await domtoimage.toPng(element, fallbackOptions);
|
||||
console.log("✅ Fallback method succeeded");
|
||||
} catch (fallbackError) {
|
||||
console.error("❌ Both methods failed:", fallbackError);
|
||||
throw fallbackError;
|
||||
}
|
||||
}
|
||||
|
||||
// بازگردانی استایلهای اصلی
|
||||
htmlElement.style.transform = originalTransform;
|
||||
htmlElement.style.position = originalPosition;
|
||||
|
||||
Reference in New Issue
Block a user