react-floor-mapper 0.1.19 → 0.1.21

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.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as React2 from 'react';
2
- import { useRef, useState, useEffect, useMemo } from 'react';
2
+ import { useRef, useState, useMemo, useEffect } from 'react';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
4
  import { Stage, Layer, Image as Image$1, Line, Group, Circle } from 'react-konva';
5
5
  import useImage from 'use-image';
6
- import { ZoomIn, ZoomOut } from 'lucide-react';
6
+ import { RotateCcw, ZoomIn, ZoomOut } from 'lucide-react';
7
7
  import styled from 'styled-components';
8
8
 
9
9
  // src/components/ImageWithPoints.tsx
@@ -571,7 +571,8 @@ var usePoints = (initialPoints) => {
571
571
  const [points, setPoints] = useState(
572
572
  () => initialPoints.map((p, i) => ({ id: i + 1, x: p.x, y: p.y }))
573
573
  );
574
- return { points, setPoints };
574
+ const resetPoints = () => setPoints([]);
575
+ return { points, setPoints, resetPoints };
575
576
  };
576
577
  var useZoom = (stage) => {
577
578
  const MIN_SCALE = 0.5;
@@ -587,30 +588,34 @@ var useZoom = (stage) => {
587
588
  };
588
589
  var Container = styled.div`
589
590
  overflow: hidden;
590
- width:1200px;
591
- height:1200px;
591
+ width:100%;
592
+ height:250px;
592
593
  display: flex;
594
+ flex-direction:column;
593
595
  align-items: stretch;
594
596
  border:1px solid #ccc;
595
597
  border-radius:4px;
598
+ *{
599
+ box-sizing:border-box;
600
+ }
596
601
  `;
597
- var NavContainer = styled.div`
598
- width:80px;
599
- height:100%;
600
- background:red;
601
- flex-shrink:0;
602
- display: flex;
603
- justify-content: flex-start;
602
+ var NavBase = styled.div`
603
+ display:flex;
604
604
  align-items: center;
605
- flex-direction:column;
606
605
  gap:20px;
607
- padding:20px 0;
606
+ `;
607
+ var NavContainer = styled(NavBase)`
608
+ width:100%;
609
+ height:60px;
610
+ flex-shrink:0;
611
+ justify-content: space-between;
612
+ padding:0 10px;
608
613
  background:#ebebeb;
609
614
  border-left:1px solid #ccc;
610
615
  `;
611
616
  var CanvasContainer = styled.div`
612
- width:calc(100% - 80px);
613
- height:100%;
617
+ height:calc(100% - 60px);
618
+ width:100%;
614
619
  overflow: hidden;
615
620
  `;
616
621
  var ButtonBase = styled.button`
@@ -624,8 +629,8 @@ var ButtonBase = styled.button`
624
629
  justify-content: center;
625
630
  align-items: center;
626
631
  font-size:12px;
627
- min-width:50px;
628
- min-height:50px;
632
+ min-width:45px;
633
+ min-height:45px;
629
634
  border-left:1px solid #ccc;
630
635
  &:disabled:{
631
636
  opacity:0.5;
@@ -633,13 +638,51 @@ var ButtonBase = styled.button`
633
638
  }
