show live change values object
This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user