82 lines
2.5 KiB
TypeScript
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;
|