add konva js to project + create some components with ai

This commit is contained in:
hamid zarghami
2025-11-16 16:33:54 +03:30
parent c1c6b0ebf7
commit 1a0c869101
38 changed files with 1855 additions and 42 deletions
@@ -0,0 +1,101 @@
import { useEffect, useRef } from "react";
import { Stage, Layer, Transformer } from "react-konva";
import Konva from "konva";
import { useEditorStore } from "../store/editorStore";
import { clx } from "@/helpers/utils";
import { useDrawingHandlers } from "./canvas/useDrawingHandlers";
import { useStageSize } from "./canvas/useStageSize";
import ObjectRenderer from "./canvas/ObjectRenderer";
const EditorCanvas = () => {
const stageRef = useRef<Konva.Stage>(null);
const layerRef = useRef<Konva.Layer>(null);
const {
tool,
objects,
updateObject,
selectedObjectId,
setSelectedObjectId,
setStageRef,
setLayerRef,
} = useEditorStore();
const { transformerRef, handleStageMouseDown, handleStageMouseMove, handleStageMouseUp } = useDrawingHandlers();
const stageSize = useStageSize();
useEffect(() => {
if (stageRef.current) {
setStageRef(stageRef);
}
if (layerRef.current) {
setLayerRef(layerRef);
}
}, [setStageRef, setLayerRef]);
const handleSelect = (id: string, node: Konva.Node) => {
setSelectedObjectId(id);
if (transformerRef.current) {
transformerRef.current.nodes([node]);
transformerRef.current.getLayer()?.batchDraw();
}
};
return (
<div className="flex-1 flex items-center justify-center bg-gray-100 overflow-hidden">
<Stage
ref={stageRef}
width={stageSize.width}
height={stageSize.height}
onMouseDown={handleStageMouseDown}
onMouseMove={handleStageMouseMove}
onMouseUp={handleStageMouseUp}
className={clx("bg-white shadow-lg")}
>
<Layer ref={layerRef}>
{objects.map((obj) => (
<ObjectRenderer
key={obj.id}
obj={obj}
isSelected={selectedObjectId === obj.id}
transformerRef={transformerRef}
layerRef={layerRef}
onSelect={handleSelect}
onUpdate={updateObject}
draggable={tool === "select"}
/>
))}
{selectedObjectId && (
<Transformer
ref={transformerRef}
boundBoxFunc={(oldBox, newBox) => {
if (Math.abs(newBox.width) < 5 || Math.abs(newBox.height) < 5) {
return oldBox;
}
return newBox;
}}
anchorFill="#3b82f6"
anchorStroke="#ffffff"
borderStroke="#3b82f6"
borderStrokeWidth={2}
anchorSize={8}
rotateEnabled={true}
enabledAnchors={[
"top-left",
"top-right",
"bottom-left",
"bottom-right",
"top-center",
"bottom-center",
"middle-left",
"middle-right",
]}
/>
)}
</Layer>
</Stage>
</div>
);
};
export default EditorCanvas;