- {shapes.map((shape, index) => (
-
- ))}
+ return (
+
+ Rounded Shapes
+
+
+ {shapes.map((shape, index) => (
+
+ ))}
+
+
+ );
+};
-export default RoundedShape
\ No newline at end of file
+export default RoundedShape;
diff --git a/src/components/EachComponent/Shapes/PlainShapes.jsx b/src/components/EachComponent/Shapes/PlainShapes.jsx
index 87a17c2..f62eed3 100644
--- a/src/components/EachComponent/Shapes/PlainShapes.jsx
+++ b/src/components/EachComponent/Shapes/PlainShapes.jsx
@@ -1,174 +1,326 @@
-import ActiveObjectContext from '@/components/Context/activeObject/ObjectContext';
-import CanvasContext from '@/components/Context/canvasContext/CanvasContext';
-import React, { useContext } from 'react'
+import ActiveObjectContext from "@/components/Context/activeObject/ObjectContext";
+import CanvasContext from "@/components/Context/canvasContext/CanvasContext";
+import React, { useContext } from "react";
import ReactDOMServer from "react-dom/server";
-import { fabric } from 'fabric';
-import { Card } from '@/components/ui/card';
-import { Separator } from '@/components/ui/separator';
-import { Badge, Circle, Heart, Shield } from 'lucide-react';
+import { fabric } from "fabric";
+import { Card } from "@/components/ui/card";
+import { Separator } from "@/components/ui/separator";
+import { Badge, Circle, Heart, Shield } from "lucide-react";
const PlainShapes = () => {
- const { canvas } = useContext(CanvasContext);
- const { setActiveObject } = useContext(ActiveObjectContext);
+ const { canvas } = useContext(CanvasContext);
+ const { setActiveObject } = useContext(ActiveObjectContext);
- const shapes = [
- {
- icon:
, name: 'Arrow'
- },
+ const shapes = [
+ {
+ icon: (
+
+ ),
+ name: "Arrow",
+ },
- { icon:
, name: 'Badge' },
- { icon:
, name: 'Circle' },
+ { icon:
, name: "Badge" },
+ { icon:
, name: "Circle" },
- { icon:
, name: 'Club' },
+ {
+ icon: (
+
+ ),
+ name: "Club",
+ },
- {
- icon:
, name: 'Cross'
- },
+ {
+ icon: (
+
+ ),
+ name: "Cross",
+ },
- {
- icon:
, name: 'Diamond'
- },
+ {
+ icon: (
+
+ ),
+ name: "Diamond",
+ },
- { icon:
, name: 'Heart' },
+ { icon:
, name: "Heart" },
- {
- icon:
, name: 'Hexagon'
- },
+ {
+ icon: (
+
+ ),
+ name: "Hexagon",
+ },
- {
- icon:
, name: 'Line'
- },
+ {
+ icon: (
+
+ ),
+ name: "Line",
+ },
- {
- icon:
, name: 'Octagon'
- },
+ {
+ icon: (
+
+ ),
+ name: "Octagon",
+ },
- {
- icon:
, name: 'Pentagon'
- },
+ {
+ icon: (
+
+ ),
+ name: "Pentagon",
+ },
- {
- icon:
, name: 'Rectangle'
- },
+ {
+ icon: (
+
+ ),
+ name: "Rectangle",
+ },
- {
- icon:
, name: 'Right Triangle'
- },
+ {
+ icon: (
+
+ ),
+ name: "Right Triangle",
+ },
+ {
+ icon:
,
+ name: "Shield",
+ },
- {
- icon:
, name: 'Shield'
- },
+ {
+ icon: (
+
+ ),
+ name: "Rectangle Square",
+ },
- {
- icon:
, name: 'Rectangle Square'
- },
+ {
+ icon: (
+
+ ),
+ name: "Star",
+ },
+ {
+ icon: (
+
+ ),
+ name: "Triangle",
+ },
- {
- icon:
, name: 'Star'
- },
+ {
+ icon: (
+
+ ),
+ name: "Rectangle Vertical",
+ },
+ ];
- {
- icon:
, name: 'Triangle'
- },
+ const addObject = (icon, name) => {
+ if (!canvas) {
+ console.error("Canvas is not initialized.");
+ return;
+ }
- {
- icon:
, name: 'Rectangle Vertical'
- },
+ const svgString = ReactDOMServer.renderToStaticMarkup(icon);
- ];
-
- const addObject = (icon, name) => {
- if (!canvas) {
- console.error("Canvas is not initialized.");
- return;
- }
-
- const svgString = ReactDOMServer.renderToStaticMarkup(icon);
-
- if (!svgString) {
- console.error("Failed to retrieve SVG string from icon.");
- return;
- }
- // Load SVG onto the Fabric.js canvas
- fabric.loadSVGFromString(svgString, (objects, options) => {
- if (!objects || !options) {
- console.error("Failed to parse SVG.");
- return;
- }
- const iconGroup = fabric.util.groupSVGElements(objects, options);
- iconGroup.set({
- left: canvas.width / 2,
- top: canvas.height / 2,
- originX: 'center',
- originY: 'center',
- fill: "#f09b0a",
- scaleX: 6,
- scaleY: 6,
- strokeWidth: 0,
- // rx: 0,
- // x: 0,
- // y: 0,
- });
- if (name === "Line") {
- iconGroup.set({
- strokeWidth: 2,
- })
- }
- canvas.add(iconGroup);
- canvas.setActiveObject(iconGroup);
- setActiveObject(iconGroup)
- canvas.renderAll();
+ if (!svgString) {
+ console.error("Failed to retrieve SVG string from icon.");
+ return;
+ }
+ // Load SVG onto the Fabric.js canvas
+ fabric.loadSVGFromString(svgString, (objects, options) => {
+ if (!objects || !options) {
+ console.error("Failed to parse SVG.");
+ return;
+ }
+ const iconGroup = fabric.util.groupSVGElements(objects, options);
+ iconGroup.set({
+ left: canvas.width / 2,
+ top: canvas.height / 2,
+ originX: "center",
+ originY: "center",
+ fill: "#f09b0a",
+ scaleX: 6,
+ scaleY: 6,
+ strokeWidth: 0,
+ // rx: 0,
+ // x: 0,
+ // y: 0,
+ });
+ if (name === "Line") {
+ iconGroup.set({
+ strokeWidth: 2,
});
- };
+ }
+ canvas.add(iconGroup);
+ canvas.setActiveObject(iconGroup);
+ setActiveObject(iconGroup);
+ canvas.renderAll();
+ });
+ };
- return (
-
- Plain Shapes
-
-
- {shapes.map((shape, index) => (
-
- ))}
+ return (
+
+ Plain Shapes
+
+
+ {shapes.map((shape, index) => (
+
+ ))}
+
+
+ );
+};
-export default PlainShapes
\ No newline at end of file
+export default PlainShapes;
diff --git a/src/components/EachComponent/UploadImage.jsx b/src/components/EachComponent/UploadImage.jsx
index a4c84c3..310bb38 100644
--- a/src/components/EachComponent/UploadImage.jsx
+++ b/src/components/EachComponent/UploadImage.jsx
@@ -1,288 +1,308 @@
-import { useContext, useRef, useState } from 'react'
-import CanvasContext from '../Context/canvasContext/CanvasContext'
-import { Button } from '@/components/ui/button'
-import { fabric } from 'fabric'
-import { ImageIcon, Trash2 } from 'lucide-react'
-import { Label } from '@/components/ui/label'
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
-import Resizer from "react-image-file-resizer"
-import { Slider } from '@/components/ui/slider'
-import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
-import { useDropzone } from 'react-dropzone'
-import ImageCustomization from './Customization/ImageCustomization'
-import { Separator } from '../ui/separator'
-import ActiveObjectContext from '../Context/activeObject/ObjectContext'
+import { useContext, useRef, useState } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "@/components/ui/button";
+import { fabric } from "fabric";
+import { ImageIcon, Trash2 } from "lucide-react";
+import { Label } from "@/components/ui/label";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+import Resizer from "react-image-file-resizer";
+import { Slider } from "@/components/ui/slider";
+import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
+import {
+ Card,
+ CardContent,
+ CardDescription,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
+import { useDropzone } from "react-dropzone";
+import ImageCustomization from "./Customization/ImageCustomization";
+import { Separator } from "../ui/separator";
+import ActiveObjectContext from "../Context/activeObject/ObjectContext";
const UploadImage = () => {
- const { canvas } = useContext(CanvasContext);
- const [width, setWidth] = useState(1080);
- const [height, setHeight] = useState(1080);
- const [quality, setQuality] = useState(100);
- const [rotation, setRotation] = useState("0");
- const [format, setFormat] = useState('JPEG');
- const fileInputRef = useRef(null);
+ const { canvas } = useContext(CanvasContext);
+ const [width, setWidth] = useState(1080);
+ const [height, setHeight] = useState(1080);
+ const [quality, setQuality] = useState(100);
+ const [rotation, setRotation] = useState("0");
+ const [format, setFormat] = useState("JPEG");
+ const fileInputRef = useRef(null);
- const { activeObject, setActiveObject } = useContext(ActiveObjectContext);
+ const { activeObject, setActiveObject } = useContext(ActiveObjectContext);
- const [file, setFile] = useState(null);
- const [preview, setPreview] = useState(null);
+ const [file, setFile] = useState(null);
+ const [preview, setPreview] = useState(null);
- const { getRootProps, getInputProps, isDragActive } = useDropzone({
- accept: {
- 'image/*': ['.jpeg', '.png', '.gif', '.jpg', '.webp', '.svg']
- },
- // maxSize: 5 * 1024 * 1024, // 5MB max file size
- multiple: false,
- onDrop: (acceptedFiles) => {
- if (!acceptedFiles.length) {
- console.error("No files were dropped.");
- return;
- }
- const selectedFile = acceptedFiles[0];
- // Create a preview URL
- const blobUrl = URL.createObjectURL(selectedFile);
- setFile(selectedFile);
- setPreview(blobUrl);
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
+ accept: {
+ "image/*": [".jpeg", ".png", ".gif", ".jpg", ".webp", ".svg"],
+ },
+ // maxSize: 5 * 1024 * 1024, // 5MB max file size
+ multiple: false,
+ onDrop: (acceptedFiles) => {
+ if (!acceptedFiles.length) {
+ console.error("No files were dropped.");
+ return;
+ }
+ const selectedFile = acceptedFiles[0];
+ // Create a preview URL
+ const blobUrl = URL.createObjectURL(selectedFile);
+ setFile(selectedFile);
+ setPreview(blobUrl);
- if (selectedFile.type === "image/svg+xml") {
- addImageToCanvas(selectedFile);
- URL.revokeObjectURL(blobUrl);
- } else {
- const imgElement = new Image();
- imgElement.src = blobUrl;
+ if (selectedFile.type === "image/svg+xml") {
+ addImageToCanvas(selectedFile);
+ URL.revokeObjectURL(blobUrl);
+ } else {
+ const imgElement = new Image();
+ imgElement.src = blobUrl;
- imgElement.onload = () => {
- if (imgElement.width > 1080) {
- handleResize(selectedFile, (compressedFile) => {
- addImageToCanvas(compressedFile);
- });
- } else {
- addImageToCanvas(selectedFile);
- }
- URL.revokeObjectURL(blobUrl); // Clean up
- };
+ imgElement.onload = () => {
+ if (imgElement.width > 1080) {
+ handleResize(selectedFile, (compressedFile) => {
+ addImageToCanvas(compressedFile);
+ });
+ } else {
+ addImageToCanvas(selectedFile);
+ }
+ URL.revokeObjectURL(blobUrl); // Clean up
+ };
- imgElement.onerror = () => {
- console.error("Failed to load image.");
- URL.revokeObjectURL(blobUrl); // Clean up
- };
- }
- }
+ imgElement.onerror = () => {
+ console.error("Failed to load image.");
+ URL.revokeObjectURL(blobUrl); // Clean up
+ };
+ }
+ },
+ });
+
+ const removeFile = () => {
+ // Revoke the object URL to free up memory
+ if (preview) {
+ URL.revokeObjectURL(preview);
+ }
+ setFile(null);
+ setPreview(null);
+ if (fileInputRef.current) {
+ fileInputRef.current.value = "";
+ }
+ if (activeObject?.type === "image") {
+ canvas.remove(activeObject);
+ setActiveObject(null);
+ canvas.renderAll();
+ }
+ };
+
+ const handleResize = (file, callback) => {
+ Resizer.imageFileResizer(
+ file,
+ width,
+ height,
+ format,
+ quality,
+ parseInt(rotation),
+ (resizedFile) => {
+ callback(resizedFile);
+ },
+ "file"
+ );
+ };
+
+ const addImageToCanvas = (file) => {
+ const blobUrl = URL.createObjectURL(file);
+ fabric.Image.fromURL(blobUrl, (img) => {
+ img.set({
+ left: canvas.width / 4,
+ top: canvas.height / 4,
+ scaleX: 0.5,
+ scaleY: 0.5,
+ });
+ canvas.add(img);
+ canvas.setActiveObject(img);
+ // Update the active object state
+ setActiveObject(img);
+ canvas.renderAll();
+ URL.revokeObjectURL(blobUrl);
});
+ };
- const removeFile = () => {
- // Revoke the object URL to free up memory
- if (preview) {
- URL.revokeObjectURL(preview)
- }
- setFile(null)
- setPreview(null)
- if (fileInputRef.current) {
- fileInputRef.current.value = ""
- }
- if (activeObject?.type === "image") {
- canvas.remove(activeObject);
- setActiveObject(null);
- canvas.renderAll();
- }
- }
+ return (
+
+
+ Image Upload & Editing
+
+ Upload, resize, and apply effects to your images
+
+
+
+
+
+ Upload
+ Effects
+
- const handleResize = (file, callback) => {
- Resizer.imageFileResizer(
- file,
- width,
- height,
- format,
- quality,
- parseInt(rotation),
- (resizedFile) => {
- callback(resizedFile)
- },
- 'file',
- )
- }
+ {/* Uploads */}
+
+
+
+
+
+ setWidth(value[0])}
+ />
+
+
+
+ setHeight(value[0])}
+ />
+
+
+ {format === "JPEG" && (
+
+
+ setQuality(value[0])}
+ />
+
+ )}
- const addImageToCanvas = (file) => {
- const blobUrl = URL.createObjectURL(file)
- fabric.Image.fromURL(blobUrl, (img) => {
- img.set({
- left: canvas.width / 4,
- top: canvas.height / 4,
- scaleX: 0.5,
- scaleY: 0.5,
- })
- canvas.add(img)
- canvas.setActiveObject(img);
- // Update the active object state
- setActiveObject(img);
- canvas.renderAll();
- URL.revokeObjectURL(blobUrl);
- })
- }
+
+
+
+
+
+
+
+
+
+
- return (
-
-
- Image Upload & Editing
- Upload, resize, and apply effects to your images
-
-
-
-
- Upload
- Effects
-
-
- {/* Uploads */}
-
-
-
-
-
- setWidth(value[0])}
- />
-
-
-
- setHeight(value[0])}
- />
-
-
- {format === "JPEG" && (
-
-
- setQuality(value[0])}
- />
-
- )}
-
-
-
-
-
-
-
-
-
-
-
-
- {/* upload image */}
- {
- !preview &&
-
-
-
-
-
-
-
-
- {isDragActive
- ? 'Drop file here'
- : 'Drag \'n\' drop an image, or click to select a file'
- }
-
-
- (Max 5MB, image files only)
-
-
-
-
-
-
- }
-
- {/* preview image */}
- {preview && (
-
-
-
- {
- file?.type === "image/svg+xml" ?
:
-

- }
-
-
-
-
{file?.name}
-
-
-
-
-
- )}
+ {/* upload image */}
+ {!preview && (
+
+
+
+
+
+
+
+
+ {isDragActive
+ ? "Drop file here"
+ : "Drag 'n' drop an image, or click to select a file"}
+
+
+ (Max 5MB, image files only)
+
-
+
+
+
+
+ )}
- {/* Effects */}
-
-
-
-
-
-
- )
-}
-export default UploadImage
+ {/* preview image */}
+ {preview && (
+
+
+
+ {file?.type === "image/svg+xml" ? (
+
+ ) : (
+

+ )}
+
+
+
+ {file?.name}
+
+
+
+
+
+
+ )}
+
+
+ {/* Effects */}
+
+
+
+
+
+
+ );
+};
+export default UploadImage;
diff --git a/src/components/ObjectShortcut.jsx b/src/components/ObjectShortcut.jsx
index adbc276..c99018e 100644
--- a/src/components/ObjectShortcut.jsx
+++ b/src/components/ObjectShortcut.jsx
@@ -176,6 +176,7 @@ export const ObjectShortcut = ({ value }) => {
const clearCanvas = () => {
canvas.clear();
canvas.renderAll();
+ canvas.setBackgroundColor("#ffffff", canvas.renderAll.bind(canvas));
setActiveObject(null);
};
diff --git a/src/components/Panel/CanvasPanel.jsx b/src/components/Panel/CanvasPanel.jsx
new file mode 100644
index 0000000..8f56b39
--- /dev/null
+++ b/src/components/Panel/CanvasPanel.jsx
@@ -0,0 +1,29 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import { X } from "lucide-react";
+import CanvasSetting from "../CanvasSetting";
+
+const CanvasPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Canvas Settings
+
+
+
+
+
+
+ );
+};
+
+export default CanvasPanel;
diff --git a/src/components/Panel/CommonPanel.jsx b/src/components/Panel/CommonPanel.jsx
index c319a54..57e6f2e 100644
--- a/src/components/Panel/CommonPanel.jsx
+++ b/src/components/Panel/CommonPanel.jsx
@@ -1,15 +1,7 @@
import { useContext } from "react";
import CanvasContext from "../Context/canvasContext/CanvasContext";
-import SelectObjectFromGroup from "../EachComponent/Customization/SelectObjectFromGroup";
-import StrokeCustomization from "../EachComponent/Customization/StrokeCustomization";
-import PositionCustomization from "../EachComponent/Customization/PositionCustomization";
-import { Card } from "../ui/card";
-import CollapsibleComponent from "../EachComponent/Customization/CollapsibleComponent";
-import FlipCustomization from "../EachComponent/Customization/FlipCustomization";
-import RotateCustomization from "../EachComponent/Customization/RotateCustomization";
import SkewCustomization from "../EachComponent/Customization/SkewCustomization";
import ScaleObjects from "../EachComponent/Customization/ScaleObjects";
-import ShadowCustomization from "../EachComponent/Customization/ShadowCustomization";
import AddImageIntoShape from "../EachComponent/Customization/AddImageIntoShape";
import ApplyColor from "../EachComponent/ApplyColor";
@@ -23,45 +15,17 @@ const CommonPanel = () => {
return (
-
-
{/* Apply fill and background color */}
{activeObjectType !== "image" && !hasClipPath && !customClipPath && (
)}
- {/* Apply stroke and stroke color */}
- {!customClipPath && (
- <>
-
- >
- )}
-
- {activeObject?.type !== "group" && (
- <>
-
- >
- )}
-
- {/* Controls for opacity, flip, and rotation */}
-
-
-
-
-
-
-
-
-
{/* Skew Customization */}
{/* Scale Objects */}
- {/* Shadow Customization */}
-
-
{/* Add image into shape */}
diff --git a/src/components/Panel/EditorPanel.jsx b/src/components/Panel/EditorPanel.jsx
index 10e01f2..18f9449 100644
--- a/src/components/Panel/EditorPanel.jsx
+++ b/src/components/Panel/EditorPanel.jsx
@@ -2,6 +2,16 @@ import { useContext } from "react";
import CanvasContext from "../Context/canvasContext/CanvasContext";
import TextPanel from "./TextPanel";
import ColorPanel from "./ColorPanel";
+import ShapePanel from "./ShapePanel";
+import IconPanel from "./IconPanel";
+import UploadPanel from "./UploadPanel";
+import StrokePanel from "./StrokePanel";
+import ShadowPanel from "./ShadowPanel";
+import FlipPanel from "./FlipPanel";
+import PositionPanel from "./PositionPanel";
+import ImagePanel from "./ImagePanel";
+import GroupObjectPanel from "./GroupObjectPanel";
+import CanvasPanel from "./CanvasPanel";
const EditorPanel = () => {
const { selectedPanel } = useContext(CanvasContext);
@@ -10,8 +20,28 @@ const EditorPanel = () => {
switch (selectedPanel) {
case "text":
return
;
+ case "shape":
+ return
;
+ case "icon":
+ return
;
+ case "upload":
+ return
;
case "color":
return
;
+ case "stroke":
+ return
;
+ case "shadow":
+ return
;
+ case "flip":
+ return
;
+ case "position":
+ return
;
+ case "image-insert":
+ return
;
+ case "group-obj":
+ return
;
+ case "canvas":
+ return
;
default:
return;
}
diff --git a/src/components/Panel/FlipPanel.jsx b/src/components/Panel/FlipPanel.jsx
new file mode 100644
index 0000000..7bfb8fd
--- /dev/null
+++ b/src/components/Panel/FlipPanel.jsx
@@ -0,0 +1,39 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import { X } from "lucide-react";
+import { Card } from "../ui/card";
+import CollapsibleComponent from "../EachComponent/Customization/CollapsibleComponent";
+import FlipCustomization from "../EachComponent/Customization/FlipCustomization";
+import RotateCustomization from "../EachComponent/Customization/RotateCustomization";
+
+const FlipPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Flip & Rotate
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default FlipPanel;
diff --git a/src/components/Panel/GroupObjectPanel.jsx b/src/components/Panel/GroupObjectPanel.jsx
new file mode 100644
index 0000000..0bdd55c
--- /dev/null
+++ b/src/components/Panel/GroupObjectPanel.jsx
@@ -0,0 +1,36 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import SelectObjectFromGroup from "../EachComponent/Customization/SelectObjectFromGroup";
+import { X } from "lucide-react";
+import SkewCustomization from "../EachComponent/Customization/SkewCustomization";
+import ScaleObjects from "../EachComponent/Customization/ScaleObjects";
+
+const GroupObjectPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Group Object
+
+
+
+
+ {/* Skew Customization */}
+
+
+ {/* Scale Objects */}
+
+
+
+ );
+};
+
+export default GroupObjectPanel;
diff --git a/src/components/Panel/IconPanel.jsx b/src/components/Panel/IconPanel.jsx
new file mode 100644
index 0000000..99be08b
--- /dev/null
+++ b/src/components/Panel/IconPanel.jsx
@@ -0,0 +1,30 @@
+import { useContext } from "react";
+import { Button } from "../ui/button";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { X } from "lucide-react";
+import { ScrollArea } from "../ui/scroll-area";
+import AllIconsPage from "../EachComponent/Icons/AllIcons";
+
+const IconPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Icons
+
+
+
+
+
+
+
+ );
+};
+
+export default IconPanel;
diff --git a/src/components/Panel/ImagePanel.jsx b/src/components/Panel/ImagePanel.jsx
new file mode 100644
index 0000000..c968d1d
--- /dev/null
+++ b/src/components/Panel/ImagePanel.jsx
@@ -0,0 +1,29 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import { X } from "lucide-react";
+import AddImageIntoShape from "../EachComponent/Customization/AddImageIntoShape";
+
+const ImagePanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Image
+
+
+
+
+
+
+ );
+};
+
+export default ImagePanel;
diff --git a/src/components/Panel/PositionPanel.jsx b/src/components/Panel/PositionPanel.jsx
new file mode 100644
index 0000000..6e4b79d
--- /dev/null
+++ b/src/components/Panel/PositionPanel.jsx
@@ -0,0 +1,29 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import { X } from "lucide-react";
+import PositionCustomization from "../EachComponent/Customization/PositionCustomization";
+
+const PositionPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Position Controller
+
+
+
+
+
+
+ );
+};
+
+export default PositionPanel;
diff --git a/src/components/Panel/ShadowPanel.jsx b/src/components/Panel/ShadowPanel.jsx
new file mode 100644
index 0000000..08a4c3b
--- /dev/null
+++ b/src/components/Panel/ShadowPanel.jsx
@@ -0,0 +1,29 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import { X } from "lucide-react";
+import ShadowCustomization from "../EachComponent/Customization/ShadowCustomization";
+
+const ShadowPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Shadow Color
+
+
+
+
+
+
+ );
+};
+
+export default ShadowPanel;
diff --git a/src/components/Panel/ShapePanel.jsx b/src/components/Panel/ShapePanel.jsx
new file mode 100644
index 0000000..d837b7f
--- /dev/null
+++ b/src/components/Panel/ShapePanel.jsx
@@ -0,0 +1,47 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import { X } from "lucide-react";
+import { Separator } from "../ui/separator";
+import CustomShape from "../EachComponent/CustomShape/CustomShape";
+import RoundedShape from "../EachComponent/RoundedShapes/RoundedShape";
+import PlainShapes from "../EachComponent/Shapes/PlainShapes";
+
+const ShapePanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Shape
+
+
+
+
+ Custom Shapes
+
+
+
+
+ );
+};
+
+export default ShapePanel;
diff --git a/src/components/Panel/StrokePanel.jsx b/src/components/Panel/StrokePanel.jsx
index e8d7900..e8833d6 100644
--- a/src/components/Panel/StrokePanel.jsx
+++ b/src/components/Panel/StrokePanel.jsx
@@ -1,16 +1,16 @@
import { useContext } from "react";
-import ApplyColor from "../EachComponent/ApplyColor";
import { Button } from "../ui/button";
import CanvasContext from "../Context/canvasContext/CanvasContext";
import { X } from "lucide-react";
import { ScrollArea } from "../ui/scroll-area";
+import StrokeCustomization from "../EachComponent/Customization/StrokeCustomization";
-const ColorPanel = () => {
+const StrokePanel = () => {
const { setSelectedPanel } = useContext(CanvasContext);
return (
-
Color
+ Stroke Color
-
-
+
+
);
};
-export default ColorPanel;
+export default StrokePanel;
diff --git a/src/components/Panel/TopBar.jsx b/src/components/Panel/TopBar.jsx
index a200883..383c396 100644
--- a/src/components/Panel/TopBar.jsx
+++ b/src/components/Panel/TopBar.jsx
@@ -5,9 +5,23 @@ import OpacityCustomization from "../EachComponent/Customization/OpacityCustomiz
import CanvasContext from "../Context/canvasContext/CanvasContext";
import { useContext } from "react";
import { ObjectShortcut } from "../ObjectShortcut";
+import ActiveObjectContext from "../Context/activeObject/ObjectContext";
+import { Button } from "../ui/button";
+import { ImagePlus } from "lucide-react";
+import { RxBorderWidth } from "react-icons/rx";
+import { LuFlipVertical } from "react-icons/lu";
+import { SlTarget } from "react-icons/sl";
+import { RiShadowLine } from "react-icons/ri";
+import { FaRegObjectGroup } from "react-icons/fa";
+import { Tooltip } from "react-tooltip";
export function TopBar() {
- const { selectedPanel } = useContext(CanvasContext);
+ const { activeObject } = useContext(ActiveObjectContext);
+ const { selectedPanel, setSelectedPanel, textColor } =
+ useContext(CanvasContext);
+ const activeObjectType = activeObject?.type;
+ const hasClipPath = !!activeObject?.clipPath;
+ const customClipPath = activeObject?.isClipPath;
return (
+
+
+
+
+
+
+
+
+
+
+
@@ -33,6 +188,14 @@ export function TopBar() {
+
+
+
+
+
+
+
+
);
}
diff --git a/src/components/Panel/UploadPanel.jsx b/src/components/Panel/UploadPanel.jsx
new file mode 100644
index 0000000..faeaff5
--- /dev/null
+++ b/src/components/Panel/UploadPanel.jsx
@@ -0,0 +1,30 @@
+import { useContext } from "react";
+import CanvasContext from "../Context/canvasContext/CanvasContext";
+import { X } from "lucide-react";
+import { Button } from "../ui/button";
+import { ScrollArea } from "../ui/scroll-area";
+import UploadImage from "../EachComponent/UploadImage";
+
+const UploadPanel = () => {
+ const { setSelectedPanel } = useContext(CanvasContext);
+ return (
+
+
+
Upload
+
+
+
+
+
+
+
+ );
+};
+
+export default UploadPanel;