react-floor-mapper 0.1.18 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -596,7 +596,8 @@ var usePoints = (initialPoints) => {
596
596
  const [points, setPoints] = React2.useState(
597
597
  () => initialPoints.map((p, i) => ({ id: i + 1, x: p.x, y: p.y }))
598
598
  );
599
- return { points, setPoints };
599
+ const resetPoints = () => setPoints([]);
600
+ return { points, setPoints, resetPoints };
600
601
  };
601
602
  var useZoom = (stage) => {
602
603
  const MIN_SCALE = 0.5;
@@ -612,30 +613,34 @@ var useZoom = (stage) => {
612
613
  };
613
614
  var Container = styled__default.default.div`
614
615
  overflow: hidden;
615
- width:1200px;
616
- height:1200px;
616
+ width:100%;
617
+ height:250px;
617
618
  display: flex;
619
+ flex-direction:column;
618
620
  align-items: stretch;
619
621
  border:1px solid #ccc;
620
622
  border-radius:4px;
623
+ *{
624
+ box-sizing:border-box;
625
+ }
621
626
  `;
622
- var NavContainer = styled__default.default.div`
623
- width:80px;
624
- height:100%;
625
- background:red;
626
- flex-shrink:0;
627
- display: flex;
628
- justify-content: flex-start;
627
+ var NavBase = styled__default.default.div`
628
+ display:flex;
629
629
  align-items: center;
630
- flex-direction:column;
631
630
  gap:20px;
632
- padding:20px 0;
631
+ `;
632
+ var NavContainer = styled__default.default(NavBase)`
633
+ width:100%;
634
+ height:60px;
635
+ flex-shrink:0;
636
+ justify-content: space-between;
637
+ padding:0 10px;
633
638
  background:#ebebeb;
634
639
  border-left:1px solid #ccc;
635
640
  `;
636
641
  var CanvasContainer = styled__default.default.div`
637
- width:calc(100% - 80px);
638
- height:100%;
642
+ height:calc(100% - 60px);
643
+ width:100%;
639
644
  overflow: hidden;
640
645
  `;
641
646
  var ButtonBase = styled__default.default.button`
@@ -649,8 +654,8 @@ var ButtonBase = styled__default.default.button`
649
654
  justify-content: center;
650
655
  align-items: center;
651
656
  font-size:12px;
652
- min-width:50px;
653
- min-height:50px;
657
+ min-width:45px;
658
+ min-height:45px;
654
659
  border-left:1px solid #ccc;
655
660
  &:disabled:{
656
661
  opacity:0.5;
@@ -658,13 +663,51 @@ var ButtonBase = styled__default.default.button`
658
663
  }
