import { useContext, useEffect, useState } from "react"; import CanvasContext from "./Context/canvasContext/CanvasContext"; import { Card, CardTitle } from "./ui/card"; import { Button } from "./ui/button"; import { Trash2, UploadIcon } from "lucide-react"; import { Separator } from "./ui/separator"; import ColorComponent from "./ColorComponent"; import { Label } from "./ui/label"; import { Input } from "./ui/input"; import { Slider } from "./ui/slider"; import { fabric } from "fabric"; import { ScrollArea } from "./ui/scroll-area"; import { useNavigate, useParams } from "react-router-dom"; import { useToast } from "../hooks/use-toast"; import { useMutation } from "@tanstack/react-query"; import { deleteImage, uploadImage } from "../api/uploadApi"; import { createProject } from "../api/projectApi"; import SaveCanvas from "./SaveCanvas"; const CanvasSetting = () => { const { canvas } = useContext(CanvasContext); const params = useParams(); const { id } = params; const { toast } = useToast(); const navigate = useNavigate(); const [bgImage, setBgImage] = useState(null); const [bgOverLayImage, setBgOverLayImage] = useState(null); // create empty project if no id is provided useEffect(() => { const createEmptyProject = async () => { try { const response = await createProject(); if (response?.status === 200) { toast({ title: response?.status, description: response?.message }) } if (response?.data?.id) { navigate(`/${response.data.id}`); } } catch (error) { console.error("Project creation failed:", error); } }; if (!id) { createEmptyProject(); } }, [id, navigate, toast]); // upload bg-image handler const { mutate: uploadBackgroundImage } = useMutation({ mutationFn: async ({ file, id }) => { return await uploadImage({ file, id }); }, onSuccess: (data) => { if (data?.status === 200) { toast({ title: data?.status, description: data?.message }); setBgImage(data?.data[0]?.url); // Create an image element const imgElement = new Image(); // Set the crossOrigin attribute BEFORE setting the src imgElement.crossOrigin = "anonymous"; // This ensures CORS headers are sent imgElement.src = data?.data[0]?.url; imgElement.onload = () => { // Create a fabric.Image instance const img = new fabric.Image(imgElement, { scaleX: canvas.width / imgElement.width, scaleY: canvas.height / imgElement.height, }); // Set the background image on the canvas canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)); }; imgElement.onerror = (error) => { console.error('Failed to load image:', error); toast({ variant: "destructive", title: "Image Load Error", description: "Failed to load the image. Please try again." }) }; } else { toast({ variant: "destructive", title: data?.status, description: data?.message }); } } }) // handle bg-image remove const { mutate: removeBackgroundMutate } = useMutation({ mutationFn: async (url) => { return await deleteImage(url); }, onSuccess: (data) => { if (data?.status === 200) { toast({ title: data?.status, description: data?.message }) canvas.backgroundImage = null; canvas.renderAll(); setBgImage(null); } else { toast({ variant: "destructive", title: data?.status, description: data?.message }) } } }); // upload bg-overLayImage handler const { mutate: uploadOverlayImage } = useMutation({ mutationFn: async ({ file, id }) => { return await uploadImage({ file, id }); }, onSuccess: (data) => { if (data?.status === 200) { toast({ title: data?.status, description: data?.message }); setBgOverLayImage(data?.data[0]?.url); // Create an image element const imgElement = new Image(); // Set the crossOrigin attribute BEFORE setting the src imgElement.crossOrigin = "anonymous"; // This ensures CORS headers are sent imgElement.src = data?.data[0]?.url; imgElement.onload = () => { // Create a fabric.Image instance const img = new fabric.Image(imgElement, { scaleX: canvas.width / imgElement.width, scaleY: canvas.height / imgElement.height, }); // Set the background image on the canvas canvas.setOverlayImage(img, canvas.renderAll.bind(canvas)); }; imgElement.onerror = (error) => { console.error('Failed to load image:', error); toast({ variant: "destructive", title: "Image Load Error", description: "Failed to load the image. Please try again." }) }; } else { toast({ variant: "destructive", title: data?.status, description: data?.message }); } } }) // handle bg-overLayImage remove const { mutate: removeOverLayMutate } = useMutation({ mutationFn: async (url) => { return await deleteImage(url); }, onSuccess: (data) => { if (data?.status === 200) { toast({ title: data?.status, description: data?.message }) canvas.overlayImage = null; canvas.renderAll(); setBgOverLayImage(null); } else { toast({ variant: "destructive", title: data?.status, description: data?.message }) } } }); const setBackgroundImage = (e) => { const file = e.target.files[0]; if (file) { uploadBackgroundImage({ file, id }) } else { toast({ variant: "destructive", title: "Error", description: "Please select a file", }) } }; const setBackgroundOverlayImage = (e) => { const file = e.target.files[0]; if (file) { uploadOverlayImage({ file, id }) } else { toast({ variant: "destructive", title: "Error", description: "Please select a file", }) } }; const adjustBackgroundOpacity = (value) => { if (canvas) { if (canvas.backgroundImage) { // Update the opacity of the background image if it exists canvas.backgroundImage.set("opacity", value); } else if (canvas.overlayImage) { // Update the opacity of the overlay image if it exists canvas.overlayImage.set("opacity", value); } else { console.error("No background or overlay image found on the canvas."); return; } // Re-render the canvas to apply changes canvas.renderAll(); } else { console.error("Canvas is not initialized."); } }; const removeBackgroundImage = () => { if (canvas) { const bgUrl = canvas.backgroundImage?.getSrc(); console.log("background image from remove", bgUrl) if (bgUrl) { removeBackgroundMutate(bgUrl) } else { toast({ variant: "destructive", title: "Error", description: "No background image found", }) } } }; const removeBackgroundOverlayImage = () => { if (canvas) { const overLayUrl = canvas.overlayImage?.getSrc(); console.log("overlay image from remove", overLayUrl); if (overLayUrl) { removeOverLayMutate(overLayUrl); } else { toast({ variant: "destructive", title: "Error", description: "No overlay image found", }) } } }; useEffect(() => { if (canvas) { const bgUrl = canvas.backgroundImage?.getSrc(); setBgImage(bgUrl); const overLayUrl = canvas.overlayImage?.getSrc(); setBgOverLayImage(overLayUrl); } }, [canvas, setBgImage, setBgOverLayImage]) return (
Canvas Setting
{ bgImage && canvas_bg_image }
{ !bgImage && } { bgImage && }
{ bgImage ? : }
{ bgOverLayImage && canvas_bgOverLay_image }
{ !bgOverLayImage && } { bgOverLayImage && }
{ bgOverLayImage ? : } {/* opacity */}
{ const newOpacity = value[0]; // Extract slider value adjustBackgroundOpacity(newOpacity); // Adjust Fabric.js background opacity }} />
{/* Save canvas Component */} { id && }
); }; export default CanvasSetting;