Files
dpage-editor/src/pages/editor/components/canvas/GuidesLayer.tsx
T
2026-04-26 10:50:22 +03:30

82 lines
2.5 KiB
TypeScript

import { Layer, Line } from "react-konva";
import type { Guide } from "./useSnap";
type GuidesLayerProps = {
guides: Guide[];
stageWidth: number;
stageHeight: number;
activeGuideIds: string[];
selectedGuideId: string | null;
draftGuide: { orientation: Guide["orientation"]; position: number } | null;
onGuideSelect: (id: string) => void;
onGuideDragEnd: (id: string, position: number, shouldRemove: boolean) => void;
};
const GuidesLayer = ({
guides,
stageWidth,
stageHeight,
activeGuideIds,
selectedGuideId,
draftGuide,
onGuideSelect,
onGuideDragEnd,
}: GuidesLayerProps) => {
return (
<Layer>
{guides.map((guide) => {
const isVertical = guide.orientation === "vertical";
const isActive = activeGuideIds.includes(guide.id);
const isSelected = selectedGuideId === guide.id;
return (
<Line
key={guide.id}
id={guide.id}
name="guide-line"
x={isVertical ? guide.position : 0}
y={isVertical ? 0 : guide.position}
points={isVertical ? [0, 0, 0, stageHeight] : [0, 0, stageWidth, 0]}
stroke={isSelected ? "#2563eb" : isActive ? "#1d4ed8" : "#60a5fa"}
strokeWidth={isSelected ? 2.5 : isActive ? 2 : 1}
dash={[6, 6]}
hitStrokeWidth={10}
draggable
dragBoundFunc={(pos) =>
isVertical ? { x: pos.x, y: 0 } : { x: 0, y: pos.y }
}
onMouseDown={() => onGuideSelect(guide.id)}
onDragEnd={(e) => {
const node = e.target;
const nextPosition = isVertical ? node.x() : node.y();
const shouldRemove = isVertical
? nextPosition < 0 || nextPosition > stageWidth
: nextPosition < 0 || nextPosition > stageHeight;
onGuideDragEnd(guide.id, nextPosition, shouldRemove);
}}
/>
);
})}
{draftGuide && (
<Line
name="guide-line-draft"
listening={false}
x={draftGuide.orientation === "vertical" ? draftGuide.position : 0}
y={draftGuide.orientation === "vertical" ? 0 : draftGuide.position}
points={
draftGuide.orientation === "vertical"
? [0, 0, 0, stageHeight]
: [0, 0, stageWidth, 0]
}
stroke="#2563eb"
strokeWidth={1.5}
dash={[6, 6]}
opacity={0.9}
/>
)}
</Layer>
);
};
export default GuidesLayer;