237 lines
11 KiB
JavaScript
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>
|
|
)
|
|
}
|