border radius
This commit is contained in:
@@ -177,6 +177,7 @@ const ObjectRenderer = ({
|
||||
y={relativeY}
|
||||
width={mask.width || 100}
|
||||
height={mask.height || 100}
|
||||
cornerRadius={Math.max(0, mask.borderRadius ?? 0)}
|
||||
rotation={mask.rotation || 0}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,9 @@ const ShapeSettings = ({ selectedObject, onUpdate }: ShapeSettingsProps) => {
|
||||
const baseFill = selectedObject.fill ?? "#3b82f6";
|
||||
const baseStroke = selectedObject.stroke ?? "#1e40af";
|
||||
const baseStrokeWidth = selectedObject.strokeWidth ?? 0;
|
||||
const baseBorderRadius = selectedObject.borderRadius ?? 0;
|
||||
const isSquareShape =
|
||||
selectedObject.shapeType === "square" || selectedObject.shapeType === undefined;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
@@ -65,6 +68,19 @@ const ShapeSettings = ({ selectedObject, onUpdate }: ShapeSettingsProps) => {
|
||||
}
|
||||
min={0}
|
||||
/>
|
||||
{isSquareShape && (
|
||||
<Input
|
||||
label="گردی گوشه"
|
||||
type="number"
|
||||
value={baseBorderRadius}
|
||||
onChange={(e) =>
|
||||
onUpdate(selectedObject.id, {
|
||||
borderRadius: Math.max(0, parseInt(e.target.value) || 0),
|
||||
})
|
||||
}
|
||||
min={0}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,6 +13,7 @@ const RectangleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shap
|
||||
|
||||
const actualStrokeWidth = obj.strokeWidth ?? 0;
|
||||
const hasStroke = actualStrokeWidth > 0;
|
||||
const cornerRadius = Math.max(0, obj.borderRadius ?? 0);
|
||||
|
||||
// برای نمایش انتخاب: اگر strokeWidth واقعی > 0 است، از آن استفاده کن، وگرنه stroke را برای انتخاب نمایش بده
|
||||
const displayStroke = isSelected
|
||||
@@ -36,6 +37,7 @@ const RectangleShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: Shap
|
||||
y={obj.y}
|
||||
width={obj.width || 100}
|
||||
height={obj.height || 100}
|
||||
cornerRadius={cornerRadius}
|
||||
fill={isMask ? "transparent" : obj.fill}
|
||||
stroke={displayStroke}
|
||||
strokeWidth={displayStrokeWidth}
|
||||
|
||||
@@ -57,6 +57,7 @@ export type EditorObject = {
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
shapeType?: ShapeType;
|
||||
borderRadius?: number;
|
||||
tableData?: TableData;
|
||||
visible?: boolean;
|
||||
isMask?: boolean;
|
||||
|
||||
@@ -75,12 +75,32 @@ const drawMaskShape = (
|
||||
// Default: Rectangle
|
||||
const width = maskShape.width || 100;
|
||||
const height = maskShape.height || 100;
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
const radius = Math.max(0, maskShape.borderRadius || 0);
|
||||
drawRoundedRectPath(ctx, 0, 0, width, height, radius);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
const drawRoundedRectPath = (
|
||||
ctx: CanvasRenderingContext2D,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
radius: number
|
||||
): void => {
|
||||
const normalizedRadius = Math.max(0, Math.min(radius, width / 2, height / 2));
|
||||
ctx.beginPath();
|
||||
if (normalizedRadius === 0) {
|
||||
ctx.rect(x, y, width, height);
|
||||
} else {
|
||||
ctx.roundRect(x, y, width, height, normalizedRadius);
|
||||
}
|
||||
ctx.closePath();
|
||||
};
|
||||
|
||||
/**
|
||||
* رسم یک object روی canvas context
|
||||
* این تابع یک نسخه ساده است - در پیادهسازی واقعی باید
|
||||
@@ -122,10 +142,12 @@ const drawObject = async (
|
||||
ctx.fill();
|
||||
if (ctx.lineWidth > 0) ctx.stroke();
|
||||
} else {
|
||||
ctx.fillRect(0, 0, object.width || 100, object.height || 100);
|
||||
if (ctx.lineWidth > 0) {
|
||||
ctx.strokeRect(0, 0, object.width || 100, object.height || 100);
|
||||
}
|
||||
const width = object.width || 100;
|
||||
const height = object.height || 100;
|
||||
const radius = Math.max(0, object.borderRadius || 0);
|
||||
drawRoundedRectPath(ctx, 0, 0, width, height, radius);
|
||||
ctx.fill();
|
||||
if (ctx.lineWidth > 0) ctx.stroke();
|
||||
}
|
||||
}
|
||||
// برای text objects
|
||||
|
||||
Reference in New Issue
Block a user