fix custom shape in viewer

This commit is contained in:
hamid zarghami
2026-06-13 16:31:24 +03:30
parent 46f5389036
commit 9447500725
4 changed files with 91 additions and 2 deletions
@@ -75,7 +75,7 @@ const buildCustomShapeObject = (points: DrawPoint[]): EditorObject => {
fillType: "solid",
stroke: "#1e40af",
strokeWidth: 2,
opacity: 1,
opacity: 100,
rotation: 0,
};
};
@@ -59,7 +59,7 @@ const CustomShape = ({ obj, isSelected, onSelect, onUpdate, draggable }: ShapePr
strokeWidth={displayStrokeWidth}
perfectDrawEnabled={false}
rotation={obj.rotation ?? 0}
opacity={obj.opacity ?? 1}
opacity={(obj.opacity ?? 100) / 100}
draggable={draggable}
onClick={(e) => {
if (shapeRef.current) {
+74
View File
@@ -622,6 +622,80 @@ const BookPage = forwardRef<HTMLDivElement, BookPageProps>(
);
}
case 'custom-shape': {
const rawPoints = obj.points ?? [];
const isClosed = obj.closed ?? true;
const minLength = isClosed ? 6 : 4;
if (rawPoints.length < minLength) return null;
const width = (obj.width || 100) * scale;
const height = (obj.height || 100) * scale;
const pointsStr = Array.from(
{ length: rawPoints.length / 2 },
(_, i) => `${rawPoints[i * 2] * scale},${rawPoints[i * 2 + 1] * scale}`,
).join(' ');
const strokeWidth = hasStroke && obj.stroke ? actualStrokeWidth * scale : 0;
const fillColor = obj.fill || '#3b82f6';
const strokeColor = obj.stroke || 'transparent';
const gradientId = `custom-shape-grad-${obj.id}-${index}`;
return (
<svg
key={obj.id || index}
style={applyStyle(
{
position: 'absolute',
left: `${(obj.x || 0) * scale}px`,
top: `${(obj.y || 0) * scale}px`,
width: `${width}px`,
height: `${height}px`,
opacity: (obj.opacity ?? 100) / 100,
transform: obj.rotation ? `rotate(${obj.rotation}deg)` : undefined,
transformOrigin: 'top left',
zIndex: index,
overflow: 'visible',
},
obj,
index,
)}
viewBox={`0 0 ${width} ${height}`}
>
{obj.fillType === 'gradient' && obj.gradient ? (
<defs>
<linearGradient
id={gradientId}
gradientUnits="userSpaceOnUse"
x1="0"
y1="0"
x2={width}
y2={height}
gradientTransform={`rotate(${obj.gradient.angle}, ${width / 2}, ${height / 2})`}
>
<stop offset="0%" stopColor={obj.gradient.from} />
<stop offset="100%" stopColor={obj.gradient.to} />
</linearGradient>
</defs>
) : null}
{isClosed ? (
<polygon
points={pointsStr}
fill={obj.fillType === 'gradient' && obj.gradient ? `url(#${gradientId})` : fillColor}
stroke={strokeColor}
strokeWidth={strokeWidth}
/>
) : (
<polyline
points={pointsStr}
fill="none"
stroke={strokeColor}
strokeWidth={strokeWidth}
/>
)}
</svg>
);
}
case 'grid': {
if (!obj.tableData) return null;
+15
View File
@@ -50,6 +50,8 @@ type ViewerDataPage = {
isMask?: boolean;
maskId?: string;
maskInvert?: boolean;
points?: number[];
closed?: boolean;
}>;
};
@@ -165,6 +167,19 @@ export function transformViewerDataToPages(data: ViewerData): PageData[] {
baseObject.maskInvert = obj.maskInvert;
}
if (obj.type === "custom-shape") {
if (obj.points !== undefined) baseObject.points = obj.points;
if (obj.closed !== undefined) baseObject.closed = obj.closed;
// Older custom shapes stored Konva opacity (01) instead of 0100
if (
obj.opacity !== undefined &&
obj.opacity > 0 &&
obj.opacity <= 1
) {
baseObject.opacity = obj.opacity * 100;
}
}
return baseObject;
});