From 2059a601aaf8af37ddb91cba88f869f42d100bfe Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sun, 3 Aug 2025 16:27:40 +0330 Subject: [PATCH] remove background --- src/components/UploadBoxDraggble.tsx | 6 +- src/pages/setting/Setting.tsx | 10 +- .../personality/components/SettingSideBar.tsx | 8 ++ .../personality/utils/screenshotHelper.ts | 104 +++++++++++++++++- 4 files changed, 118 insertions(+), 10 deletions(-) diff --git a/src/components/UploadBoxDraggble.tsx b/src/components/UploadBoxDraggble.tsx index 783be8e..2171459 100644 --- a/src/components/UploadBoxDraggble.tsx +++ b/src/components/UploadBoxDraggble.tsx @@ -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) => { @@ -100,6 +101,9 @@ const UploadBoxDraggble: FC = (props: Props) => { if (props.onChangePreview) { props.onChangePreview(array); } + if (props.onDelete) { + props.onDelete() + } } useEffect(() => { diff --git a/src/pages/setting/Setting.tsx b/src/pages/setting/Setting.tsx index 5781af2..2ad3e7d 100644 --- a/src/pages/setting/Setting.tsx +++ b/src/pages/setting/Setting.tsx @@ -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') diff --git a/src/pages/setting/personality/components/SettingSideBar.tsx b/src/pages/setting/personality/components/SettingSideBar.tsx index 0948e78..7fcbd07 100644 --- a/src/pages/setting/personality/components/SettingSideBar.tsx +++ b/src/pages/setting/personality/components/SettingSideBar.tsx @@ -160,6 +160,8 @@ const SettingSideBar: FC = () => { ) } + console.log(data[activeSection]); + return (
@@ -211,6 +213,12 @@ const SettingSideBar: FC = () => { { + updateActiveItem({ + backgroundImage: undefined + }) + }} />
diff --git a/src/pages/setting/personality/utils/screenshotHelper.ts b/src/pages/setting/personality/utils/screenshotHelper.ts index 11a517a..6929c9d 100644 --- a/src/pages/setting/personality/utils/screenshotHelper.ts +++ b/src/pages/setting/personality/utils/screenshotHelper.ts @@ -1,5 +1,59 @@ import domtoimage from "dom-to-image"; +/** + * تبدیل تصاویر خارجی به data URL برای حل مشکل CORS + */ +const convertImagesToDataUrl = async (element: HTMLElement): Promise => { + 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;