diff --git a/public/assets/svgs/Group 25403.svg b/public/assets/svgs/Group 25403.svg
new file mode 100644
index 0000000..b2d1937
--- /dev/null
+++ b/public/assets/svgs/Group 25403.svg
@@ -0,0 +1,49 @@
+
diff --git a/public/assets/svgs/Group 25404.svg b/public/assets/svgs/Group 25404.svg
new file mode 100644
index 0000000..c545865
--- /dev/null
+++ b/public/assets/svgs/Group 25404.svg
@@ -0,0 +1,38 @@
+
diff --git a/src/components/Canvas.jsx b/src/components/Canvas.jsx
index 1f6c8d0..357e35f 100644
--- a/src/components/Canvas.jsx
+++ b/src/components/Canvas.jsx
@@ -13,16 +13,36 @@ const Canvas = () => {
const { openSetting, openObjectPanel, openPanel } = useContext(OpenContext);
- const { setActiveObject } = useContext(ActiveObjectContext);
+ const { activeObject, setActiveObject } = useContext(ActiveObjectContext);
useEffect(() => {
- if (canvas) {
- canvas.on('mouse:down', () => {
- const activeObject = canvas?.getActiveObject();
+ if (!canvas) return; // Ensure canvas is available
+
+ // Event handler for mouse down
+ const handleMouseDown = (event) => {
+ const target = event.target; // Get the clicked target
+ const activeObject = canvas.getActiveObject(); // Get the active object
+
+ if (target) {
+ if (target.type === 'group') {
+ setActiveObject(activeObject);
+ } else {
+ setActiveObject(activeObject);
+ }
+ } else {
setActiveObject(activeObject);
- });
- }
- }, [canvas]);
+ }
+ };
+
+ // Attach the event listener
+ canvas.on('mouse:down', handleMouseDown);
+
+ // Cleanup function to remove the event listener
+ return () => {
+ canvas.off('mouse:down', handleMouseDown); // Remove the listener on unmount
+ };
+ }, [canvas]); // Re-run only when canvas changes
+
const removeSelected = useCallback(() => {
const activeObject = canvas?.getActiveObject();
@@ -56,6 +76,8 @@ const Canvas = () => {
};
}, [removeSelected]);
+ // console.log(activeObject);
+
return (
diff --git a/src/components/EachComponent/CustomShape/shapes.js b/src/components/EachComponent/CustomShape/shapes.js
index 0b37708..7d399a5 100644
--- a/src/components/EachComponent/CustomShape/shapes.js
+++ b/src/components/EachComponent/CustomShape/shapes.js
@@ -35,6 +35,8 @@ export const shapes = [
{ shape: 25400, source: "/assets/svgs/Group 25400.svg" },
{ shape: 25401, source: "/assets/svgs/Group 25401.svg" },
{ shape: 25402, source: "/assets/svgs/Group 25402.svg" },
+ { shape: 25403, source: "/assets/svgs/Group 25403.svg" },
+ { shape: 25404, source: "/assets/svgs/Group 25404.svg" },
];
diff --git a/src/components/EachComponent/Customization/SelectObjectFromGroup.jsx b/src/components/EachComponent/Customization/SelectObjectFromGroup.jsx
new file mode 100644
index 0000000..277cb59
--- /dev/null
+++ b/src/components/EachComponent/Customization/SelectObjectFromGroup.jsx
@@ -0,0 +1,96 @@
+import ActiveObjectContext from '@/components/Context/activeObject/ObjectContext';
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
+import { useContext, useEffect, useState } from 'react'
+import { Card, } from '@/components/ui/card';
+import CanvasContext from '@/components/Context/canvasContext/CanvasContext';
+import { Separator } from '@/components/ui/separator';
+
+const SelectObjectFromGroup = () => {
+ const [groupObjects, setGroupObjects] = useState([]);
+ const [selectedObject, setSelectedObject] = useState(null);
+ const { setActiveObject } = useContext(ActiveObjectContext);
+ const { canvas } = useContext(CanvasContext);
+
+ const activeObject = canvas?.getActiveObject();
+
+ // Update group objects when the active object changes
+ useEffect(() => {
+ if (activeObject?.type === 'group') {
+ setGroupObjects(activeObject._objects || []);
+ setSelectedObject(null); // Reset selection when group changes
+ } else {
+ setGroupObjects([]);
+ setSelectedObject(null);
+ }
+ }, [activeObject]);
+
+ // Handle object selection from dropdown
+ const handleSelectObject = (value) => {
+ const selected = groupObjects[parseInt(value)];
+ setSelectedObject(selected);
+ setActiveObject(selected);
+ };
+
+ // Don't render if there's no active group
+ if (!activeObject || activeObject.type !== 'group') {
+ return null;
+ }
+
+ console.log(selectedObject);
+ console.log(selectedObject?.group);
+ console.log(selectedObject?.fill);
+
+ return (
+
+
+ Group Objects
+
+
+
+
+ {selectedObject && (
+
+
+
+ )}
+
+
+
+ );
+};
+export default SelectObjectFromGroup;
\ No newline at end of file
diff --git a/src/components/EachComponent/CustomizeShape.jsx b/src/components/EachComponent/CustomizeShape.jsx
index 0e79862..3ff8d36 100644
--- a/src/components/EachComponent/CustomizeShape.jsx
+++ b/src/components/EachComponent/CustomizeShape.jsx
@@ -15,6 +15,7 @@ import { Card } from '../ui/card';
import PositionCustomization from './Customization/PositionCustomization';
import CollapsibleComponent from './Customization/CollapsibleComponent';
import ImageCustomization from './Customization/ImageCustomization';
+import SelectObjectFromGroup from './Customization/SelectObjectFromGroup';
const CustomizeShape = () => {
const { canvas } = useContext(CanvasContext);
@@ -28,16 +29,24 @@ const CustomizeShape = () => {
return
No active object found
;
}
+ console.log(activeObject?.type);
+
return (
+
+
+
{/* Apply fill and background color */}
- {(!hasClipPath && activeObjectType !== 'group' && !customClipPath) &&
}
+ {(activeObjectType !== 'image' && !hasClipPath && !customClipPath) &&
}
{/* Apply stroke and stroke color */}
- {(activeObjectType !== 'group' && !customClipPath) && <>
>}
+ {(!customClipPath) && <>
>}
-
-
+ {
+ activeObject?.type !== "group" &&
+ <>
+ >
+ }
{/* Controls for opacity, flip, and rotation */}
@@ -60,7 +69,7 @@ const CustomizeShape = () => {
{/* Shadow Customization */}
- {activeObjectType !== 'group' && }
+
{/* Text Customization */}
diff --git a/src/components/EachComponent/RoundedShapes/RoundedShape.jsx b/src/components/EachComponent/RoundedShapes/RoundedShape.jsx
index bcb23ba..371b9e6 100644
--- a/src/components/EachComponent/RoundedShapes/RoundedShape.jsx
+++ b/src/components/EachComponent/RoundedShapes/RoundedShape.jsx
@@ -51,9 +51,7 @@ const RoundedShape = () => {
scaleX: 6,
scaleY: 6,
strokeWidth: 0,
- // rx: 0,
- // x: 0,
- // y: 0,
+ stroke: "#ffffff"
});
canvas.add(iconGroup);
canvas.setActiveObject(iconGroup);
diff --git a/src/components/EditPanel.jsx b/src/components/EditPanel.jsx
index 2cdca5f..3bc8733 100644
--- a/src/components/EditPanel.jsx
+++ b/src/components/EditPanel.jsx
@@ -28,9 +28,13 @@ export function EditPanel() {
top: canvas?.height / 2,
originX: "center",
originY: "center",
+ selectable: true, // Allow group selection
+ subTargetCheck: true, // Allow individual object selection
+ hasControls: true, // Enable resizing/movement of the group
})
canvas.remove(...activeObjects);
canvas.add(group);
+ // canvas.setActiveObject(group);
canvas.renderAll();
} else {
console.log("Select at least two objects")
@@ -39,33 +43,44 @@ export function EditPanel() {
const ungroupSelectedObjects = () => {
const activeObject = canvas.getActiveObject();
+
if (activeObject && activeObject.type === "group") {
- // Get the active group
+ // Get the group
const group = activeObject;
// Remove the group from the canvas
canvas.remove(group);
- // Iterate through each object in the group and re-add to the canvas
+ // Iterate through each object in the group
group._objects.forEach((object) => {
- // Ensure the object has a fresh state
+ // Calculate the absolute position based on the group's transformation
+ const objLeft = object.left * group.scaleX + group.left;
+ const objTop = object.top * group.scaleY + group.top;
+
+ // Reset transformations and positions
object.set({
- hasControls: true, // Allow resizing
- selectable: true, // Make selectable
- group: null, // Remove group reference
- left: canvas?.width / 2,
- top: canvas?.height / 2,
+ left: objLeft,
+ top: objTop,
+ scaleX: object.scaleX * group.scaleX, // Adjust scale based on group
+ scaleY: object.scaleY * group.scaleY, // Adjust scale based on group
+ angle: object.angle + group.angle, // Adjust rotation
+ hasControls: true, // Allow resizing
+ selectable: true, // Make selectable
+ group: null, // Remove group reference
originX: "center",
originY: "center",
});
- // Set the object's coordinates and transformation matrix
+ // Update coordinates
object.setCoords();
// Add the object back to the canvas
canvas.add(object);
});
+ // Clear the selection
+ canvas.discardActiveObject();
+
// Render the canvas to reflect changes
canvas.renderAll();
}
diff --git a/src/components/Layouts/AddShapes.jsx b/src/components/Layouts/AddShapes.jsx
index a463de7..16ed3fc 100644
--- a/src/components/Layouts/AddShapes.jsx
+++ b/src/components/Layouts/AddShapes.jsx
@@ -3,10 +3,51 @@ import PlainShapes from '../EachComponent/Shapes/PlainShapes'
import { Card } from '../ui/card'
import { Separator } from '../ui/separator'
import CustomShape from '../EachComponent/CustomShape/CustomShape'
+import { useContext } from 'react'
+import CanvasContext from '../Context/canvasContext/CanvasContext'
+import ActiveObjectContext from '../Context/activeObject/ObjectContext'
+import { fabric } from 'fabric'
+import { Button } from '../ui/button'
+import { Type } from "lucide-react";
const AddShapes = () => {
+ const { canvas } = useContext(CanvasContext);
+ const { setActiveObject } = useContext(ActiveObjectContext);
+
+ 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();
+ }
+ };
+
return (
+
+ Add Text
+
+
+
+
+
+
Custom Shapes
diff --git a/src/components/Layouts/SheetLeftPanel.jsx b/src/components/Layouts/SheetLeftPanel.jsx
index 9c9b257..3d8dadc 100644
--- a/src/components/Layouts/SheetLeftPanel.jsx
+++ b/src/components/Layouts/SheetLeftPanel.jsx
@@ -2,7 +2,7 @@ import { Sheet, SheetContent, SheetDescription } from '../ui/sheet';
import AddShapes from './AddShapes';
import { Separator } from '../ui/separator';
import { Button } from '../ui/button';
-import { X, Store, Shapes, Upload, Type } from "lucide-react";
+import { X, Store, Shapes, Upload } from "lucide-react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs';
import AllIconsPage from '../EachComponent/Icons/AllIcons';
import UploadImage from '../EachComponent/UploadImage';
@@ -32,7 +32,7 @@ const SheetLeftPanel = () => {
- Your customizable open canvas playground.
+ Your customizable, canvas playground.
@@ -41,16 +41,19 @@ const SheetLeftPanel = () => {
-
- Shapes
+
+
+ Shapes & Text
-
- Icons
+
+
+ Icons
-
- Image
+
+
+ Image
@@ -67,7 +70,6 @@ const SheetLeftPanel = () => {
-