634
639
  `;
635
640
  var Button = styled(ButtonBase)``;
641
+
642
+ // src/utils/debounce.ts
643
+ var debounce = (fn, delay = 200) => {
644
+ let timeoutId = null;
645
+ let lastArgs = null;
646
+ const debounced = (...args) => {
647
+ lastArgs = args;
648
+ if (timeoutId) {
649
+ clearTimeout(timeoutId);
650
+ }
651
+ timeoutId = setTimeout(() => {
652
+ timeoutId = null;
653
+ if (lastArgs) {
654
+ fn(...lastArgs);
655
+ lastArgs = null;
656
+ }
657
+ }, delay);
658
+ };
659
+ debounced.cancel = () => {
660
+ if (timeoutId) {
661
+ clearTimeout(timeoutId);
662
+ timeoutId = null;
663
+ }
664
+ lastArgs = null;
665
+ };
666
+ debounced.flush = () => {
667
+ if (!timeoutId) return;
668
+ clearTimeout(timeoutId);
669
+ timeoutId = null;
670
+ if (lastArgs) {
671
+ fn(...lastArgs);
672
+ lastArgs = null;
673
+ }
674
+ };
675
+ return debounced;
676
+ };
636
677
  var Mapper = ({
637
- src = "https://konvajs.org/assets/line-building.png",
678
+ src = "",
638
679
  initialPoints = [],
639
- maxWidth = 1200
680
+ width = 600,
681
+ height = 600,
682
+ onChange
640
683
  }) => {
641
684
  const stageRef = useRef(null);
642
- const { points, setPoints } = usePoints(initialPoints);
685
+ const { points, setPoints, resetPoints } = usePoints(initialPoints);
643
686
  const { stageScale, setStageScale, MAX_SCALE, MIN_SCALE } = useZoom(stageRef == null ? void 0 : stageRef.current);
644
687
  const SCALE_BY = 1.2;
645
688
  const [closed, setClosed] = useState(initialPoints.length >= 3);
@@ -647,11 +690,11 @@ var Mapper = ({
647
690
  const [stagePosition, setStagePosition] = useState({ x: 0, y: 0 });
648
691
  const [dragStart, setDragStart] = useState(null);
649
692
  const [isDraggingPoint, setIsDraggingPoint] = useState(false);
650
- const [image] = useImage(src, "anonymous");
693
+ const [image, imageStatus] = useImage(src, "anonymous", "no-referrer");
651
694
  const imgW = (image == null ? void 0 : image.width) || 1;
652
695
  const imgH = (image == null ? void 0 : image.height) || 1;
653
- const scale = maxWidth / imgW;
654
- const stageSize = { width: maxWidth, height: imgH * scale };
696
+ const scale = width / imgW;
697
+ const stageSize = { width, height: imgH * scale };
655
698
  const DRAG_THRESHOLD = 5;
656
699
  const LINE_HIT_THRESHOLD = 10;
657
700
  const handleZoomIn = () => {
@@ -770,6 +813,15 @@ var Mapper = ({
770
813
  }
771
814
  return null;
772
815
  };
816
+ const debouncedOnChange = useMemo(
817
+ () => onChange ? debounce(onChange, 200) : null,
818
+ [onChange]
819
+ );
820
+ useEffect(() => {
821
+ if (!debouncedOnChange) return;
822
+ debouncedOnChange(points);
823
+ return () => debouncedOnChange.cancel();
824
+ }, [points, debouncedOnChange]);
773
825
  useEffect(() => {
774
826
  if (image) {
775
827
  const initialPos = getConstrainedPosition({ x: 0, y: 0 }, 1);
@@ -843,6 +895,10 @@ var Mapper = ({
843
895
  );
844
896
  setPoints(updatedPoints);
845
897
  };
898
+ const handlePointReset = () => {
899
+ setClosed(false);
900
+ resetPoints();
901
+ };
846
902
  const handlePointDragEnd = (e) => {
847
903
  e.cancelBubble = true;
848
904
  setIsDraggingPoint(false);
@@ -917,13 +973,55 @@ var Mapper = ({
917
973
  const dist = Math.hypot(dx, dy);
918
974
  setHoveringFirst(dist < 15);
919
975
  };
920
- return /* @__PURE__ */ jsxs(Container, { children: [
976
+ return /* @__PURE__ */ jsxs(Container, { style: { width, height }, children: [
977
+ /* @__PURE__ */ jsxs(NavContainer, { children: [
978
+ /* @__PURE__ */ jsx(
979
+ Button,
980
+ {
981
+ onClick: handlePointReset,
982
+ disabled: !points.length,
983
+ title: "Reset Points",
984
+ children: /* @__PURE__ */ jsx(RotateCcw, { style: { width: "20px", height: "20px" } })
985
+ }
986
+ ),
987
+ /* @__PURE__ */ jsxs(NavBase, { children: [
988
+ /* @__PURE__ */ jsx(
989
+ Button,
990
+ {
991
+ onClick: handleZoomIn,
992
+ disabled: stageScale >= MAX_SCALE,
993
+ title: "Zoom In (Ctrl/Cmd + +)",
994
+ children: /* @__PURE__ */ jsx(ZoomIn, { style: { width: "20px", height: "20px" } })
995
+ }
996
+ ),
997
+ /* @__PURE__ */ jsx(
998
+ Button,
999
+ {
1000
+ onClick: handleZoomOut,
1001
+ disabled: stageScale <= MIN_SCALE,
1002
+ title: "Zoom Out (Ctrl/Cmd + -)",
1003
+ children: /* @__PURE__ */ jsx(ZoomOut, { style: { width: "20px", height: "20px" } })
1004
+ }
1005
+ ),
1006
+ /* @__PURE__ */ jsxs(
1007
+ Button,
1008
+ {
1009
+ onClick: handleResetZoom,
1010
+ title: "Reset Zoom (Ctrl/Cmd + 0)",
1011
+ children: [
1012
+ Math.round(stageScale * 100),
1013
+ "%"
1014
+ ]
1015
+ }
1016
+ )
1017
+ ] })
1018
+ ] }),
921
1019
  /* @__PURE__ */ jsx(CanvasContainer, { children: /* @__PURE__ */ jsx(
922
1020
  Stage,
923
1021
  {
924
1022
  ref: stageRef,
925
- width: 1200,
926
- height: 1200,
1023
+ width,
1024
+ height,
927
1025
  onMouseDown: handleStageMouseDown,
928
1026
  onMouseUp: handleStageMouseUp,
929
1027
  onMouseMove: handleMouseMove,
@@ -979,38 +1077,7 @@ var Mapper = ({
979
1077
  )) })
980
1078
  ] })
981
1079
  }
982
- ) }),
983
- /* @__PURE__ */ jsxs(NavContainer, { children: [
984
- /* @__PURE__ */ jsx(
985
- Button,
986
- {
987
- onClick: handleZoomIn,
988
- disabled: stageScale >= MAX_SCALE,
989
- title: "Zoom In (Ctrl/Cmd + +)",
990
- children: /* @__PURE__ */ jsx(ZoomIn, { style: { width: "20px", height: "20px" } })
991
- }
992
- ),
993
- /* @__PURE__ */ jsx(
994
- Button,
995
- {
996
- onClick: handleZoomOut,
997
- disabled: stageScale <= MIN_SCALE,
998
- title: "Zoom Out (Ctrl/Cmd + -)",
999
- children: /* @__PURE__ */ jsx(ZoomOut, { style: { width: "20px", height: "20px" } })
1000
- }
1001
- ),
1002
- /* @__PURE__ */ jsxs(
1003
- Button,
1004
- {
1005
- onClick: handleResetZoom,
1006
- title: "Reset Zoom (Ctrl/Cmd + 0)",
1007
- children: [
1008
- Math.round(stageScale * 100),
1009
- "%"
1010
- ]
1011
- }
1012
- )
1013
- ] })
1080
+ ) })
1014
1081
  ] });
1015
1082
  };
1016
1083