split background and a4 + scale a4 in every size

This commit is contained in:
hamid zarghami
2025-12-30 15:01:34 +03:30
parent fc67b9cab3
commit 97c59702bd
2 changed files with 78 additions and 68 deletions
+70 -62
View File
@@ -1,8 +1,7 @@
import { useEffect, useRef } from "react"; import { useEffect, useRef } from "react";
import { Stage, Layer, Transformer } from "react-konva"; import { Stage, Layer, Transformer, Rect } from "react-konva";
import Konva from "konva"; import Konva from "konva";
import { useEditorStore } from "../store/editorStore"; import { useEditorStore } from "../store/editorStore";
import { clx } from "@/helpers/utils";
import { useDrawingHandlers } from "./canvas/useDrawingHandlers"; import { useDrawingHandlers } from "./canvas/useDrawingHandlers";
import { useStageSize } from "./canvas/useStageSize"; import { useStageSize } from "./canvas/useStageSize";
import ObjectRenderer from "./canvas/ObjectRenderer"; import ObjectRenderer from "./canvas/ObjectRenderer";
@@ -106,7 +105,7 @@ const EditorCanvas = () => {
// Use a small delay to ensure the node is mounted (especially for images that need to load) // Use a small delay to ensure the node is mounted (especially for images that need to load)
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
if (!layerRef.current || !transformerRef.current) return; if (!layerRef.current || !transformerRef.current) return;
const node = layerRef.current.findOne(`#${selectedObjectId}`); const node = layerRef.current.findOne(`#${selectedObjectId}`);
if (node && transformerRef.current) { if (node && transformerRef.current) {
transformerRef.current.nodes([node]); transformerRef.current.nodes([node]);
@@ -153,67 +152,76 @@ const EditorCanvas = () => {
return ( return (
<div className="flex-1 flex items-center justify-center bg-gray-100 overflow-hidden"> <div className="flex-1 flex items-center justify-center bg-gray-100 overflow-hidden">
<Stage <div className="shadow-lg" style={{ transform: `scale(${stageSize.scale})`, transformOrigin: 'center center' }}>
ref={stageRef} <Stage
width={stageSize.width} ref={stageRef}
height={stageSize.height} width={stageSize.width}
onMouseDown={handleStageMouseDown} height={stageSize.height}
onMouseMove={handleStageMouseMove} onMouseDown={handleStageMouseDown}
onMouseUp={handleStageMouseUp} onMouseMove={handleStageMouseMove}
className={clx("bg-white shadow-lg")} onMouseUp={handleStageMouseUp}
> >
<Layer ref={layerRef}> <Layer ref={layerRef}>
{objects.map((obj) => ( <Rect
<ObjectRenderer x={0}
key={obj.id} y={0}
obj={obj} width={stageSize.width}
isSelected={selectedObjectId === obj.id} height={stageSize.height}
transformerRef={transformerRef} fill="#ffffff"
layerRef={layerRef} listening={false}
onSelect={handleSelect}
onUpdate={updateObject}
draggable={tool === "select"}
onCellClick={handleCellClick}
onCellDblClick={handleCellDblClick}
selectedCellId={selectedCellId}
/> />
))} {objects.map((obj) => (
{selectedObjectId && (() => { <ObjectRenderer
const selectedObject = objects.find(obj => obj.id === selectedObjectId); key={obj.id}
const isText = selectedObject?.type === "text"; obj={obj}
isSelected={selectedObjectId === obj.id}
return ( transformerRef={transformerRef}
<Transformer layerRef={layerRef}
ref={transformerRef} onSelect={handleSelect}
boundBoxFunc={(oldBox, newBox) => { onUpdate={updateObject}
if (Math.abs(newBox.width) < 5 || Math.abs(newBox.height) < 5) { draggable={tool === "select"}
return oldBox; onCellClick={handleCellClick}
} onCellDblClick={handleCellDblClick}
return newBox; selectedCellId={selectedCellId}
}}
ignoreStroke={isText}
perfectDrawEnabled={false}
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",
]}
/> />
); ))}
})()} {selectedObjectId && (() => {
</Layer> const selectedObject = objects.find(obj => obj.id === selectedObjectId);
</Stage> const isText = selectedObject?.type === "text";
return (
<Transformer
ref={transformerRef}
boundBoxFunc={(oldBox, newBox) => {
if (Math.abs(newBox.width) < 5 || Math.abs(newBox.height) < 5) {
return oldBox;
}
return newBox;
}}
ignoreStroke={isText}
perfectDrawEnabled={false}
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>
{editingCell && (() => { {editingCell && (() => {
const obj = objects.find((o) => o.id === editingCell.tableId); const obj = objects.find((o) => o.id === editingCell.tableId);
if (!obj || !obj.tableData) return null; if (!obj || !obj.tableData) return null;
@@ -1,13 +1,14 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
const A4_WIDTH = 794; export const A4_WIDTH = 794;
const A4_HEIGHT = 1123; export const A4_HEIGHT = 1123;
const SCALE = 0.8; const SCALE = 0.8;
export const useStageSize = () => { export const useStageSize = () => {
const [stageSize, setStageSize] = useState({ const [stageSize, setStageSize] = useState({
width: A4_WIDTH * SCALE, width: A4_WIDTH,
height: A4_HEIGHT * SCALE, height: A4_HEIGHT,
scale: SCALE,
}); });
useEffect(() => { useEffect(() => {
@@ -19,8 +20,9 @@ export const useStageSize = () => {
const newScale = Math.min(scaleX, scaleY, SCALE); const newScale = Math.min(scaleX, scaleY, SCALE);
setStageSize({ setStageSize({
width: A4_WIDTH * newScale, width: A4_WIDTH,
height: A4_HEIGHT * newScale, height: A4_HEIGHT,
scale: newScale,
}); });
}; };