659
664
  `;
660
665
  var Button = styled__default.default(ButtonBase)``;
666
+
667
+ // src/utils/debounce.ts
668
+ var debounce = (fn, delay = 200) => {
669
+ let timeoutId = null;
670
+ let lastArgs = null;
671
+ const debounced = (...args) => {
672
+ lastArgs = args;
673
+ if (timeoutId) {
674
+ clearTimeout(timeoutId);
675
+ }
676
+ timeoutId = setTimeout(() => {
677
+ timeoutId = null;
678
+ if (lastArgs) {
679
+ fn(...lastArgs);
680
+ lastArgs = null;
681
+ }
682
+ }, delay);
683
+ };
684
+ debounced.cancel = () => {
685
+ if (timeoutId) {
686
+ clearTimeout(timeoutId);
687
+ timeoutId = null;
688
+ }
689
+ lastArgs = null;
690
+ };
691
+ debounced.flush = () => {
692
+ if (!timeoutId) return;
693
+ clearTimeout(timeoutId);
694
+ timeoutId = null;
695
+ if (lastArgs) {
696
+ fn(...lastArgs);
697
+ lastArgs = null;
698
+ }
699
+ };
700
+ return debounced;
701
+ };
661
702
  var Mapper = ({
662
- src = "https://konvajs.org/assets/line-building.png",
703
+ src = "",
663
704
  initialPoints = [],
664
- maxWidth = 1200
705
+ width = 600,
706
+ height = 600,
707
+ onChange
665
708
  }) => {
666
709
  const stageRef = React2.useRef(null);
667
- const { points, setPoints } = usePoints(initialPoints);
710
+ const { points, setPoints, resetPoints } = usePoints(initialPoints);
668
711
  const { stageScale, setStageScale, MAX_SCALE, MIN_SCALE } = useZoom(stageRef == null ? void 0 : stageRef.current);
669
712
  const SCALE_BY = 1.2;
670
713
  const [closed, setClosed] = React2.useState(initialPoints.length >= 3);
@@ -672,11 +715,11 @@ var Mapper = ({
672
715
  const [stagePosition, setStagePosition] = React2.useState({ x: 0, y: 0 });
673
716
  const [dragStart, setDragStart] = React2.useState(null);
674
717
  const [isDraggingPoint, setIsDraggingPoint] = React2.useState(false);
675
- const [image] = useImage__default.default(src, "anonymous");
718
+ const [image, imageStatus] = useImage__default.default(src, "anonymous");
676
719
  const imgW = (image == null ? void 0 : image.width) || 1;
677
720
  const imgH = (image == null ? void 0 : image.height) || 1;
678
- const scale = maxWidth / imgW;
679
- const stageSize = { width: maxWidth, height: imgH * scale };
721
+ const scale = width / imgW;
722
+ const stageSize = { width, height: imgH * scale };
680
723
  const DRAG_THRESHOLD = 5;
681
724
  const LINE_HIT_THRESHOLD = 10;
682
725
  const handleZoomIn = () => {
@@ -795,6 +838,15 @@ var Mapper = ({
795
838
  }
796
839
  return null;
797
840
  };
841
+ const debouncedOnChange = React2.useMemo(
842
+ () => onChange ? debounce(onChange, 200) : null,
843
+ [onChange]
844
+ );
845
+ React2.useEffect(() => {
846
+ if (!debouncedOnChange) return;
847
+ debouncedOnChange(points);
848
+ return () => debouncedOnChange.cancel();
849
+ }, [points, debouncedOnChange]);
798
850
  React2.useEffect(() => {
799
851
  if (image) {
800
852
  const initialPos = getConstrainedPosition({ x: 0, y: 0 }, 1);
@@ -868,6 +920,10 @@ var Mapper = ({
868
920
  );
869
921
  setPoints(updatedPoints);
870
922
  };
923
+ const handlePointReset = () => {
924
+ setClosed(false);
925
+ resetPoints();
926
+ };
871
927
  const handlePointDragEnd = (e) => {
872
928
  e.cancelBubble = true;
873
929
  setIsDraggingPoint(false);
@@ -942,13 +998,55 @@ var Mapper = ({
942
998
  const dist = Math.hypot(dx, dy);
943
999
  setHoveringFirst(dist < 15);
944
1000
  };
945
- return /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
1001
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { style: { width, height }, children: [
1002
+ /* @__PURE__ */ jsxRuntime.jsxs(NavContainer, { children: [
1003
+ /* @__PURE__ */ jsxRuntime.jsx(
1004
+ Button,
1005
+ {
1006
+ onClick: handlePointReset,
1007
+ disabled: !points.length,
1008
+ title: "Reset Points",
1009
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { style: { width: "20px", height: "20px" } })
1010
+ }
1011
+ ),
1012
+ /* @__PURE__ */ jsxRuntime.jsxs(NavBase, { children: [
1013
+ /* @__PURE__ */ jsxRuntime.jsx(
1014
+ Button,
1015
+ {
1016
+ onClick: handleZoomIn,
1017
+ disabled: stageScale >= MAX_SCALE,
1018
+ title: "Zoom In (Ctrl/Cmd + +)",
1019
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { style: { width: "20px", height: "20px" } })
1020
+ }
1021
+ ),
1022
+ /* @__PURE__ */ jsxRuntime.jsx(
1023
+ Button,
1024
+ {
1025
+ onClick: handleZoomOut,
1026
+ disabled: stageScale <= MIN_SCALE,
1027
+ title: "Zoom Out (Ctrl/Cmd + -)",
1028
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { style: { width: "20px", height: "20px" } })
1029
+ }
1030
+ ),
1031
+ /* @__PURE__ */ jsxRuntime.jsxs(
1032
+ Button,
1033
+ {
1034
+ onClick: handleResetZoom,
1035
+ title: "Reset Zoom (Ctrl/Cmd + 0)",
1036
+ children: [
1037
+ Math.round(stageScale * 100),
1038
+ "%"
1039
+ ]
1040
+ }
1041
+ )
1042
+ ] })
1043
+ ] }),
946
1044
  /* @__PURE__ */ jsxRuntime.jsx(CanvasContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(
947
1045
  reactKonva.Stage,
948
1046
  {
949
1047
  ref: stageRef,
950
- width: 1200,
951
- height: 1200,
1048
+ width,
1049
+ height,
952
1050
  onMouseDown: handleStageMouseDown,
953
1051
  onMouseUp: handleStageMouseUp,
954
1052
  onMouseMove: handleMouseMove,
@@ -1004,38 +1102,7 @@ var Mapper = ({
1004
1102
  )) })
1005
1103
  ] })
1006
1104
  }
1007
- ) }),
1008
- /* @__PURE__ */ jsxRuntime.jsxs(NavContainer, { children: [
1009
- /* @__PURE__ */ jsxRuntime.jsx(
1010
- Button,
1011
- {
1012
- onClick: handleZoomIn,
1013
- disabled: stageScale >= MAX_SCALE,
1014
- title: "Zoom In (Ctrl/Cmd + +)",
1015
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { style: { width: "20px", height: "20px" } })
1016
- }
1017
- ),
1018
- /* @__PURE__ */ jsxRuntime.jsx(
1019
- Button,
1020
- {
1021
- onClick: handleZoomOut,
1022
- disabled: stageScale <= MIN_SCALE,
1023
- title: "Zoom Out (Ctrl/Cmd + -)",
1024
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { style: { width: "20px", height: "20px" } })
1025
- }
1026
- ),
1027
- /* @__PURE__ */ jsxRuntime.jsxs(
1028
- Button,
1029
- {
1030
- onClick: handleResetZoom,
1031
- title: "Reset Zoom (Ctrl/Cmd + 0)",
1032
- children: [
1033
- Math.round(stageScale * 100),
1034
- "%"
1035
- ]
1036
- }
1037
- )
1038
- ] })
1105
+ ) })
1039
1106
  ] });
1040
1107
  };
1041
1108