show live change values object

This commit is contained in:
hamid zarghami
2026-01-07 16:15:16 +03:30
parent 1b710555bc
commit 879c086069
6 changed files with 91 additions and 117 deletions
@@ -74,7 +74,7 @@ const ObjectRenderer = ({
if (rafId1) cancelAnimationFrame(rafId1);
groupNode?.clearCache();
};
}, [shouldApplyMask, isSelected, maskShape?.x, maskShape?.y, maskShape?.width, maskShape?.height, maskShape?.rotation, obj.x, obj.y, obj.width, obj.height, obj.rotation, obj.maskInvert]);
}, [shouldApplyMask, isSelected, maskShape?.x, maskShape?.y, maskShape?.width, maskShape?.height, maskShape?.rotation, obj.x, obj.y, obj.width, obj.height, obj.rotation, obj.maskInvert, obj.strokeWidth, obj.stroke, obj.fill]);
// Refresh cache after transformer is attached (when isSelected changes)
useEffect(() => {
@@ -1,5 +1,3 @@
import { useEffect, useState } from "react";
import Button from "@/components/Button";
import Input from "@/components/Input";
import ColorPicker from "@/components/ColorPicker";
import type { EditorObject } from "@/pages/editor/store/editorStore";
@@ -9,14 +7,6 @@ type ShapeSettingsProps = {
onUpdate: (id: string, updates: Partial<EditorObject>) => void;
};
type ShapeFormState = {
width: string;
height: string;
fill: string;
stroke: string;
strokeWidth: string;
};
const ShapeSettings = ({ selectedObject, onUpdate }: ShapeSettingsProps) => {
const baseWidth = selectedObject.width ?? 100;
const baseHeight = selectedObject.height ?? 100;
@@ -24,105 +14,57 @@ const ShapeSettings = ({ selectedObject, onUpdate }: ShapeSettingsProps) => {
const baseStroke = selectedObject.stroke ?? "#1e40af";
const baseStrokeWidth = selectedObject.strokeWidth ?? 0;
const [formState, setFormState] = useState<ShapeFormState>({
width: String(baseWidth),
height: String(baseHeight),
fill: baseFill,
stroke: baseStroke,
strokeWidth: String(baseStrokeWidth),
});
useEffect(() => {
setFormState({
width: String(baseWidth),
height: String(baseHeight),
fill: baseFill,
stroke: baseStroke,
strokeWidth: String(baseStrokeWidth),
});
}, [baseWidth, baseHeight, baseFill, baseStroke, baseStrokeWidth]);
const parseNumber = (value: string, fallback: number) => {
const parsed = parseInt(value, 10);
return Number.isNaN(parsed) ? fallback : parsed;
};
const handleSave = () => {
onUpdate(selectedObject.id, {
width: parseNumber(formState.width, baseWidth),
height: parseNumber(formState.height, baseHeight),
fill: formState.fill || baseFill,
stroke: formState.stroke || baseStroke,
strokeWidth: parseNumber(formState.strokeWidth, baseStrokeWidth),
});
};
const isDirty =
formState.width !== String(baseWidth) ||
formState.height !== String(baseHeight) ||
formState.fill !== baseFill ||
formState.stroke !== baseStroke ||
formState.strokeWidth !== String(baseStrokeWidth);
return (
<div className="space-y-4">
<Input
label="عرض"
type="number"
value={formState.width}
value={baseWidth}
onChange={(e) =>
setFormState((prev) => ({
...prev,
width: e.target.value,
}))
onUpdate(selectedObject.id, {
width: parseInt(e.target.value) || baseWidth,
})
}
/>
<Input
label="ارتفاع"
type="number"
value={formState.height}
value={baseHeight}
onChange={(e) =>
setFormState((prev) => ({
...prev,
height: e.target.value,
}))
onUpdate(selectedObject.id, {
height: parseInt(e.target.value) || baseHeight,
})
}
/>
<ColorPicker
label="رنگ پس‌زمینه"
value={formState.fill}
value={baseFill}
onChange={(value) =>
setFormState((prev) => ({
...prev,
onUpdate(selectedObject.id, {
fill: value,
}))
})
}
/>
<ColorPicker
label="رنگ خط"
value={formState.stroke}
value={baseStroke}
onChange={(value) =>
setFormState((prev) => ({
...prev,
onUpdate(selectedObject.id, {
stroke: value,
}))
})
}
/>
<Input
label="ضخامت خط"
type="number"
value={formState.strokeWidth}
value={baseStrokeWidth}
onChange={(e) =>
setFormState((prev) => ({
...prev,
strokeWidth: e.target.value,
}))
onUpdate(selectedObject.id, {
strokeWidth: parseInt(e.target.value) || 0,
})
}
min={0}
/>
<Button type="button" onClick={handleSave} disabled={!isDirty} className="w-full">
ذخیره تغییرات
</Button>
</div>
);
};
@@ -15,6 +15,22 @@ const AbstractShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shape
const radius = baseRadius * abstractScale;
const innerRadius = radius * 0.5;
const actualStrokeWidth = obj.strokeWidth ?? 0;
const hasStroke = actualStrokeWidth > 0;
// برای نمایش انتخاب: اگر strokeWidth واقعی > 0 است، از آن استفاده کن، وگرنه stroke را برای انتخاب نمایش بده
const displayStroke = isSelected
? (hasStroke ? obj.stroke : "#3b82f6")
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: (hasStroke ? obj.stroke : undefined);
const displayStrokeWidth = isSelected
? (hasStroke ? actualStrokeWidth : 3)
: (isMask && showGuide ? 2 : actualStrokeWidth);
return (
<Star
ref={shapeRef}
@@ -26,16 +42,8 @@ const AbstractShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shape
innerRadius={innerRadius}
outerRadius={radius}
fill={isMask ? "transparent" : obj.fill}
stroke={
isSelected
? "#3b82f6"
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: obj.stroke
}
strokeWidth={isSelected ? 3 : (isMask && showGuide ? 2 : (obj.strokeWidth ?? 0))}
stroke={displayStroke}
strokeWidth={displayStrokeWidth}
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
@@ -11,6 +11,22 @@ const CircleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: ShapePr
const isMask = obj.isMask || false;
const showGuide = obj.showMaskGuide !== false;
const actualStrokeWidth = obj.strokeWidth ?? 0;
const hasStroke = actualStrokeWidth > 0;
// برای نمایش انتخاب: اگر strokeWidth واقعی > 0 است، از آن استفاده کن، وگرنه stroke را برای انتخاب نمایش بده
const displayStroke = isSelected
? (hasStroke ? obj.stroke : "#3b82f6")
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: (hasStroke ? obj.stroke : undefined);
const displayStrokeWidth = isSelected
? (hasStroke ? actualStrokeWidth : 3)
: (isMask && showGuide ? 2 : actualStrokeWidth);
return (
<Circle
ref={shapeRef}
@@ -20,16 +36,8 @@ const CircleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: ShapePr
y={obj.y}
radius={(obj.width || 50) / 2}
fill={isMask ? "transparent" : obj.fill}
stroke={
isSelected
? "#3b82f6"
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: obj.stroke
}
strokeWidth={isSelected ? 3 : (isMask && showGuide ? 2 : (obj.strokeWidth ?? 0))}
stroke={displayStroke}
strokeWidth={displayStrokeWidth}
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
@@ -11,6 +11,22 @@ const RectangleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shap
const isMask = obj.isMask || false;
const showGuide = obj.showMaskGuide !== false;
const actualStrokeWidth = obj.strokeWidth ?? 0;
const hasStroke = actualStrokeWidth > 0;
// برای نمایش انتخاب: اگر strokeWidth واقعی > 0 است، از آن استفاده کن، وگرنه stroke را برای انتخاب نمایش بده
const displayStroke = isSelected
? (hasStroke ? obj.stroke : "#3b82f6")
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: (hasStroke ? obj.stroke : undefined);
const displayStrokeWidth = isSelected
? (hasStroke ? actualStrokeWidth : 3)
: (isMask && showGuide ? 2 : actualStrokeWidth);
return (
<Rect
ref={shapeRef}
@@ -21,16 +37,8 @@ const RectangleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shap
width={obj.width || 100}
height={obj.height || 100}
fill={isMask ? "transparent" : obj.fill}
stroke={
isSelected
? "#3b82f6"
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: obj.stroke
}
strokeWidth={isSelected ? 3 : (isMask && showGuide ? 2 : (obj.strokeWidth ?? 0))}
stroke={displayStroke}
strokeWidth={displayStrokeWidth}
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}
@@ -12,6 +12,22 @@ const TriangleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shape
const showGuide = obj.showMaskGuide !== false;
const radius = Math.min((obj.width || 100) / 2, (obj.height || 100) / 2);
const actualStrokeWidth = obj.strokeWidth ?? 0;
const hasStroke = actualStrokeWidth > 0;
// برای نمایش انتخاب: اگر strokeWidth واقعی > 0 است، از آن استفاده کن، وگرنه stroke را برای انتخاب نمایش بده
const displayStroke = isSelected
? (hasStroke ? obj.stroke : "#3b82f6")
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: (hasStroke ? obj.stroke : undefined);
const displayStrokeWidth = isSelected
? (hasStroke ? actualStrokeWidth : 3)
: (isMask && showGuide ? 2 : actualStrokeWidth);
return (
<RegularPolygon
ref={shapeRef}
@@ -22,16 +38,8 @@ const TriangleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shape
sides={3}
radius={radius}
fill={isMask ? "transparent" : obj.fill}
stroke={
isSelected
? "#3b82f6"
: (isMask && showGuide)
? "#ff6b6b"
: (isMask && !showGuide)
? "transparent"
: obj.stroke
}
strokeWidth={isSelected ? 3 : (isMask && showGuide ? 2 : (obj.strokeWidth ?? 0))}
stroke={displayStroke}
strokeWidth={displayStrokeWidth}
dash={isMask && showGuide ? [10, 5] : undefined}
rotation={obj.rotation || 0}
draggable={draggable}