canvas-backend/src/components/EditPanel.jsx

237 lines
11 KiB
JavaScript

import { useContext, useState } from "react"
import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
import { Button } from './ui/button';
import { PencilRuler, Save, Settings, Shapes, SquareX, Store, Upload, ChevronDown, ChevronUp, Type, ImageDown, X } from 'lucide-react';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './ui/tooltip';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible';
import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs';
import OpenContext from './Context/openContext/OpenContext';
import CanvasContext from './Context/canvasContext/CanvasContext';
import ActiveObjectContext from './Context/activeObject/ObjectContext';
import { fabric } from 'fabric';
import RndComponent from './Layouts/RndComponent';
import { ObjectShortcut } from "./ObjectShortcut";
export function EditPanel() {
const [isCollapsed, setIsCollapsed] = useState(false);
const { setTabValue, setOpenSetting, setOpenObjectPanel, setCaptureOpen, setOpenPanel } = useContext(OpenContext);
const { canvas } = useContext(CanvasContext);
const { setActiveObject } = useContext(ActiveObjectContext);
const saveCanvasState = () => {
// Get the JSON representation of all objects
const json = canvas.toJSON(['id', 'selectable']); // Include any custom properties you need
console.log(json);
// Get background image data if it exists
let backgroundImageData = null;
if (canvas.backgroundImage) {
backgroundImageData = {
src: canvas.backgroundImage._element.src,
width: canvas.backgroundImage.width,
height: canvas.backgroundImage.height,
scaleX: canvas.backgroundImage.scaleX,
scaleY: canvas.backgroundImage.scaleY,
originX: canvas.backgroundImage.originX,
originY: canvas.backgroundImage.originY,
opacity: canvas.backgroundImage.opacity
};
}
// Create the complete canvas state
const canvasState = {
version: '1.0',
objects: json.objects,
background: backgroundImageData,
width: canvas.width,
height: canvas.height,
backgroundColor: canvas.backgroundColor
};
console.log('Canvas state saved:', canvasState);
// loadCanvasState(canvasState);
};
// for clear canvas
const clearCanvas = () => {
canvas.clear();
canvas.renderAll();
}
const addText = () => {
if (canvas) {
const text = new fabric.IText('Editable Text', {
left: 100,
top: 100,
fontFamily: 'Poppins',
fontSize: 16,
});
// Add the text to the canvas and re-render
canvas.add(text);
// canvas.clipPath = text;
canvas.setActiveObject(text);
setActiveObject(text);
canvas.renderAll();
}
};
const rndValue = {
valueX: 0,
valueY: 20,
width: 250,
height: 0,
minWidth: 250,
maxWidth: 300,
minHeight: 0,
maxHeight: 0,
bound: "parent"
}
return (
<RndComponent value={rndValue}>
<Card className="w-full shadow-lg">
<CardHeader className="p-1 mr-12">
<div className="flex items-center justify-between">
<Button className="rnd-escape" variant={"ghost"} onClick={() => setOpenPanel(false)}><X /></Button>
<CardTitle className="text-lg">Edit Panel</CardTitle>
</div>
</CardHeader>
<Collapsible open={!isCollapsed} onOpenChange={(open) => setIsCollapsed(!open)} className="rnd-escape">
<CollapsibleTrigger asChild>
<Button variant="ghost" size="sm" className="absolute top-1 right-2">
{isCollapsed ? <ChevronDown className="h-4 w-4" /> : <ChevronUp className="h-4 w-4" />}
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
<CardContent className="p-2">
<Tabs defaultValue="edit" className="w-full">
<TabsList className="w-full flex justify-around gap-2">
<TabsTrigger value="edit">Edit</TabsTrigger>
<TabsTrigger value="add" className="block xl:hidden lg:hidden md:hidden">Add</TabsTrigger>
<TabsTrigger value="canvas">Canvas</TabsTrigger>
</TabsList>
<TabsContent value="edit" className="mt-2">
<ObjectShortcut value={"edit"} />
</TabsContent>
<TabsContent value="add" className="mt-2">
<TooltipProvider>
<div className="grid grid-cols-3 gap-2">
<ActionButton
icon={<Store className="h-4 w-4" />}
label="Icons"
onClick={() => {
setOpenObjectPanel(true);
setTabValue("icons");
}}
tooltipContent="Add icons to canvas"
/>
<ActionButton
icon={<Shapes className="h-4 w-4" />}
label="Shapes"
onClick={() => {
setTabValue("shapes");
setOpenObjectPanel(true);
}}
tooltipContent="Add shapes to canvas"
/>
<ActionButton
icon={<Type className="h-4 w-4" />}
label="Text"
onClick={() => {
addText();
setTabValue("customize"); setOpenObjectPanel(true);
}}
tooltipContent="Add text to canvas"
/>
<ActionButton
icon={<Upload className="h-4 w-4" />}
label="Image"
onClick={() => {
setTabValue("images"); setOpenObjectPanel(true);
}}
tooltipContent="Upload and add image to canvas"
/>
<ActionButton
icon={<PencilRuler className="h-4 w-4" />}
label="Customize"
onClick={() => {
setTabValue("customize"); setOpenObjectPanel(true);
}}
tooltipContent="Customize objects on canvas"
/>
</div>
</TooltipProvider>
</TabsContent>
<TabsContent value="canvas" className="mt-2">
<TooltipProvider>
<div className="grid grid-cols-3 gap-2">
<ActionButton
icon={<Save className="h-4 w-4" />}
label="Save"
onClick={saveCanvasState}
tooltipContent="Save current canvas state"
/>
<div className="block xl:hidden lg:hidden md:hidden">
<ActionButton
icon={<Settings className="h-4 w-4" />}
label="Settings"
onClick={() => setOpenSetting(true)}
tooltipContent="Open canvas settings"
/>
</div>
<ActionButton
icon={<SquareX className="h-4 w-4" />}
label="Clear"
onClick={clearCanvas}
tooltipContent="Clear entire canvas"
/>
<ActionButton
icon={<ImageDown className="h-4 w-4" />}
label="Capture"
onClick={() => setCaptureOpen(true)}
tooltipContent="Capture canvas"
/>
</div>
</TooltipProvider>
</TabsContent>
</Tabs>
</CardContent>
</CollapsibleContent>
</Collapsible>
</Card>
</RndComponent>
)
}
function ActionButton({ icon, label, onClick, tooltipContent }) {
return (
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="md" className="w-full" onClick={onClick}>
<div className="flex flex-col items-center gap-0 p-1">
{icon}
<span className="text-xs">{label}</span>
</div>
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" align="center" className="max-w-xs">
<p>{tooltipContent}</p>
</TooltipContent>
</Tooltip>
)
}