graphics-debug 0.0.40 → 0.0.42

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/lib/react.js CHANGED
@@ -8,8 +8,14 @@ import "../chunk-NG6H63SM.js";
8
8
  import "../chunk-A4VFIZRQ.js";
9
9
 
10
10
  // site/components/InteractiveGraphics/InteractiveGraphics.tsx
11
- import { compose, scale, translate } from "transformation-matrix";
12
- import { useMemo as useMemo7, useState as useState6 } from "react";
11
+ import {
12
+ compose,
13
+ scale,
14
+ translate,
15
+ inverse as inverse2,
16
+ applyToPoint as applyToPoint10
17
+ } from "transformation-matrix";
18
+ import { useMemo as useMemo7, useState as useState6, useEffect as useEffect3, useCallback } from "react";
13
19
  import useMouseMatrixTransform from "use-mouse-matrix-transform";
14
20
  import { SuperGrid } from "react-supergrid";
15
21
  import useResizeObserver from "@react-hook/resize-observer";
@@ -800,8 +806,144 @@ function getMaxStep(graphics) {
800
806
  return Math.max(maxPointStep, maxLineStep, maxRectStep, maxCircleStep);
801
807
  }
802
808
 
803
- // site/components/InteractiveGraphics/InteractiveGraphics.tsx
809
+ // site/components/InteractiveGraphics/ContextMenu.tsx
810
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
804
811
  import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
812
+ var ContextMenu = ({
813
+ x,
814
+ y,
815
+ onSaveCamera,
816
+ onClearCamera,
817
+ onAddMark,
818
+ onClearMarks,
819
+ onClose
820
+ }) => {
821
+ const menuRef = useRef2(null);
822
+ useEffect2(() => {
823
+ const handleClickOutside = (event) => {
824
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
825
+ onClose();
826
+ }
827
+ };
828
+ document.addEventListener("mousedown", handleClickOutside);
829
+ return () => {
830
+ document.removeEventListener("mousedown", handleClickOutside);
831
+ };
832
+ }, [onClose]);
833
+ const menuStyle = {
834
+ position: "absolute",
835
+ left: x,
836
+ top: y,
837
+ backgroundColor: "white",
838
+ border: "1px solid #ccc",
839
+ borderRadius: 3,
840
+ boxShadow: "0 2px 6px rgba(0,0,0,0.1)",
841
+ padding: 0,
842
+ zIndex: 1e3,
843
+ minWidth: 160,
844
+ fontSize: "12px"
845
+ };
846
+ const menuItemStyle = {
847
+ padding: "4px 8px",
848
+ cursor: "pointer",
849
+ userSelect: "none",
850
+ lineHeight: "1.5"
851
+ };
852
+ const handleItemHover = (e) => {
853
+ e.currentTarget.style.backgroundColor = "#f5f5f5";
854
+ };
855
+ const handleItemLeave = (e) => {
856
+ e.currentTarget.style.backgroundColor = "";
857
+ };
858
+ return /* @__PURE__ */ jsxs3("div", { ref: menuRef, style: menuStyle, children: [
859
+ /* @__PURE__ */ jsx7(
860
+ "div",
861
+ {
862
+ style: menuItemStyle,
863
+ onClick: () => {
864
+ onSaveCamera();
865
+ onClose();
866
+ },
867
+ onMouseEnter: handleItemHover,
868
+ onMouseLeave: handleItemLeave,
869
+ children: "Save Camera Position"
870
+ }
871
+ ),
872
+ /* @__PURE__ */ jsx7(
873
+ "div",
874
+ {
875
+ style: menuItemStyle,
876
+ onClick: () => {
877
+ onClearCamera();
878
+ onClose();
879
+ },
880
+ onMouseEnter: handleItemHover,
881
+ onMouseLeave: handleItemLeave,
882
+ children: "Clear Saved Camera Position"
883
+ }
884
+ ),
885
+ /* @__PURE__ */ jsx7(
886
+ "div",
887
+ {
888
+ style: menuItemStyle,
889
+ onClick: () => {
890
+ onAddMark();
891
+ onClose();
892
+ },
893
+ onMouseEnter: handleItemHover,
894
+ onMouseLeave: handleItemLeave,
895
+ children: "Add Mark"
896
+ }
897
+ ),
898
+ /* @__PURE__ */ jsx7(
899
+ "div",
900
+ {
901
+ style: menuItemStyle,
902
+ onClick: () => {
903
+ onClearMarks();
904
+ onClose();
905
+ },
906
+ onMouseEnter: handleItemHover,
907
+ onMouseLeave: handleItemLeave,
908
+ children: "Clear Marks"
909
+ }
910
+ )
911
+ ] });
912
+ };
913
+
914
+ // site/components/InteractiveGraphics/Marker.tsx
915
+ import { applyToPoint as applyToPoint9 } from "transformation-matrix";
916
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
917
+ var Marker = ({ marker, transform }) => {
918
+ const [screenX, screenY] = applyToPoint9(transform, [marker.x, marker.y]);
919
+ return /* @__PURE__ */ jsx8(
920
+ "svg",
921
+ {
922
+ style: {
923
+ position: "absolute",
924
+ top: 0,
925
+ left: 0,
926
+ pointerEvents: "none",
927
+ zIndex: 900
928
+ },
929
+ children: /* @__PURE__ */ jsxs4("g", { transform: `translate(${screenX}, ${screenY})`, children: [
930
+ /* @__PURE__ */ jsx8(
931
+ "circle",
932
+ {
933
+ r: 7,
934
+ fill: "rgba(255, 0, 0, 0.5)",
935
+ stroke: "rgba(255, 0, 0, 0.8)",
936
+ strokeWidth: 2
937
+ }
938
+ ),
939
+ /* @__PURE__ */ jsx8("circle", { r: 2, fill: "rgba(255, 0, 0, 0.9)" })
940
+ ] })
941
+ }
942
+ );
943
+ };
944
+
945
+ // site/components/InteractiveGraphics/InteractiveGraphics.tsx
946
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
805
947
  var InteractiveGraphics = ({
806
948
  graphics,
807
949
  onObjectClicked,
@@ -809,7 +951,10 @@ var InteractiveGraphics = ({
809
951
  }) => {
810
952
  const [activeLayers, setActiveLayers] = useState6(null);
811
953
  const [activeStep, setActiveStep] = useState6(null);
954
+ const [showLastStep, setShowLastStep] = useState6(true);
812
955
  const [size, setSize] = useState6({ width: 600, height: 600 });
956
+ const [contextMenu, setContextMenu] = useState6(null);
957
+ const [markers, setMarkers] = useState6([]);
813
958
  const availableLayers = Array.from(
814
959
  /* @__PURE__ */ new Set([
815
960
  ...graphics.lines?.map((l) => l.layer).filter(Boolean) ?? [],
@@ -829,8 +974,13 @@ var InteractiveGraphics = ({
829
974
  maxY: actualBounds.maxY + height / 10
830
975
  };
831
976
  }, [graphics]);
832
- const { transform: realToScreen, ref } = useMouseMatrixTransform({
833
- initialTransform: compose(
977
+ const getStorageKey = useCallback(() => {
978
+ const path = window.location.pathname;
979
+ const search = window.location.search;
980
+ return `saved-camera-position-${path}${search}`;
981
+ }, []);
982
+ const getDefaultTransform = useCallback(() => {
983
+ return compose(
834
984
  translate(size.width / 2, size.height / 2),
835
985
  scale(
836
986
  Math.min(
@@ -846,7 +996,29 @@ var InteractiveGraphics = ({
846
996
  -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,
847
997
  -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2
848
998
  )
849
- )
999
+ );
1000
+ }, [size, graphicsBoundsWithPadding]);
1001
+ const getSavedData = useCallback(() => {
1002
+ try {
1003
+ const savedData = localStorage.getItem(getStorageKey());
1004
+ if (savedData) {
1005
+ return JSON.parse(savedData);
1006
+ }
1007
+ } catch (error) {
1008
+ console.error("Error loading saved data:", error);
1009
+ }
1010
+ return null;
1011
+ }, [getStorageKey]);
1012
+ const getSavedTransform = useCallback(() => {
1013
+ const savedData = getSavedData();
1014
+ return savedData?.transform || null;
1015
+ }, [getSavedData]);
1016
+ const {
1017
+ transform: realToScreen,
1018
+ ref,
1019
+ setTransform
1020
+ } = useMouseMatrixTransform({
1021
+ initialTransform: getSavedTransform() || getDefaultTransform()
850
1022
  });
851
1023
  useResizeObserver(ref, (entry) => {
852
1024
  setSize({
@@ -854,9 +1026,93 @@ var InteractiveGraphics = ({
854
1026
  height: entry.contentRect.height
855
1027
  });
856
1028
  });
1029
+ useEffect3(() => {
1030
+ const savedData = getSavedData();
1031
+ if (savedData?.markers) {
1032
+ setMarkers(savedData.markers);
1033
+ }
1034
+ }, [getSavedData]);
1035
+ const handleContextMenu = useCallback((event) => {
1036
+ event.preventDefault();
1037
+ const mouseX = event.clientX;
1038
+ const mouseY = event.clientY;
1039
+ const rect = event.currentTarget.getBoundingClientRect();
1040
+ const elementX = rect.left;
1041
+ const elementY = rect.top;
1042
+ const viewportWidth = window.innerWidth;
1043
+ const viewportHeight = window.innerHeight;
1044
+ const menuWidth = 160;
1045
+ const menuHeight = 100;
1046
+ let x = mouseX - elementX;
1047
+ let y = mouseY - elementY;
1048
+ if (mouseX > viewportWidth / 2) {
1049
+ x = x - menuWidth;
1050
+ }
1051
+ if (mouseY > viewportHeight / 2) {
1052
+ y = y - menuHeight;
1053
+ }
1054
+ setContextMenu({
1055
+ x,
1056
+ y,
1057
+ clientX: mouseX,
1058
+ clientY: mouseY
1059
+ });
1060
+ }, []);
1061
+ const saveToLocalStorage = useCallback(
1062
+ (transform, markerPoints) => {
1063
+ try {
1064
+ const dataToSave = {
1065
+ transform,
1066
+ markers: markerPoints
1067
+ };
1068
+ localStorage.setItem(getStorageKey(), JSON.stringify(dataToSave));
1069
+ } catch (error) {
1070
+ console.error("Error saving data:", error);
1071
+ }
1072
+ },
1073
+ [getStorageKey]
1074
+ );
1075
+ const handleSaveCamera = useCallback(() => {
1076
+ saveToLocalStorage(realToScreen, markers);
1077
+ }, [saveToLocalStorage, realToScreen, markers]);
1078
+ const handleClearCamera = useCallback(() => {
1079
+ try {
1080
+ const defaultTransform = getDefaultTransform();
1081
+ saveToLocalStorage(defaultTransform, markers);
1082
+ setTransform(defaultTransform);
1083
+ } catch (error) {
1084
+ console.error("Error clearing camera position:", error);
1085
+ }
1086
+ }, [saveToLocalStorage, getDefaultTransform, setTransform, markers]);
1087
+ const handleAddMark = useCallback(() => {
1088
+ if (!contextMenu) return;
1089
+ try {
1090
+ const screenPoint = { x: contextMenu.clientX, y: contextMenu.clientY };
1091
+ const rect = ref.current?.getBoundingClientRect();
1092
+ if (rect) {
1093
+ const screenX = screenPoint.x - rect.left;
1094
+ const screenY = screenPoint.y - rect.top;
1095
+ const inverseTransform = inverse2(realToScreen);
1096
+ const [realX, realY] = applyToPoint10(inverseTransform, [
1097
+ screenX,
1098
+ screenY
1099
+ ]);
1100
+ const newMarker = { x: realX, y: realY };
1101
+ const newMarkers = [...markers, newMarker];
1102
+ setMarkers(newMarkers);
1103
+ saveToLocalStorage(realToScreen, newMarkers);
1104
+ }
1105
+ } catch (error) {
1106
+ console.error("Error adding marker:", error);
1107
+ }
1108
+ }, [contextMenu, ref, realToScreen, markers, saveToLocalStorage]);
1109
+ const handleClearMarks = useCallback(() => {
1110
+ setMarkers([]);
1111
+ saveToLocalStorage(realToScreen, []);
1112
+ }, [realToScreen, saveToLocalStorage]);
857
1113
  const interactiveState = {
858
1114
  activeLayers,
859
- activeStep,
1115
+ activeStep: showLastStep ? maxStep : activeStep,
860
1116
  realToScreen,
861
1117
  onObjectClicked
862
1118
  };
@@ -869,7 +1125,8 @@ var InteractiveGraphics = ({
869
1125
  const filterLayerAndStep = (obj) => {
870
1126
  if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))
871
1127
  return false;
872
- if (activeStep !== null && obj.step !== void 0 && obj.step !== activeStep)
1128
+ const selectedStep = showLastStep ? maxStep : activeStep;
1129
+ if (selectedStep !== null && obj.step !== void 0 && obj.step !== selectedStep)
873
1130
  return false;
874
1131
  return true;
875
1132
  };
@@ -913,9 +1170,9 @@ var InteractiveGraphics = ({
913
1170
  );
914
1171
  const totalFilteredObjects = filteredLines.length + filteredRects.length + filteredPoints.length + filteredCircles.length;
915
1172
  const isLimitReached = objectLimit && totalFilteredObjects > objectLimit;
916
- return /* @__PURE__ */ jsxs3("div", { children: [
917
- showToolbar && /* @__PURE__ */ jsxs3("div", { style: { margin: 8 }, children: [
918
- availableLayers.length > 1 && /* @__PURE__ */ jsxs3(
1173
+ return /* @__PURE__ */ jsxs5("div", { children: [
1174
+ showToolbar && /* @__PURE__ */ jsxs5("div", { style: { margin: 8 }, children: [
1175
+ availableLayers.length > 1 && /* @__PURE__ */ jsxs5(
919
1176
  "select",
920
1177
  {
921
1178
  value: activeLayers ? activeLayers[0] : "",
@@ -925,18 +1182,18 @@ var InteractiveGraphics = ({
925
1182
  },
926
1183
  style: { marginRight: 8 },
927
1184
  children: [
928
- /* @__PURE__ */ jsx7("option", { value: "", children: "All Layers" }),
929
- availableLayers.map((layer) => /* @__PURE__ */ jsx7("option", { value: layer, children: layer }, layer))
1185
+ /* @__PURE__ */ jsx9("option", { value: "", children: "All Layers" }),
1186
+ availableLayers.map((layer) => /* @__PURE__ */ jsx9("option", { value: layer, children: layer }, layer))
930
1187
  ]
931
1188
  }
932
1189
  ),
933
- maxStep > 0 && /* @__PURE__ */ jsxs3(
1190
+ maxStep > 0 && /* @__PURE__ */ jsxs5(
934
1191
  "div",
935
1192
  {
936
1193
  style: { display: "inline-flex", alignItems: "center", gap: 8 },
937
1194
  children: [
938
1195
  "Step:",
939
- /* @__PURE__ */ jsx7(
1196
+ /* @__PURE__ */ jsx9(
940
1197
  "input",
941
1198
  {
942
1199
  type: "number",
@@ -945,26 +1202,43 @@ var InteractiveGraphics = ({
945
1202
  value: activeStep ?? 0,
946
1203
  onChange: (e) => {
947
1204
  const value = parseInt(e.target.value);
1205
+ setShowLastStep(false);
948
1206
  setActiveStep(Number.isNaN(value) ? null : value);
949
1207
  },
950
1208
  disabled: activeStep === null
951
1209
  }
952
1210
  ),
953
- /* @__PURE__ */ jsxs3("label", { children: [
954
- /* @__PURE__ */ jsx7(
1211
+ /* @__PURE__ */ jsxs5("label", { children: [
1212
+ /* @__PURE__ */ jsx9(
955
1213
  "input",
956
1214
  {
957
1215
  type: "checkbox",
958
1216
  style: { marginRight: 4 },
959
1217
  checked: activeStep !== null,
960
1218
  onChange: (e) => {
1219
+ setShowLastStep(false);
961
1220
  setActiveStep(e.target.checked ? 0 : null);
962
1221
  }
963
1222
  }
964
1223
  ),
965
1224
  "Filter by step"
966
1225
  ] }),
967
- isLimitReached && /* @__PURE__ */ jsxs3("span", { style: { color: "red", fontSize: "12px" }, children: [
1226
+ /* @__PURE__ */ jsxs5("label", { children: [
1227
+ /* @__PURE__ */ jsx9(
1228
+ "input",
1229
+ {
1230
+ type: "checkbox",
1231
+ style: { marginRight: 4 },
1232
+ checked: showLastStep,
1233
+ onChange: (e) => {
1234
+ setShowLastStep(e.target.checked);
1235
+ setActiveStep(null);
1236
+ }
1237
+ }
1238
+ ),
1239
+ "Show last step"
1240
+ ] }),
1241
+ isLimitReached && /* @__PURE__ */ jsxs5("span", { style: { color: "red", fontSize: "12px" }, children: [
968
1242
  "Display limited to ",
969
1243
  objectLimit,
970
1244
  " objects. Received:",
@@ -976,7 +1250,7 @@ var InteractiveGraphics = ({
976
1250
  }
977
1251
  )
978
1252
  ] }),
979
- /* @__PURE__ */ jsx7(
1253
+ /* @__PURE__ */ jsxs5(
980
1254
  "div",
981
1255
  {
982
1256
  ref,
@@ -985,60 +1259,84 @@ var InteractiveGraphics = ({
985
1259
  height: 600,
986
1260
  overflow: "hidden"
987
1261
  },
988
- children: /* @__PURE__ */ jsxs3(DimensionOverlay, { transform: realToScreen, children: [
989
- filteredLines.map((line) => /* @__PURE__ */ jsx7(
990
- Line,
991
- {
992
- line,
993
- index: line.originalIndex,
994
- interactiveState
995
- },
996
- line.originalIndex
997
- )),
998
- filteredRects.map((rect) => /* @__PURE__ */ jsx7(
999
- Rect,
1000
- {
1001
- rect,
1002
- index: rect.originalIndex,
1003
- interactiveState
1004
- },
1005
- rect.originalIndex
1006
- )),
1007
- filteredPoints.map((point) => /* @__PURE__ */ jsx7(
1008
- Point,
1009
- {
1010
- point,
1011
- index: point.originalIndex,
1012
- interactiveState
1013
- },
1014
- point.originalIndex
1015
- )),
1016
- filteredCircles.map((circle) => /* @__PURE__ */ jsx7(
1017
- Circle,
1262
+ onContextMenu: handleContextMenu,
1263
+ children: [
1264
+ /* @__PURE__ */ jsxs5(DimensionOverlay, { transform: realToScreen, children: [
1265
+ filteredLines.map((line) => /* @__PURE__ */ jsx9(
1266
+ Line,
1267
+ {
1268
+ line,
1269
+ index: line.originalIndex,
1270
+ interactiveState
1271
+ },
1272
+ line.originalIndex
1273
+ )),
1274
+ filteredRects.map((rect) => /* @__PURE__ */ jsx9(
1275
+ Rect,
1276
+ {
1277
+ rect,
1278
+ index: rect.originalIndex,
1279
+ interactiveState
1280
+ },
1281
+ rect.originalIndex
1282
+ )),
1283
+ filteredPoints.map((point) => /* @__PURE__ */ jsx9(
1284
+ Point,
1285
+ {
1286
+ point,
1287
+ index: point.originalIndex,
1288
+ interactiveState
1289
+ },
1290
+ point.originalIndex
1291
+ )),
1292
+ filteredCircles.map((circle) => /* @__PURE__ */ jsx9(
1293
+ Circle,
1294
+ {
1295
+ circle,
1296
+ index: circle.originalIndex,
1297
+ interactiveState
1298
+ },
1299
+ circle.originalIndex
1300
+ )),
1301
+ /* @__PURE__ */ jsx9(
1302
+ SuperGrid,
1303
+ {
1304
+ stringifyCoord: (x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`,
1305
+ width: size.width,
1306
+ height: size.height,
1307
+ transform: realToScreen
1308
+ }
1309
+ )
1310
+ ] }),
1311
+ markers.map((marker, index) => /* @__PURE__ */ jsx9(
1312
+ Marker,
1018
1313
  {
1019
- circle,
1020
- index: circle.originalIndex,
1021
- interactiveState
1314
+ marker,
1315
+ index,
1316
+ transform: realToScreen
1022
1317
  },
1023
- circle.originalIndex
1318
+ index
1024
1319
  )),
1025
- /* @__PURE__ */ jsx7(
1026
- SuperGrid,
1320
+ contextMenu && /* @__PURE__ */ jsx9(
1321
+ ContextMenu,
1027
1322
  {
1028
- stringifyCoord: (x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`,
1029
- width: size.width,
1030
- height: size.height,
1031
- transform: realToScreen
1323
+ x: contextMenu.x,
1324
+ y: contextMenu.y,
1325
+ onSaveCamera: handleSaveCamera,
1326
+ onClearCamera: handleClearCamera,
1327
+ onAddMark: handleAddMark,
1328
+ onClearMarks: handleClearMarks,
1329
+ onClose: () => setContextMenu(null)
1032
1330
  }
1033
1331
  )
1034
- ] })
1332
+ ]
1035
1333
  }
1036
1334
  )
1037
1335
  ] });
1038
1336
  };
1039
1337
 
1040
1338
  // site/components/InteractiveGraphicsCanvas.tsx
1041
- import { useRef as useRef2, useEffect as useEffect2, useState as useState7 } from "react";
1339
+ import { useRef as useRef3, useEffect as useEffect4, useState as useState7 } from "react";
1042
1340
  import useMouseMatrixTransform2 from "use-mouse-matrix-transform";
1043
1341
  import { compose as compose2, scale as scale2, translate as translate2 } from "transformation-matrix";
1044
1342
  import useResizeObserver2 from "@react-hook/resize-observer";
@@ -1085,7 +1383,7 @@ function getGraphicsBoundsWithPadding(graphics) {
1085
1383
  }
1086
1384
 
1087
1385
  // site/components/InteractiveGraphicsCanvas.tsx
1088
- import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1386
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1089
1387
  function InteractiveGraphicsCanvas({
1090
1388
  graphics,
1091
1389
  showLabelsByDefault = true,
@@ -1093,8 +1391,8 @@ function InteractiveGraphicsCanvas({
1093
1391
  height = 500,
1094
1392
  width = "100%"
1095
1393
  }) {
1096
- const canvasRef = useRef2(null);
1097
- const containerRef = useRef2(null);
1394
+ const canvasRef = useRef3(null);
1395
+ const containerRef = useRef3(null);
1098
1396
  const [size, setSize] = useState7({ width: 600, height: 600 });
1099
1397
  const [activeStep, setActiveStep] = useState7(null);
1100
1398
  const [showLabels, setShowLabels] = useState7(showLabelsByDefault);
@@ -1190,14 +1488,14 @@ function InteractiveGraphicsCanvas({
1190
1488
  y: matrix.b * point.x + matrix.d * point.y + matrix.f
1191
1489
  };
1192
1490
  };
1193
- useEffect2(() => {
1491
+ useEffect4(() => {
1194
1492
  drawCanvas();
1195
1493
  }, [transform, size, filteredGraphics, showGrid, showLabels]);
1196
- return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
1197
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [
1198
- /* @__PURE__ */ jsxs4("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
1199
- /* @__PURE__ */ jsxs4("label", { children: [
1200
- /* @__PURE__ */ jsx8(
1494
+ return /* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
1495
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [
1496
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
1497
+ /* @__PURE__ */ jsxs6("label", { children: [
1498
+ /* @__PURE__ */ jsx10(
1201
1499
  "input",
1202
1500
  {
1203
1501
  type: "checkbox",
@@ -1210,7 +1508,7 @@ function InteractiveGraphicsCanvas({
1210
1508
  ),
1211
1509
  "Filter by step"
1212
1510
  ] }),
1213
- /* @__PURE__ */ jsx8(
1511
+ /* @__PURE__ */ jsx10(
1214
1512
  "input",
1215
1513
  {
1216
1514
  type: "number",
@@ -1226,8 +1524,8 @@ function InteractiveGraphicsCanvas({
1226
1524
  style: { width: "60px" }
1227
1525
  }
1228
1526
  ),
1229
- /* @__PURE__ */ jsxs4("label", { children: [
1230
- /* @__PURE__ */ jsx8(
1527
+ /* @__PURE__ */ jsxs6("label", { children: [
1528
+ /* @__PURE__ */ jsx10(
1231
1529
  "input",
1232
1530
  {
1233
1531
  type: "checkbox",
@@ -1242,8 +1540,8 @@ function InteractiveGraphicsCanvas({
1242
1540
  "Show last step"
1243
1541
  ] })
1244
1542
  ] }),
1245
- /* @__PURE__ */ jsx8("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: /* @__PURE__ */ jsxs4("label", { children: [
1246
- /* @__PURE__ */ jsx8(
1543
+ /* @__PURE__ */ jsx10("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: /* @__PURE__ */ jsxs6("label", { children: [
1544
+ /* @__PURE__ */ jsx10(
1247
1545
  "input",
1248
1546
  {
1249
1547
  type: "checkbox",
@@ -1257,7 +1555,7 @@ function InteractiveGraphicsCanvas({
1257
1555
  "Show labels"
1258
1556
  ] }) })
1259
1557
  ] }),
1260
- /* @__PURE__ */ jsx8(
1558
+ /* @__PURE__ */ jsx10(
1261
1559
  "div",
1262
1560
  {
1263
1561
  ref: (node) => {
@@ -1273,7 +1571,7 @@ function InteractiveGraphicsCanvas({
1273
1571
  border: "1px solid #ccc",
1274
1572
  overflow: "hidden"
1275
1573
  },
1276
- children: /* @__PURE__ */ jsx8(
1574
+ children: /* @__PURE__ */ jsx10(
1277
1575
  "canvas",
1278
1576
  {
1279
1577
  ref: canvasRef,
@@ -1292,11 +1590,11 @@ function InteractiveGraphicsCanvas({
1292
1590
  }
1293
1591
 
1294
1592
  // site/components/CanvasGraphics/CanvasGraphics.tsx
1295
- import React3, { useRef as useRef3, useEffect as useEffect3, useState as useState8 } from "react";
1593
+ import React3, { useRef as useRef4, useEffect as useEffect5, useState as useState8 } from "react";
1296
1594
  import useMouseMatrixTransform3 from "use-mouse-matrix-transform";
1297
1595
  import { compose as compose3, scale as scale3, translate as translate3 } from "transformation-matrix";
1298
1596
  import useResizeObserver3 from "@react-hook/resize-observer";
1299
- import { jsx as jsx9 } from "react/jsx-runtime";
1597
+ import { jsx as jsx11 } from "react/jsx-runtime";
1300
1598
  function TransformContainer({
1301
1599
  initialTransform,
1302
1600
  children,
@@ -1305,10 +1603,10 @@ function TransformContainer({
1305
1603
  const { transform, ref } = useMouseMatrixTransform3({
1306
1604
  initialTransform
1307
1605
  });
1308
- useEffect3(() => {
1606
+ useEffect5(() => {
1309
1607
  onTransformChange(transform);
1310
1608
  }, [transform, onTransformChange]);
1311
- return /* @__PURE__ */ jsx9(
1609
+ return /* @__PURE__ */ jsx11(
1312
1610
  "div",
1313
1611
  {
1314
1612
  ref,
@@ -1329,8 +1627,8 @@ var CanvasGraphics = ({
1329
1627
  disableLabels = false,
1330
1628
  initialTransform
1331
1629
  }) => {
1332
- const canvasRef = useRef3(null);
1333
- const containerRef = useRef3(null);
1630
+ const canvasRef = useRef4(null);
1631
+ const containerRef = useRef4(null);
1334
1632
  const [size, setSize] = useState8({ width, height });
1335
1633
  const [currentTransform, setCurrentTransform] = useState8(null);
1336
1634
  const graphicsBoundsWithPadding = React3.useMemo(() => {
@@ -1438,13 +1736,13 @@ var CanvasGraphics = ({
1438
1736
  y: matrix.b * point.x + matrix.d * point.y + matrix.f
1439
1737
  };
1440
1738
  };
1441
- useEffect3(() => {
1739
+ useEffect5(() => {
1442
1740
  drawCanvas();
1443
1741
  }, [drawCanvas]);
1444
- useEffect3(() => {
1742
+ useEffect5(() => {
1445
1743
  setCurrentTransform(computedInitialTransform);
1446
1744
  }, [computedInitialTransform]);
1447
- return /* @__PURE__ */ jsx9(
1745
+ return /* @__PURE__ */ jsx11(
1448
1746
  "div",
1449
1747
  {
1450
1748
  ref: containerRef,
@@ -1455,16 +1753,16 @@ var CanvasGraphics = ({
1455
1753
  border: "1px solid #eee",
1456
1754
  overflow: "hidden"
1457
1755
  },
1458
- children: /* @__PURE__ */ jsx9(
1756
+ children: /* @__PURE__ */ jsx11(
1459
1757
  TransformContainer,
1460
1758
  {
1461
1759
  initialTransform: computedInitialTransform,
1462
1760
  onTransformChange: handleTransformChange,
1463
- children: /* @__PURE__ */ jsx9(
1761
+ children: /* @__PURE__ */ jsx11(
1464
1762
  DimensionOverlay,
1465
1763
  {
1466
1764
  transform: currentTransform || computedInitialTransform,
1467
- children: /* @__PURE__ */ jsx9(
1765
+ children: /* @__PURE__ */ jsx11(
1468
1766
  "canvas",
1469
1767
  {
1470
1768
  ref: canvasRef,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../site/components/InteractiveGraphics/InteractiveGraphics.tsx","../../site/components/InteractiveGraphics/Line.tsx","../../site/components/InteractiveGraphics/Tooltip.tsx","../../site/utils/distToLineSegment.ts","../../site/utils/safeLighten.ts","../../site/components/InteractiveGraphics/Point.tsx","../../site/components/InteractiveGraphics/Rect.tsx","../../site/components/InteractiveGraphics/Circle.tsx","../../site/utils/getGraphicsBounds.ts","../../site/components/InteractiveGraphics/hooks/useIsPointOnScreen.ts","../../site/components/InteractiveGraphics/hooks/useDoesLineIntersectViewport.ts","../../site/components/InteractiveGraphics/hooks/useFilterLines.ts","../../site/components/InteractiveGraphics/hooks/useFilterPoints.ts","../../site/components/InteractiveGraphics/hooks/useFilterRects.ts","../../site/components/InteractiveGraphics/hooks/useFilterCircles.ts","../../site/components/DimensionOverlay.tsx","../../site/utils/getMaxStep.ts","../../site/components/InteractiveGraphicsCanvas.tsx","../../site/utils/getGraphicsFilteredByStep.ts","../../site/utils/getGraphicsBoundsWithPadding.ts","../../site/components/CanvasGraphics/CanvasGraphics.tsx"],"sourcesContent":["import { compose, scale, translate } from \"transformation-matrix\"\nimport { GraphicsObject } from \"../../../lib\"\nimport { useMemo, useState } from \"react\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { InteractiveState } from \"./InteractiveState\"\nimport { SuperGrid } from \"react-supergrid\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { Line } from \"./Line\"\nimport { Point } from \"./Point\"\nimport { Rect } from \"./Rect\"\nimport { Circle } from \"./Circle\"\nimport { getGraphicsBounds } from \"site/utils/getGraphicsBounds\"\nimport {\n useIsPointOnScreen,\n useDoesLineIntersectViewport,\n useFilterLines,\n useFilterPoints,\n useFilterRects,\n useFilterCircles,\n} from \"./hooks\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\nimport { getMaxStep } from \"site/utils/getMaxStep\"\n\nexport type GraphicsObjectClickEvent = {\n type: \"point\" | \"line\" | \"rect\" | \"circle\"\n index: number\n object: any\n}\n\nexport const InteractiveGraphics = ({\n graphics,\n onObjectClicked,\n objectLimit,\n}: {\n graphics: GraphicsObject\n onObjectClicked?: (event: GraphicsObjectClickEvent) => void\n objectLimit?: number\n}) => {\n const [activeLayers, setActiveLayers] = useState<string[] | null>(null)\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const availableLayers: string[] = Array.from(\n new Set([\n ...(graphics.lines?.map((l) => l.layer!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.layer!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.layer!).filter(Boolean) ?? []),\n ]),\n )\n const maxStep = getMaxStep(graphics)\n\n const graphicsBoundsWithPadding = useMemo(() => {\n const actualBounds = getGraphicsBounds(graphics)\n const width = actualBounds.maxX - actualBounds.minX\n const height = actualBounds.maxY - actualBounds.minY\n return {\n minX: actualBounds.minX - width / 10,\n minY: actualBounds.minY - height / 10,\n maxX: actualBounds.maxX + width / 10,\n maxY: actualBounds.maxY + height / 10,\n }\n }, [graphics])\n\n const { transform: realToScreen, ref } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n useResizeObserver(ref, (entry: ResizeObserverEntry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n const interactiveState: InteractiveState = {\n activeLayers: activeLayers,\n activeStep: activeStep,\n realToScreen: realToScreen,\n onObjectClicked: onObjectClicked,\n }\n\n const showToolbar = availableLayers.length > 1 || maxStep > 0\n\n // Use custom hooks for visibility checks and filtering\n const isPointOnScreen = useIsPointOnScreen(realToScreen, size)\n\n const doesLineIntersectViewport = useDoesLineIntersectViewport(\n realToScreen,\n size,\n )\n\n // Filter by layer and step\n const filterLayerAndStep = (obj: { layer?: string; step?: number }) => {\n if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))\n return false\n if (\n activeStep !== null &&\n obj.step !== undefined &&\n obj.step !== activeStep\n )\n return false\n return true\n }\n\n const filterLines = useFilterLines(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterPoints = useFilterPoints(isPointOnScreen, filterLayerAndStep)\n\n const filterRects = useFilterRects(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterCircles = useFilterCircles(\n isPointOnScreen,\n filterLayerAndStep,\n realToScreen,\n size,\n )\n\n const filterAndLimit = <T,>(\n objects: T[] | undefined,\n filterFn: (obj: T) => boolean,\n ): (T & { originalIndex: number })[] => {\n if (!objects) return []\n const filtered = objects\n .map((obj, index) => ({ ...obj, originalIndex: index }))\n .filter(filterFn)\n return objectLimit ? filtered.slice(-objectLimit) : filtered\n }\n\n const filteredLines = useMemo(\n () => filterAndLimit(graphics.lines, filterLines),\n [graphics.lines, filterLines, objectLimit],\n )\n const filteredRects = useMemo(\n () => filterAndLimit(graphics.rects, filterRects),\n [graphics.rects, filterRects, objectLimit],\n )\n const filteredPoints = useMemo(\n () => filterAndLimit(graphics.points, filterPoints),\n [graphics.points, filterPoints, objectLimit],\n )\n const filteredCircles = useMemo(\n () => filterAndLimit(graphics.circles, filterCircles),\n [graphics.circles, filterCircles, objectLimit],\n )\n\n const totalFilteredObjects =\n filteredLines.length +\n filteredRects.length +\n filteredPoints.length +\n filteredCircles.length\n const isLimitReached = objectLimit && totalFilteredObjects > objectLimit\n\n return (\n <div>\n {showToolbar && (\n <div style={{ margin: 8 }}>\n {availableLayers.length > 1 && (\n <select\n value={activeLayers ? activeLayers[0] : \"\"}\n onChange={(e) => {\n const value = e.target.value\n setActiveLayers(value === \"\" ? null : [value])\n }}\n style={{ marginRight: 8 }}\n >\n <option value=\"\">All Layers</option>\n {availableLayers.map((layer) => (\n <option key={layer} value={layer}>\n {layer}\n </option>\n ))}\n </select>\n )}\n\n {maxStep > 0 && (\n <div\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8 }}\n >\n Step:\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setActiveStep(Number.isNaN(value) ? null : value)\n }}\n disabled={activeStep === null}\n />\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n {isLimitReached && (\n <span style={{ color: \"red\", fontSize: \"12px\" }}>\n Display limited to {objectLimit} objects. Received:{\" \"}\n {totalFilteredObjects}.\n </span>\n )}\n </div>\n )}\n </div>\n )}\n\n <div\n ref={ref}\n style={{\n position: \"relative\",\n height: 600,\n overflow: \"hidden\",\n }}\n >\n <DimensionOverlay transform={realToScreen}>\n {filteredLines.map((line) => (\n <Line\n key={line.originalIndex}\n line={line}\n index={line.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredRects.map((rect) => (\n <Rect\n key={rect.originalIndex}\n rect={rect}\n index={rect.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredPoints.map((point) => (\n <Point\n key={point.originalIndex}\n point={point}\n index={point.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredCircles.map((circle) => (\n <Circle\n key={circle.originalIndex}\n circle={circle}\n index={circle.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n <SuperGrid\n stringifyCoord={(x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`}\n width={size.width}\n height={size.height}\n transform={realToScreen}\n />\n </DimensionOverlay>\n </div>\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { distToLineSegment } from \"site/utils/distToLineSegment\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Line = ({\n line,\n index,\n interactiveState,\n}: { line: Types.Line; index: number; interactiveState: InteractiveState }) => {\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const {\n points,\n layer,\n step,\n strokeColor,\n strokeWidth = 1 / realToScreen.a,\n strokeDash,\n } = line\n const [isHovered, setIsHovered] = useState(false)\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 })\n\n const screenPoints = points.map((p) => applyToPoint(realToScreen, p))\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const hoverThreshold = 10 // pixels\n\n setMousePos({ x: mouseX, y: mouseY })\n\n // Check distance to each line segment\n let isNearLine = false\n for (let i = 0; i < screenPoints.length - 1; i++) {\n const dist = distToLineSegment(\n mouseX,\n mouseY,\n screenPoints[i].x,\n screenPoints[i].y,\n screenPoints[i + 1].x,\n screenPoints[i + 1].y,\n )\n if (dist < hoverThreshold) {\n isNearLine = true\n break\n }\n }\n\n setIsHovered(isNearLine)\n }\n\n const baseColor = strokeColor ?? defaultColors[index % defaultColors.length]\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setIsHovered(false)}\n onClick={\n isHovered\n ? () =>\n onObjectClicked?.({\n type: \"line\",\n index,\n object: line,\n })\n : undefined\n }\n >\n <polyline\n points={screenPoints.map((p) => `${p.x},${p.y}`).join(\" \")}\n stroke={isHovered ? safeLighten(0.2, baseColor) : baseColor}\n fill=\"none\"\n strokeWidth={strokeWidth * realToScreen.a}\n strokeDasharray={\n !strokeDash\n ? undefined\n : typeof strokeDash === \"string\"\n ? strokeDash\n : `${strokeDash[0] * realToScreen.a}, ${strokeDash[1] * realToScreen.a}`\n }\n strokeLinecap=\"round\"\n />\n {isHovered && line.label && (\n <foreignObject\n x={mousePos.x}\n y={mousePos.y - 40}\n width={300}\n height={40}\n >\n <Tooltip text={line.label} />\n </foreignObject>\n )}\n </svg>\n )\n}\n","export const Tooltip = ({ text }: { text: string }) => {\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #ccc\",\n boxShadow: \"0 0 10px 0 rgba(0, 0, 0, 0.1)\",\n borderRadius: \"4px\",\n padding: \"4px 8px\",\n fontSize: \"12px\",\n minWidth: \"150px\",\n maxWidth: \"300px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"pre-wrap\",\n zIndex: 100,\n }}\n >\n {text}\n </div>\n )\n}\n","// Calculate distance from point to line segment\nexport const distToLineSegment = (\n px: number,\n py: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n) => {\n const A = px - x1\n const B = py - y1\n const C = x2 - x1\n const D = y2 - y1\n\n const dot = A * C + B * D\n const lenSq = C * C + D * D\n let param = -1\n\n if (lenSq !== 0) param = dot / lenSq\n\n let xx = 0\n let yy = 0\n\n if (param < 0) {\n xx = x1\n yy = y1\n } else if (param > 1) {\n xx = x2\n yy = y2\n } else {\n xx = x1 + param * C\n yy = y1 + param * D\n }\n\n const dx = px - xx\n const dy = py - yy\n return Math.sqrt(dx * dx + dy * dy)\n}\n","import { lighten } from \"polished\"\n\nexport const safeLighten = (amount: number, color: string) => {\n try {\n return lighten(amount, color)\n } catch (e) {\n return color\n }\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Point = ({\n point,\n interactiveState,\n index,\n}: {\n point: Types.Point\n interactiveState: InteractiveState\n index: number\n}) => {\n const { color, label, layer, step } = point\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenPoint = applyToPoint(realToScreen, point)\n const size = 10\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenPoint.x - size / 2,\n top: screenPoint.y - size / 2,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${\n isHovered\n ? safeLighten(\n 0.2,\n color ?? defaultColors[index % defaultColors.length],\n )\n : (color ?? defaultColors[index % defaultColors.length])\n }`,\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"point\",\n index,\n object: point,\n })\n }\n >\n {isHovered && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip\n text={`${label ? `${label}\\n` : \"\"}x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`}\n />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Rect = ({\n rect,\n interactiveState,\n index,\n}: {\n rect: Types.Rect\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, width, height, fill, stroke, layer, step } = rect\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenCenter = applyToPoint(realToScreen, center)\n const screenWidth = width * realToScreen.a\n const screenHeight = height * Math.abs(realToScreen.d)\n\n // Default style when neither fill nor stroke is specified\n const hasStrokeOrFill = fill !== undefined || stroke !== undefined\n\n let backgroundColor = hasStrokeOrFill ? fill || \"transparent\" : defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = safeLighten(0.2, stroke!)\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenWidth / 2,\n top: screenCenter.y - screenHeight / 2,\n width: screenWidth,\n height: screenHeight,\n backgroundColor,\n border: stroke\n ? `2px solid ${isHovered ? safeLighten(0.2, stroke) : stroke}`\n : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"rect\",\n index,\n object: rect,\n })\n }\n >\n {isHovered && rect.label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={rect.label} />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Circle = ({\n circle,\n interactiveState,\n index,\n}: {\n circle: Types.Circle\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, radius, fill, stroke, layer, step, label } = circle\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n const screenCenter = applyToPoint(realToScreen, center)\n const screenRadius = radius * realToScreen.a\n let backgroundColor = fill || defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = stroke ? safeLighten(0.2, stroke) : stroke\n }\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenRadius,\n top: screenCenter.y - screenRadius,\n width: screenRadius * 2,\n height: screenRadius * 2,\n borderRadius: \"50%\",\n backgroundColor,\n border: stroke ? `2px solid ${stroke}` : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"circle\",\n index,\n object: circle,\n })\n }\n >\n {isHovered && label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={label} />\n </div>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport const getGraphicsBounds = (graphics: GraphicsObject) => {\n const bounds = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n }\n for (const line of graphics.lines ?? []) {\n for (const point of line.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n }\n for (const rect of graphics.rects ?? []) {\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n bounds.minX = Math.min(bounds.minX, center.x - halfWidth)\n bounds.minY = Math.min(bounds.minY, center.y - halfHeight)\n bounds.maxX = Math.max(bounds.maxX, center.x + halfWidth)\n bounds.maxY = Math.max(bounds.maxY, center.y + halfHeight)\n }\n for (const point of graphics.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n return bounds\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\nexport const useIsPointOnScreen = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (point: { x: number; y: number }) => {\n const screenPoint = applyToPoint(realToScreen, point)\n return (\n screenPoint.x >= -OFFSCREEN_MARGIN &&\n screenPoint.x <= size.width + OFFSCREEN_MARGIN &&\n screenPoint.y >= -OFFSCREEN_MARGIN &&\n screenPoint.y <= size.height + OFFSCREEN_MARGIN\n )\n }\n }, [realToScreen, size])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\n\n// Margin in pixels for determining if elements are off-screen\nexport const OFFSCREEN_MARGIN = 5\n\nexport const useDoesLineIntersectViewport = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (p1: { x: number; y: number }, p2: { x: number; y: number }) => {\n // Convert real-world points to screen coordinates\n const sp1 = applyToPoint(realToScreen, p1)\n const sp2 = applyToPoint(realToScreen, p2)\n\n // Viewport boundaries with margin\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // If either point is inside the viewport, the line intersects\n if (\n (sp1.x >= left && sp1.x <= right && sp1.y >= top && sp1.y <= bottom) ||\n (sp2.x >= left && sp2.x <= right && sp2.y >= top && sp2.y <= bottom)\n ) {\n return true\n }\n\n // Helper function to check if a line intersects with a line segment\n const intersects = (\n a1: { x: number; y: number },\n a2: { x: number; y: number },\n b1: { x: number; y: number },\n b2: { x: number; y: number },\n ) => {\n // Line segment A is (a1, a2), line segment B is (b1, b2)\n const det =\n (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x)\n\n // If lines are parallel or coincident, they don't intersect in a unique point\n if (det === 0) return false\n\n const lambda =\n ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det\n const gamma =\n ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det\n\n // Check if the intersection point is within both line segments\n return lambda >= 0 && lambda <= 1 && gamma >= 0 && gamma <= 1\n }\n\n // Check intersection with each edge of the viewport\n return (\n // Top edge\n intersects(sp1, sp2, { x: left, y: top }, { x: right, y: top }) ||\n // Right edge\n intersects(sp1, sp2, { x: right, y: top }, { x: right, y: bottom }) ||\n // Bottom edge\n intersects(sp1, sp2, { x: left, y: bottom }, { x: right, y: bottom }) ||\n // Left edge\n intersects(sp1, sp2, { x: left, y: top }, { x: left, y: bottom })\n )\n }\n }, [realToScreen, size])\n}\n","import { useMemo } from \"react\"\n\ntype Line = {\n points: Array<{ x: number; y: number }>\n layer?: string\n step?: number\n closed?: boolean\n}\n\nexport const useFilterLines = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (line: Line) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(line)) return false\n\n // Then check if any point of the line is visible\n if (line.points.some((p) => isPointOnScreen(p))) {\n return true\n }\n\n // If no points are visible, check if any line segment intersects the viewport\n for (let i = 0; i < line.points.length - 1; i++) {\n if (doesLineIntersectViewport(line.points[i], line.points[i + 1])) {\n return true\n }\n }\n\n // If it's a closed shape (polyline), check the last segment too\n if (line.points.length > 2 && line.closed) {\n if (\n doesLineIntersectViewport(\n line.points[line.points.length - 1],\n line.points[0],\n )\n ) {\n return true\n }\n }\n\n return false\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Point = {\n x: number\n y: number\n layer?: string\n step?: number\n}\n\nexport const useFilterPoints = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (point: Point) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(point)) return false\n\n // Then check if the point is visible\n return isPointOnScreen(point)\n }\n }, [isPointOnScreen, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Rect = {\n center: { x: number; y: number }\n width: number\n height: number\n layer?: string\n step?: number\n}\n\nexport const useFilterRects = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (rect: Rect) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(rect)) return false\n\n // For rectangles, check if any corner or the center is visible\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = { x: center.x - halfWidth, y: center.y - halfHeight }\n const topRight = { x: center.x + halfWidth, y: center.y - halfHeight }\n const bottomLeft = { x: center.x - halfWidth, y: center.y + halfHeight }\n const bottomRight = { x: center.x + halfWidth, y: center.y + halfHeight }\n\n // Check if any corner or center is visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen(topLeft) ||\n isPointOnScreen(topRight) ||\n isPointOnScreen(bottomLeft) ||\n isPointOnScreen(bottomRight)\n ) {\n return true\n }\n\n // Check if any edge of the rectangle intersects the viewport\n return (\n doesLineIntersectViewport(topLeft, topRight) ||\n doesLineIntersectViewport(topRight, bottomRight) ||\n doesLineIntersectViewport(bottomRight, bottomLeft) ||\n doesLineIntersectViewport(bottomLeft, topLeft)\n )\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\ntype Circle = {\n center: { x: number; y: number }\n radius: number\n layer?: string\n step?: number\n}\n\nexport const useFilterCircles = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (circle: Circle) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(circle)) return false\n\n // For circles, check if center is visible or if any cardinal point is visible\n const { center, radius } = circle\n\n // Check if center or cardinal points on the circle are visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen({ x: center.x + radius, y: center.y }) ||\n isPointOnScreen({ x: center.x - radius, y: center.y }) ||\n isPointOnScreen({ x: center.x, y: center.y + radius }) ||\n isPointOnScreen({ x: center.x, y: center.y - radius })\n ) {\n return true\n }\n\n // Check if the circle intersects the viewport\n // Convert to screen coordinates for viewport intersection test\n const screenCenter = applyToPoint(realToScreen, center)\n const scale = Math.abs(realToScreen.a) // Get the scale factor\n const screenRadius = radius * scale\n\n // Viewport boundaries\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // Check if the circle intersects with the viewport\n // Case 1: Circle center is inside the viewport horizontally but outside vertically\n if (screenCenter.x >= left && screenCenter.x <= right) {\n if (\n Math.abs(screenCenter.y - top) <= screenRadius ||\n Math.abs(screenCenter.y - bottom) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 2: Circle center is inside the viewport vertically but outside horizontally\n if (screenCenter.y >= top && screenCenter.y <= bottom) {\n if (\n Math.abs(screenCenter.x - left) <= screenRadius ||\n Math.abs(screenCenter.x - right) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 3: Circle center is outside the viewport, check corners\n const cornerDistanceSquared = (cornerX: number, cornerY: number) => {\n const dx = screenCenter.x - cornerX\n const dy = screenCenter.y - cornerY\n return dx * dx + dy * dy\n }\n\n const radiusSquared = screenRadius * screenRadius\n\n return (\n cornerDistanceSquared(left, top) <= radiusSquared ||\n cornerDistanceSquared(right, top) <= radiusSquared ||\n cornerDistanceSquared(left, bottom) <= radiusSquared ||\n cornerDistanceSquared(right, bottom) <= radiusSquared\n )\n }\n }, [isPointOnScreen, filterLayerAndStep, realToScreen, size])\n}\n","import React, { useEffect, useRef, useState } from \"react\"\nimport { applyToPoint, identity, inverse } from \"transformation-matrix\"\nimport type { Matrix } from \"transformation-matrix\"\n\ninterface Props {\n transform?: Matrix\n children: React.ReactNode\n}\n\nexport const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {\n if (!transform) transform = identity()\n const [dimensionToolVisible, setDimensionToolVisible] = useState(false)\n const [dimensionToolStretching, setDimensionToolStretching] = useState(false)\n // Start of dimension tool line in real-world coordinates (not screen)\n const [dStart, setDStart] = useState({ x: 0, y: 0 })\n // End of dimension tool line in real-world coordinates (not screen)\n const [dEnd, setDEnd] = useState({ x: 0, y: 0 })\n const mousePosRef = useRef({ x: 0, y: 0 })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const container = containerRef.current!\n const containerBounds = container?.getBoundingClientRect()\n\n const bindKeys = () => {\n const container = containerRef.current\n\n const down = (e: KeyboardEvent) => {\n if (e.key === \"d\") {\n setDStart({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDEnd({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDimensionToolVisible((visible: boolean) => !visible)\n setDimensionToolStretching(true)\n }\n if (e.key === \"Escape\") {\n setDimensionToolVisible(false)\n setDimensionToolStretching(false)\n }\n }\n\n const addKeyListener = () => {\n if (container) {\n window.addEventListener(\"keydown\", down)\n }\n }\n\n const removeKeyListener = () => {\n if (container) {\n window.removeEventListener(\"keydown\", down)\n }\n }\n\n if (container) {\n container.addEventListener(\"focus\", addKeyListener)\n container.addEventListener(\"blur\", removeKeyListener)\n container.addEventListener(\"mouseenter\", addKeyListener)\n container.addEventListener(\"mouseleave\", removeKeyListener)\n }\n return () => {\n if (container) {\n container.removeEventListener(\"focus\", addKeyListener)\n container.removeEventListener(\"blur\", removeKeyListener)\n container.removeEventListener(\"mouseenter\", addKeyListener)\n container.removeEventListener(\"mouseleave\", removeKeyListener)\n }\n }\n }\n\n useEffect(bindKeys, [containerBounds?.width, containerBounds?.height])\n\n const screenDStart = applyToPoint(transform, dStart)\n const screenDEnd = applyToPoint(transform, dEnd)\n\n const arrowScreenBounds = {\n left: Math.min(screenDStart.x, screenDEnd.x),\n right: Math.max(screenDStart.x, screenDEnd.x),\n top: Math.min(screenDStart.y, screenDEnd.y),\n bottom: Math.max(screenDStart.y, screenDEnd.y),\n flipX: screenDStart.x > screenDEnd.x,\n flipY: screenDStart.y > screenDEnd.y,\n width: 0,\n height: 0,\n }\n arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left\n arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{ position: \"relative\" }}\n onMouseMove={(e: React.MouseEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const rwPoint = applyToPoint(inverse(transform!), { x, y })\n mousePosRef.current.x = rwPoint.x\n mousePosRef.current.y = rwPoint.y\n\n if (dimensionToolStretching) {\n setDEnd({ x: rwPoint.x, y: rwPoint.y })\n }\n }}\n onMouseDown={() => {\n if (dimensionToolStretching) {\n setDimensionToolStretching(false)\n } else if (dimensionToolVisible) {\n setDimensionToolVisible(false)\n }\n }}\n onMouseEnter={() => {\n if (containerRef.current) {\n bindKeys()\n }\n }}\n >\n {children}\n {dimensionToolVisible && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: arrowScreenBounds.left,\n width: arrowScreenBounds.width,\n textAlign: \"center\",\n top: screenDStart.y + 2,\n color: \"red\",\n mixBlendMode: \"difference\",\n pointerEvents: \"none\",\n marginTop: arrowScreenBounds.flipY ? 0 : -20,\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n {Math.abs(dStart.x - dEnd.x).toFixed(2)}\n </div>\n <div\n style={{\n position: \"absolute\",\n left: screenDEnd.x,\n height: arrowScreenBounds.height,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n top: arrowScreenBounds.top,\n color: \"red\",\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n <div\n style={{\n marginLeft: arrowScreenBounds.flipX ? \"-100%\" : 4,\n paddingRight: 4,\n }}\n >\n {Math.abs(dStart.y - dEnd.y).toFixed(2)}\n </div>\n </div>\n <svg\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n zIndex: 30,\n }}\n width={containerBounds?.width || \"100%\"}\n height={containerBounds?.height || \"100%\"}\n >\n <defs>\n <marker\n id=\"head\"\n orient=\"auto\"\n markerWidth=\"3\"\n markerHeight=\"4\"\n refX=\"2\"\n refY=\"2\"\n >\n <path d=\"M0,0 V4 L2,2 Z\" fill=\"red\" />\n </marker>\n </defs>\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n markerEnd=\"url(#head)\"\n strokeWidth={1.5}\n fill=\"none\"\n stroke=\"red\"\n />\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDStart.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n <line\n x1={screenDEnd.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n </svg>\n <div\n style={{\n right: 0,\n bottom: 0,\n position: \"absolute\",\n color: \"red\",\n fontFamily: \"sans-serif\",\n fontSize: 12,\n margin: 4,\n }}\n >\n ({dStart.x.toFixed(2)},{dStart.y.toFixed(2)})<br />(\n {dEnd.x.toFixed(2)},{dEnd.y.toFixed(2)})<br />\n dist:{\" \"}\n {Math.sqrt(\n (dEnd.x - dStart.x) ** 2 + (dEnd.y - dStart.y) ** 2,\n ).toFixed(2)}\n </div>\n </>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport function getMaxStep(graphics: GraphicsObject) {\n // Helper function to safely get max step from an array\n const getMaxStepFromArray = (items?: any[]) => {\n if (!items || items.length === 0) return 0\n\n // Use reduce instead of spreading a potentially large array\n return items.reduce((max, item) => {\n const step = Number.isNaN(item.step) ? 0 : item.step || 0\n return Math.max(max, step)\n }, 0)\n }\n\n const maxPointStep = getMaxStepFromArray(graphics.points)\n const maxLineStep = getMaxStepFromArray(graphics.lines)\n const maxRectStep = getMaxStepFromArray(graphics.rects)\n const maxCircleStep = getMaxStepFromArray(graphics.circles)\n\n return Math.max(maxPointStep, maxLineStep, maxRectStep, maxCircleStep)\n}\n","import React, { useRef, useEffect, useState, useMemo } from \"react\"\nimport { drawGraphicsToCanvas, getBounds, type GraphicsObject } from \"../../lib\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"./DimensionOverlay\"\nimport { getMaxStep } from \"site/utils/getMaxStep\"\nimport { getGraphicsFilteredByStep } from \"site/utils/getGraphicsFilteredByStep\"\nimport { getGraphicsBoundsWithPadding } from \"site/utils/getGraphicsBoundsWithPadding\"\n\ninterface InteractiveGraphicsCanvasProps {\n graphics: GraphicsObject\n showLabelsByDefault?: boolean\n showGrid?: boolean\n height?: number | string\n width?: number | string\n}\n\nexport function InteractiveGraphicsCanvas({\n graphics,\n showLabelsByDefault = true,\n showGrid = true,\n height = 500,\n width = \"100%\",\n}: InteractiveGraphicsCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLabels, setShowLabels] = useState(showLabelsByDefault)\n const [showLastStep, setShowLastStep] = useState(true)\n\n // Calculate the maximum step value from all graphics objects\n const maxStep = getMaxStep(graphics)\n\n // Filter graphics objects based on step\n const filteredGraphics = getGraphicsFilteredByStep(graphics, {\n activeStep,\n showLastStep,\n maxStep,\n })\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = getGraphicsBoundsWithPadding(graphics)\n\n // Use mouse transform hook for panning/zooming\n const { transform, ref: mouseTransformRef } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = () => {\n if (!canvasRef.current) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(filteredGraphics, canvasRef.current, {\n transform: transform,\n disableLabels: !showLabels,\n })\n\n // Draw a grid for reference if requested\n if (showGrid) {\n drawGrid(canvasRef.current, transform)\n }\n }\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: any) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Determine grid spacing based on zoom level\n const gridSize = 10\n\n // Draw vertical grid lines\n for (let x = -100; x <= 100; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -100 }, transform)\n const end = transformPoint({ x, y: 100 }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -100; y <= 100; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -100, y }, transform)\n const end = transformPoint({ x: 100, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: any) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [transform, size, filteredGraphics, showGrid, showLabels])\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n <div style={{ display: \"flex\", gap: \"12px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(Number.isNaN(value) ? 0 : Math.min(value, maxStep))\n }}\n disabled={activeStep === null}\n style={{ width: \"60px\" }}\n />\n\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLabels}\n onChange={(e) => {\n setShowLabels(e.target.checked)\n }}\n />\n Show labels\n </label>\n </div>\n </div>\n\n <div\n ref={(node) => {\n // Using a callback ref approach\n containerRef.current = node\n // Apply the mouse transform ref if available\n if (mouseTransformRef && node) {\n mouseTransformRef.current = node\n }\n }}\n style={{\n position: \"relative\",\n width: width,\n height: height,\n border: \"1px solid #ccc\",\n overflow: \"hidden\",\n }}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n }}\n />\n </div>\n </div>\n )\n}\n\nexport default InteractiveGraphicsCanvas\n","import { GraphicsObject } from \"lib/types\"\n\nexport function getGraphicsFilteredByStep(\n graphics: GraphicsObject,\n {\n showLastStep,\n activeStep,\n maxStep,\n }: {\n showLastStep?: boolean\n activeStep?: number | null\n maxStep?: number | null\n },\n) {\n const selectedStep = showLastStep ? maxStep : activeStep\n\n if (selectedStep === null) {\n return graphics\n }\n\n const filteredGraphics = {\n ...graphics,\n points: graphics.points?.filter(\n (p) => p.step === undefined || p.step === selectedStep,\n ),\n lines: graphics.lines?.filter(\n (l) => l.step === undefined || l.step === selectedStep,\n ),\n rects: graphics.rects?.filter(\n (r) => r.step === undefined || r.step === selectedStep,\n ),\n circles: graphics.circles?.filter(\n (c) => c.step === undefined || c.step === selectedStep,\n ),\n }\n\n return filteredGraphics\n}\n","import { getBounds } from \"lib/drawGraphicsToCanvas\"\nimport { GraphicsObject } from \"lib/types\"\n\nexport function getGraphicsBoundsWithPadding(graphics: GraphicsObject) {\n const bounds = getBounds(graphics)\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - width / 10,\n minY: bounds.minY - height / 10,\n maxX: bounds.maxX + width / 10,\n maxY: bounds.maxY + height / 10,\n }\n}\n","import React, { useRef, useEffect, useState } from \"react\"\nimport { GraphicsObject } from \"../../../lib/types\"\nimport {\n drawGraphicsToCanvas,\n getBounds,\n} from \"../../../lib/drawGraphicsToCanvas\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate, type Matrix } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\ninterface CanvasGraphicsProps {\n graphics: GraphicsObject\n width?: number\n height?: number\n withGrid?: boolean\n initialTransform?: Matrix\n disableLabels?: boolean\n}\n\n// Create a container component that handles the mouse matrix transform\nfunction TransformContainer({\n initialTransform,\n children,\n onTransformChange,\n}: {\n initialTransform: Matrix\n children: React.ReactNode\n onTransformChange: (transform: Matrix) => void\n}) {\n const { transform, ref } = useMouseMatrixTransform({\n initialTransform,\n })\n\n // Update parent with transform changes\n useEffect(() => {\n onTransformChange(transform)\n }, [transform, onTransformChange])\n\n return (\n <div\n ref={ref}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {children}\n </div>\n )\n}\n\nexport const CanvasGraphics = ({\n graphics,\n width = 600,\n height = 600,\n withGrid = true,\n disableLabels = false,\n initialTransform,\n}: CanvasGraphicsProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [size, setSize] = useState({ width, height })\n const [currentTransform, setCurrentTransform] = useState<Matrix | null>(null)\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = React.useMemo(() => {\n const bounds = getBounds(graphics)\n const bWidth = bounds.maxX - bounds.minX\n const bHeight = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - bWidth / 10,\n minY: bounds.minY - bHeight / 10,\n maxX: bounds.maxX + bWidth / 10,\n maxY: bounds.maxY + bHeight / 10,\n }\n }, [graphics])\n\n // Compute initial transform if not provided\n const computedInitialTransform = React.useMemo(() => {\n if (initialTransform) return initialTransform\n\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n yFlip\n ? -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n )\n : Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [graphics, graphicsBoundsWithPadding, initialTransform, size])\n\n // Track transform changes from the mouse transform hook\n const handleTransformChange = React.useCallback((transform: Matrix) => {\n setCurrentTransform(transform)\n }, [])\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = React.useCallback(() => {\n if (!canvasRef.current || !currentTransform) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(graphics, canvasRef.current, {\n transform: currentTransform,\n disableLabels,\n })\n\n // Draw a grid for reference if enabled\n if (withGrid) {\n drawGrid(canvasRef.current, currentTransform)\n }\n }, [canvasRef, currentTransform, graphics, size, withGrid])\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: Matrix) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Calculate a good grid size based on zoom level\n // This is an approximate calculation\n const zoomLevel = Math.abs(transform.a) // Scale factor\n const gridSize = Math.pow(10, Math.floor(Math.log10(100 / zoomLevel)))\n\n const gridRange = Math.ceil(1000 / gridSize) * gridSize\n\n // Draw vertical grid lines\n for (let x = -gridRange; x <= gridRange; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -gridRange }, transform)\n const end = transformPoint({ x, y: gridRange }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -gridRange; y <= gridRange; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -gridRange, y }, transform)\n const end = transformPoint({ x: gridRange, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: Matrix) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [drawCanvas])\n\n // Initialize transform\n useEffect(() => {\n setCurrentTransform(computedInitialTransform)\n }, [computedInitialTransform])\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n border: \"1px solid #eee\",\n overflow: \"hidden\",\n }}\n >\n <TransformContainer\n initialTransform={computedInitialTransform}\n onTransformChange={handleTransformChange}\n >\n <DimensionOverlay\n transform={currentTransform || computedInitialTransform}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n />\n </DimensionOverlay>\n </TransformContainer>\n </div>\n )\n}\n"],"mappings":"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","names":["useMemo","useState","jsx","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useMemo","applyToPoint","useMemo","applyToPoint","useMemo","useMemo","useMemo","applyToPoint","useMemo","useMemo","applyToPoint","scale","useState","applyToPoint","jsx","jsxs","container","jsx","jsxs","useState","useMemo","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","jsxs","useRef","useState","useMouseMatrixTransform","compose","translate","scale","useResizeObserver","transform","useEffect","React","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","useMouseMatrixTransform","useEffect","useRef","useState","React","compose","translate","scale","useResizeObserver"]}
1
+ {"version":3,"sources":["../../site/components/InteractiveGraphics/InteractiveGraphics.tsx","../../site/components/InteractiveGraphics/Line.tsx","../../site/components/InteractiveGraphics/Tooltip.tsx","../../site/utils/distToLineSegment.ts","../../site/utils/safeLighten.ts","../../site/components/InteractiveGraphics/Point.tsx","../../site/components/InteractiveGraphics/Rect.tsx","../../site/components/InteractiveGraphics/Circle.tsx","../../site/utils/getGraphicsBounds.ts","../../site/components/InteractiveGraphics/hooks/useIsPointOnScreen.ts","../../site/components/InteractiveGraphics/hooks/useDoesLineIntersectViewport.ts","../../site/components/InteractiveGraphics/hooks/useFilterLines.ts","../../site/components/InteractiveGraphics/hooks/useFilterPoints.ts","../../site/components/InteractiveGraphics/hooks/useFilterRects.ts","../../site/components/InteractiveGraphics/hooks/useFilterCircles.ts","../../site/components/DimensionOverlay.tsx","../../site/utils/getMaxStep.ts","../../site/components/InteractiveGraphics/ContextMenu.tsx","../../site/components/InteractiveGraphics/Marker.tsx","../../site/components/InteractiveGraphicsCanvas.tsx","../../site/utils/getGraphicsFilteredByStep.ts","../../site/utils/getGraphicsBoundsWithPadding.ts","../../site/components/CanvasGraphics/CanvasGraphics.tsx"],"sourcesContent":["import {\n compose,\n scale,\n translate,\n inverse,\n applyToPoint,\n} from \"transformation-matrix\"\nimport { GraphicsObject } from \"../../../lib\"\nimport { useMemo, useState, useEffect, useCallback } from \"react\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { InteractiveState } from \"./InteractiveState\"\nimport { SuperGrid } from \"react-supergrid\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { Line } from \"./Line\"\nimport { Point } from \"./Point\"\nimport { Rect } from \"./Rect\"\nimport { Circle } from \"./Circle\"\nimport { getGraphicsBounds } from \"site/utils/getGraphicsBounds\"\nimport {\n useIsPointOnScreen,\n useDoesLineIntersectViewport,\n useFilterLines,\n useFilterPoints,\n useFilterRects,\n useFilterCircles,\n} from \"./hooks\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\nimport { getMaxStep } from \"site/utils/getMaxStep\"\nimport { ContextMenu } from \"./ContextMenu\"\nimport { Marker, MarkerPoint } from \"./Marker\"\n\nexport type GraphicsObjectClickEvent = {\n type: \"point\" | \"line\" | \"rect\" | \"circle\"\n index: number\n object: any\n}\n\nexport const InteractiveGraphics = ({\n graphics,\n onObjectClicked,\n objectLimit,\n}: {\n graphics: GraphicsObject\n onObjectClicked?: (event: GraphicsObjectClickEvent) => void\n objectLimit?: number\n}) => {\n const [activeLayers, setActiveLayers] = useState<string[] | null>(null)\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLastStep, setShowLastStep] = useState(true)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [contextMenu, setContextMenu] = useState<{\n x: number\n y: number\n clientX: number\n clientY: number\n } | null>(null)\n const [markers, setMarkers] = useState<MarkerPoint[]>([])\n const availableLayers: string[] = Array.from(\n new Set([\n ...(graphics.lines?.map((l) => l.layer!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.layer!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.layer!).filter(Boolean) ?? []),\n ]),\n )\n const maxStep = getMaxStep(graphics)\n\n const graphicsBoundsWithPadding = useMemo(() => {\n const actualBounds = getGraphicsBounds(graphics)\n const width = actualBounds.maxX - actualBounds.minX\n const height = actualBounds.maxY - actualBounds.minY\n return {\n minX: actualBounds.minX - width / 10,\n minY: actualBounds.minY - height / 10,\n maxX: actualBounds.maxX + width / 10,\n maxY: actualBounds.maxY + height / 10,\n }\n }, [graphics])\n\n const getStorageKey = useCallback(() => {\n const path = window.location.pathname\n const search = window.location.search\n return `saved-camera-position-${path}${search}`\n }, [])\n\n const getDefaultTransform = useCallback(() => {\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [size, graphicsBoundsWithPadding])\n\n type SavedData = {\n transform: any\n markers: MarkerPoint[]\n }\n\n const getSavedData = useCallback((): SavedData | null => {\n try {\n const savedData = localStorage.getItem(getStorageKey())\n if (savedData) {\n return JSON.parse(savedData)\n }\n } catch (error) {\n console.error(\"Error loading saved data:\", error)\n }\n return null\n }, [getStorageKey])\n\n const getSavedTransform = useCallback(() => {\n const savedData = getSavedData()\n return savedData?.transform || null\n }, [getSavedData])\n\n const {\n transform: realToScreen,\n ref,\n setTransform,\n } = useMouseMatrixTransform({\n initialTransform: getSavedTransform() || getDefaultTransform(),\n })\n\n useResizeObserver(ref, (entry: ResizeObserverEntry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Load saved markers on mount\n useEffect(() => {\n const savedData = getSavedData()\n if (savedData?.markers) {\n setMarkers(savedData.markers)\n }\n }, [getSavedData])\n\n const handleContextMenu = useCallback((event: React.MouseEvent) => {\n event.preventDefault()\n\n // Get mouse position\n const mouseX = event.clientX\n const mouseY = event.clientY\n\n // Get element position\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()\n const elementX = rect.left\n const elementY = rect.top\n\n // Get viewport dimensions\n const viewportWidth = window.innerWidth\n const viewportHeight = window.innerHeight\n\n // Menu dimensions (approximate)\n const menuWidth = 160\n const menuHeight = 100\n\n // Position based on quadrant of the screen\n let x = mouseX - elementX\n let y = mouseY - elementY\n\n // If mouse is in right half of viewport, position menu to the left\n if (mouseX > viewportWidth / 2) {\n x = x - menuWidth\n }\n\n // If mouse is in bottom half of viewport, position menu above\n if (mouseY > viewportHeight / 2) {\n y = y - menuHeight\n }\n\n setContextMenu({\n x,\n y,\n clientX: mouseX,\n clientY: mouseY,\n })\n }, [])\n\n const saveToLocalStorage = useCallback(\n (transform: any, markerPoints: MarkerPoint[]) => {\n try {\n const dataToSave: SavedData = {\n transform,\n markers: markerPoints,\n }\n localStorage.setItem(getStorageKey(), JSON.stringify(dataToSave))\n } catch (error) {\n console.error(\"Error saving data:\", error)\n }\n },\n [getStorageKey],\n )\n\n const handleSaveCamera = useCallback(() => {\n saveToLocalStorage(realToScreen, markers)\n }, [saveToLocalStorage, realToScreen, markers])\n\n const handleClearCamera = useCallback(() => {\n try {\n const defaultTransform = getDefaultTransform()\n saveToLocalStorage(defaultTransform, markers)\n setTransform(defaultTransform)\n } catch (error) {\n console.error(\"Error clearing camera position:\", error)\n }\n }, [saveToLocalStorage, getDefaultTransform, setTransform, markers])\n\n const handleAddMark = useCallback(() => {\n if (!contextMenu) return\n\n try {\n // Convert screen coordinates to real-world coordinates\n const screenPoint = { x: contextMenu.clientX, y: contextMenu.clientY }\n const rect = ref.current?.getBoundingClientRect()\n\n if (rect) {\n const screenX = screenPoint.x - rect.left\n const screenY = screenPoint.y - rect.top\n\n // Apply inverse transform to get real-world coordinates\n const inverseTransform = inverse(realToScreen)\n const [realX, realY] = applyToPoint(inverseTransform, [\n screenX,\n screenY,\n ])\n\n const newMarker: MarkerPoint = { x: realX, y: realY }\n const newMarkers = [...markers, newMarker]\n\n setMarkers(newMarkers)\n saveToLocalStorage(realToScreen, newMarkers)\n }\n } catch (error) {\n console.error(\"Error adding marker:\", error)\n }\n }, [contextMenu, ref, realToScreen, markers, saveToLocalStorage])\n\n const handleClearMarks = useCallback(() => {\n setMarkers([])\n saveToLocalStorage(realToScreen, [])\n }, [realToScreen, saveToLocalStorage])\n\n const interactiveState: InteractiveState = {\n activeLayers: activeLayers,\n activeStep: showLastStep ? maxStep : activeStep,\n realToScreen: realToScreen,\n onObjectClicked: onObjectClicked,\n }\n\n const showToolbar = availableLayers.length > 1 || maxStep > 0\n\n // Use custom hooks for visibility checks and filtering\n const isPointOnScreen = useIsPointOnScreen(realToScreen, size)\n\n const doesLineIntersectViewport = useDoesLineIntersectViewport(\n realToScreen,\n size,\n )\n\n // Filter by layer and step\n const filterLayerAndStep = (obj: { layer?: string; step?: number }) => {\n if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))\n return false\n\n const selectedStep = showLastStep ? maxStep : activeStep\n if (\n selectedStep !== null &&\n obj.step !== undefined &&\n obj.step !== selectedStep\n )\n return false\n return true\n }\n\n const filterLines = useFilterLines(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterPoints = useFilterPoints(isPointOnScreen, filterLayerAndStep)\n\n const filterRects = useFilterRects(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterCircles = useFilterCircles(\n isPointOnScreen,\n filterLayerAndStep,\n realToScreen,\n size,\n )\n\n const filterAndLimit = <T,>(\n objects: T[] | undefined,\n filterFn: (obj: T) => boolean,\n ): (T & { originalIndex: number })[] => {\n if (!objects) return []\n const filtered = objects\n .map((obj, index) => ({ ...obj, originalIndex: index }))\n .filter(filterFn)\n return objectLimit ? filtered.slice(-objectLimit) : filtered\n }\n\n const filteredLines = useMemo(\n () => filterAndLimit(graphics.lines, filterLines),\n [graphics.lines, filterLines, objectLimit],\n )\n const filteredRects = useMemo(\n () => filterAndLimit(graphics.rects, filterRects),\n [graphics.rects, filterRects, objectLimit],\n )\n const filteredPoints = useMemo(\n () => filterAndLimit(graphics.points, filterPoints),\n [graphics.points, filterPoints, objectLimit],\n )\n const filteredCircles = useMemo(\n () => filterAndLimit(graphics.circles, filterCircles),\n [graphics.circles, filterCircles, objectLimit],\n )\n\n const totalFilteredObjects =\n filteredLines.length +\n filteredRects.length +\n filteredPoints.length +\n filteredCircles.length\n const isLimitReached = objectLimit && totalFilteredObjects > objectLimit\n\n return (\n <div>\n {showToolbar && (\n <div style={{ margin: 8 }}>\n {availableLayers.length > 1 && (\n <select\n value={activeLayers ? activeLayers[0] : \"\"}\n onChange={(e) => {\n const value = e.target.value\n setActiveLayers(value === \"\" ? null : [value])\n }}\n style={{ marginRight: 8 }}\n >\n <option value=\"\">All Layers</option>\n {availableLayers.map((layer) => (\n <option key={layer} value={layer}>\n {layer}\n </option>\n ))}\n </select>\n )}\n\n {maxStep > 0 && (\n <div\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8 }}\n >\n Step:\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(Number.isNaN(value) ? null : value)\n }}\n disabled={activeStep === null}\n />\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setShowLastStep(false)\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n {isLimitReached && (\n <span style={{ color: \"red\", fontSize: \"12px\" }}>\n Display limited to {objectLimit} objects. Received:{\" \"}\n {totalFilteredObjects}.\n </span>\n )}\n </div>\n )}\n </div>\n )}\n\n <div\n ref={ref}\n style={{\n position: \"relative\",\n height: 600,\n overflow: \"hidden\",\n }}\n onContextMenu={handleContextMenu}\n >\n <DimensionOverlay transform={realToScreen}>\n {filteredLines.map((line) => (\n <Line\n key={line.originalIndex}\n line={line}\n index={line.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredRects.map((rect) => (\n <Rect\n key={rect.originalIndex}\n rect={rect}\n index={rect.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredPoints.map((point) => (\n <Point\n key={point.originalIndex}\n point={point}\n index={point.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredCircles.map((circle) => (\n <Circle\n key={circle.originalIndex}\n circle={circle}\n index={circle.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n <SuperGrid\n stringifyCoord={(x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`}\n width={size.width}\n height={size.height}\n transform={realToScreen}\n />\n </DimensionOverlay>\n {markers.map((marker, index) => (\n <Marker\n key={index}\n marker={marker}\n index={index}\n transform={realToScreen}\n />\n ))}\n {contextMenu && (\n <ContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n onSaveCamera={handleSaveCamera}\n onClearCamera={handleClearCamera}\n onAddMark={handleAddMark}\n onClearMarks={handleClearMarks}\n onClose={() => setContextMenu(null)}\n />\n )}\n </div>\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { distToLineSegment } from \"site/utils/distToLineSegment\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Line = ({\n line,\n index,\n interactiveState,\n}: { line: Types.Line; index: number; interactiveState: InteractiveState }) => {\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const {\n points,\n layer,\n step,\n strokeColor,\n strokeWidth = 1 / realToScreen.a,\n strokeDash,\n } = line\n const [isHovered, setIsHovered] = useState(false)\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 })\n\n const screenPoints = points.map((p) => applyToPoint(realToScreen, p))\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const hoverThreshold = 10 // pixels\n\n setMousePos({ x: mouseX, y: mouseY })\n\n // Check distance to each line segment\n let isNearLine = false\n for (let i = 0; i < screenPoints.length - 1; i++) {\n const dist = distToLineSegment(\n mouseX,\n mouseY,\n screenPoints[i].x,\n screenPoints[i].y,\n screenPoints[i + 1].x,\n screenPoints[i + 1].y,\n )\n if (dist < hoverThreshold) {\n isNearLine = true\n break\n }\n }\n\n setIsHovered(isNearLine)\n }\n\n const baseColor = strokeColor ?? defaultColors[index % defaultColors.length]\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setIsHovered(false)}\n onClick={\n isHovered\n ? () =>\n onObjectClicked?.({\n type: \"line\",\n index,\n object: line,\n })\n : undefined\n }\n >\n <polyline\n points={screenPoints.map((p) => `${p.x},${p.y}`).join(\" \")}\n stroke={isHovered ? safeLighten(0.2, baseColor) : baseColor}\n fill=\"none\"\n strokeWidth={strokeWidth * realToScreen.a}\n strokeDasharray={\n !strokeDash\n ? undefined\n : typeof strokeDash === \"string\"\n ? strokeDash\n : `${strokeDash[0] * realToScreen.a}, ${strokeDash[1] * realToScreen.a}`\n }\n strokeLinecap=\"round\"\n />\n {isHovered && line.label && (\n <foreignObject\n x={mousePos.x}\n y={mousePos.y - 40}\n width={300}\n height={40}\n >\n <Tooltip text={line.label} />\n </foreignObject>\n )}\n </svg>\n )\n}\n","export const Tooltip = ({ text }: { text: string }) => {\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #ccc\",\n boxShadow: \"0 0 10px 0 rgba(0, 0, 0, 0.1)\",\n borderRadius: \"4px\",\n padding: \"4px 8px\",\n fontSize: \"12px\",\n minWidth: \"150px\",\n maxWidth: \"300px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"pre-wrap\",\n zIndex: 100,\n }}\n >\n {text}\n </div>\n )\n}\n","// Calculate distance from point to line segment\nexport const distToLineSegment = (\n px: number,\n py: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n) => {\n const A = px - x1\n const B = py - y1\n const C = x2 - x1\n const D = y2 - y1\n\n const dot = A * C + B * D\n const lenSq = C * C + D * D\n let param = -1\n\n if (lenSq !== 0) param = dot / lenSq\n\n let xx = 0\n let yy = 0\n\n if (param < 0) {\n xx = x1\n yy = y1\n } else if (param > 1) {\n xx = x2\n yy = y2\n } else {\n xx = x1 + param * C\n yy = y1 + param * D\n }\n\n const dx = px - xx\n const dy = py - yy\n return Math.sqrt(dx * dx + dy * dy)\n}\n","import { lighten } from \"polished\"\n\nexport const safeLighten = (amount: number, color: string) => {\n try {\n return lighten(amount, color)\n } catch (e) {\n return color\n }\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Point = ({\n point,\n interactiveState,\n index,\n}: {\n point: Types.Point\n interactiveState: InteractiveState\n index: number\n}) => {\n const { color, label, layer, step } = point\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenPoint = applyToPoint(realToScreen, point)\n const size = 10\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenPoint.x - size / 2,\n top: screenPoint.y - size / 2,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${\n isHovered\n ? safeLighten(\n 0.2,\n color ?? defaultColors[index % defaultColors.length],\n )\n : (color ?? defaultColors[index % defaultColors.length])\n }`,\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"point\",\n index,\n object: point,\n })\n }\n >\n {isHovered && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip\n text={`${label ? `${label}\\n` : \"\"}x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`}\n />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Rect = ({\n rect,\n interactiveState,\n index,\n}: {\n rect: Types.Rect\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, width, height, fill, stroke, layer, step } = rect\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenCenter = applyToPoint(realToScreen, center)\n const screenWidth = width * realToScreen.a\n const screenHeight = height * Math.abs(realToScreen.d)\n\n // Default style when neither fill nor stroke is specified\n const hasStrokeOrFill = fill !== undefined || stroke !== undefined\n\n let backgroundColor = hasStrokeOrFill ? fill || \"transparent\" : defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = safeLighten(0.2, stroke!)\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenWidth / 2,\n top: screenCenter.y - screenHeight / 2,\n width: screenWidth,\n height: screenHeight,\n backgroundColor,\n border: stroke\n ? `2px solid ${isHovered ? safeLighten(0.2, stroke) : stroke}`\n : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"rect\",\n index,\n object: rect,\n })\n }\n >\n {isHovered && rect.label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={rect.label} />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Circle = ({\n circle,\n interactiveState,\n index,\n}: {\n circle: Types.Circle\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, radius, fill, stroke, layer, step, label } = circle\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n const screenCenter = applyToPoint(realToScreen, center)\n const screenRadius = radius * realToScreen.a\n let backgroundColor = fill || defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = stroke ? safeLighten(0.2, stroke) : stroke\n }\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenRadius,\n top: screenCenter.y - screenRadius,\n width: screenRadius * 2,\n height: screenRadius * 2,\n borderRadius: \"50%\",\n backgroundColor,\n border: stroke ? `2px solid ${stroke}` : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"circle\",\n index,\n object: circle,\n })\n }\n >\n {isHovered && label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={label} />\n </div>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport const getGraphicsBounds = (graphics: GraphicsObject) => {\n const bounds = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n }\n for (const line of graphics.lines ?? []) {\n for (const point of line.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n }\n for (const rect of graphics.rects ?? []) {\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n bounds.minX = Math.min(bounds.minX, center.x - halfWidth)\n bounds.minY = Math.min(bounds.minY, center.y - halfHeight)\n bounds.maxX = Math.max(bounds.maxX, center.x + halfWidth)\n bounds.maxY = Math.max(bounds.maxY, center.y + halfHeight)\n }\n for (const point of graphics.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n return bounds\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\nexport const useIsPointOnScreen = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (point: { x: number; y: number }) => {\n const screenPoint = applyToPoint(realToScreen, point)\n return (\n screenPoint.x >= -OFFSCREEN_MARGIN &&\n screenPoint.x <= size.width + OFFSCREEN_MARGIN &&\n screenPoint.y >= -OFFSCREEN_MARGIN &&\n screenPoint.y <= size.height + OFFSCREEN_MARGIN\n )\n }\n }, [realToScreen, size])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\n\n// Margin in pixels for determining if elements are off-screen\nexport const OFFSCREEN_MARGIN = 5\n\nexport const useDoesLineIntersectViewport = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (p1: { x: number; y: number }, p2: { x: number; y: number }) => {\n // Convert real-world points to screen coordinates\n const sp1 = applyToPoint(realToScreen, p1)\n const sp2 = applyToPoint(realToScreen, p2)\n\n // Viewport boundaries with margin\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // If either point is inside the viewport, the line intersects\n if (\n (sp1.x >= left && sp1.x <= right && sp1.y >= top && sp1.y <= bottom) ||\n (sp2.x >= left && sp2.x <= right && sp2.y >= top && sp2.y <= bottom)\n ) {\n return true\n }\n\n // Helper function to check if a line intersects with a line segment\n const intersects = (\n a1: { x: number; y: number },\n a2: { x: number; y: number },\n b1: { x: number; y: number },\n b2: { x: number; y: number },\n ) => {\n // Line segment A is (a1, a2), line segment B is (b1, b2)\n const det =\n (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x)\n\n // If lines are parallel or coincident, they don't intersect in a unique point\n if (det === 0) return false\n\n const lambda =\n ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det\n const gamma =\n ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det\n\n // Check if the intersection point is within both line segments\n return lambda >= 0 && lambda <= 1 && gamma >= 0 && gamma <= 1\n }\n\n // Check intersection with each edge of the viewport\n return (\n // Top edge\n intersects(sp1, sp2, { x: left, y: top }, { x: right, y: top }) ||\n // Right edge\n intersects(sp1, sp2, { x: right, y: top }, { x: right, y: bottom }) ||\n // Bottom edge\n intersects(sp1, sp2, { x: left, y: bottom }, { x: right, y: bottom }) ||\n // Left edge\n intersects(sp1, sp2, { x: left, y: top }, { x: left, y: bottom })\n )\n }\n }, [realToScreen, size])\n}\n","import { useMemo } from \"react\"\n\ntype Line = {\n points: Array<{ x: number; y: number }>\n layer?: string\n step?: number\n closed?: boolean\n}\n\nexport const useFilterLines = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (line: Line) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(line)) return false\n\n // Then check if any point of the line is visible\n if (line.points.some((p) => isPointOnScreen(p))) {\n return true\n }\n\n // If no points are visible, check if any line segment intersects the viewport\n for (let i = 0; i < line.points.length - 1; i++) {\n if (doesLineIntersectViewport(line.points[i], line.points[i + 1])) {\n return true\n }\n }\n\n // If it's a closed shape (polyline), check the last segment too\n if (line.points.length > 2 && line.closed) {\n if (\n doesLineIntersectViewport(\n line.points[line.points.length - 1],\n line.points[0],\n )\n ) {\n return true\n }\n }\n\n return false\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Point = {\n x: number\n y: number\n layer?: string\n step?: number\n}\n\nexport const useFilterPoints = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (point: Point) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(point)) return false\n\n // Then check if the point is visible\n return isPointOnScreen(point)\n }\n }, [isPointOnScreen, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Rect = {\n center: { x: number; y: number }\n width: number\n height: number\n layer?: string\n step?: number\n}\n\nexport const useFilterRects = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (rect: Rect) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(rect)) return false\n\n // For rectangles, check if any corner or the center is visible\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = { x: center.x - halfWidth, y: center.y - halfHeight }\n const topRight = { x: center.x + halfWidth, y: center.y - halfHeight }\n const bottomLeft = { x: center.x - halfWidth, y: center.y + halfHeight }\n const bottomRight = { x: center.x + halfWidth, y: center.y + halfHeight }\n\n // Check if any corner or center is visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen(topLeft) ||\n isPointOnScreen(topRight) ||\n isPointOnScreen(bottomLeft) ||\n isPointOnScreen(bottomRight)\n ) {\n return true\n }\n\n // Check if any edge of the rectangle intersects the viewport\n return (\n doesLineIntersectViewport(topLeft, topRight) ||\n doesLineIntersectViewport(topRight, bottomRight) ||\n doesLineIntersectViewport(bottomRight, bottomLeft) ||\n doesLineIntersectViewport(bottomLeft, topLeft)\n )\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\ntype Circle = {\n center: { x: number; y: number }\n radius: number\n layer?: string\n step?: number\n}\n\nexport const useFilterCircles = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (circle: Circle) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(circle)) return false\n\n // For circles, check if center is visible or if any cardinal point is visible\n const { center, radius } = circle\n\n // Check if center or cardinal points on the circle are visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen({ x: center.x + radius, y: center.y }) ||\n isPointOnScreen({ x: center.x - radius, y: center.y }) ||\n isPointOnScreen({ x: center.x, y: center.y + radius }) ||\n isPointOnScreen({ x: center.x, y: center.y - radius })\n ) {\n return true\n }\n\n // Check if the circle intersects the viewport\n // Convert to screen coordinates for viewport intersection test\n const screenCenter = applyToPoint(realToScreen, center)\n const scale = Math.abs(realToScreen.a) // Get the scale factor\n const screenRadius = radius * scale\n\n // Viewport boundaries\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // Check if the circle intersects with the viewport\n // Case 1: Circle center is inside the viewport horizontally but outside vertically\n if (screenCenter.x >= left && screenCenter.x <= right) {\n if (\n Math.abs(screenCenter.y - top) <= screenRadius ||\n Math.abs(screenCenter.y - bottom) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 2: Circle center is inside the viewport vertically but outside horizontally\n if (screenCenter.y >= top && screenCenter.y <= bottom) {\n if (\n Math.abs(screenCenter.x - left) <= screenRadius ||\n Math.abs(screenCenter.x - right) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 3: Circle center is outside the viewport, check corners\n const cornerDistanceSquared = (cornerX: number, cornerY: number) => {\n const dx = screenCenter.x - cornerX\n const dy = screenCenter.y - cornerY\n return dx * dx + dy * dy\n }\n\n const radiusSquared = screenRadius * screenRadius\n\n return (\n cornerDistanceSquared(left, top) <= radiusSquared ||\n cornerDistanceSquared(right, top) <= radiusSquared ||\n cornerDistanceSquared(left, bottom) <= radiusSquared ||\n cornerDistanceSquared(right, bottom) <= radiusSquared\n )\n }\n }, [isPointOnScreen, filterLayerAndStep, realToScreen, size])\n}\n","import React, { useEffect, useRef, useState } from \"react\"\nimport { applyToPoint, identity, inverse } from \"transformation-matrix\"\nimport type { Matrix } from \"transformation-matrix\"\n\ninterface Props {\n transform?: Matrix\n children: React.ReactNode\n}\n\nexport const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {\n if (!transform) transform = identity()\n const [dimensionToolVisible, setDimensionToolVisible] = useState(false)\n const [dimensionToolStretching, setDimensionToolStretching] = useState(false)\n // Start of dimension tool line in real-world coordinates (not screen)\n const [dStart, setDStart] = useState({ x: 0, y: 0 })\n // End of dimension tool line in real-world coordinates (not screen)\n const [dEnd, setDEnd] = useState({ x: 0, y: 0 })\n const mousePosRef = useRef({ x: 0, y: 0 })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const container = containerRef.current!\n const containerBounds = container?.getBoundingClientRect()\n\n const bindKeys = () => {\n const container = containerRef.current\n\n const down = (e: KeyboardEvent) => {\n if (e.key === \"d\") {\n setDStart({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDEnd({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDimensionToolVisible((visible: boolean) => !visible)\n setDimensionToolStretching(true)\n }\n if (e.key === \"Escape\") {\n setDimensionToolVisible(false)\n setDimensionToolStretching(false)\n }\n }\n\n const addKeyListener = () => {\n if (container) {\n window.addEventListener(\"keydown\", down)\n }\n }\n\n const removeKeyListener = () => {\n if (container) {\n window.removeEventListener(\"keydown\", down)\n }\n }\n\n if (container) {\n container.addEventListener(\"focus\", addKeyListener)\n container.addEventListener(\"blur\", removeKeyListener)\n container.addEventListener(\"mouseenter\", addKeyListener)\n container.addEventListener(\"mouseleave\", removeKeyListener)\n }\n return () => {\n if (container) {\n container.removeEventListener(\"focus\", addKeyListener)\n container.removeEventListener(\"blur\", removeKeyListener)\n container.removeEventListener(\"mouseenter\", addKeyListener)\n container.removeEventListener(\"mouseleave\", removeKeyListener)\n }\n }\n }\n\n useEffect(bindKeys, [containerBounds?.width, containerBounds?.height])\n\n const screenDStart = applyToPoint(transform, dStart)\n const screenDEnd = applyToPoint(transform, dEnd)\n\n const arrowScreenBounds = {\n left: Math.min(screenDStart.x, screenDEnd.x),\n right: Math.max(screenDStart.x, screenDEnd.x),\n top: Math.min(screenDStart.y, screenDEnd.y),\n bottom: Math.max(screenDStart.y, screenDEnd.y),\n flipX: screenDStart.x > screenDEnd.x,\n flipY: screenDStart.y > screenDEnd.y,\n width: 0,\n height: 0,\n }\n arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left\n arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{ position: \"relative\" }}\n onMouseMove={(e: React.MouseEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const rwPoint = applyToPoint(inverse(transform!), { x, y })\n mousePosRef.current.x = rwPoint.x\n mousePosRef.current.y = rwPoint.y\n\n if (dimensionToolStretching) {\n setDEnd({ x: rwPoint.x, y: rwPoint.y })\n }\n }}\n onMouseDown={() => {\n if (dimensionToolStretching) {\n setDimensionToolStretching(false)\n } else if (dimensionToolVisible) {\n setDimensionToolVisible(false)\n }\n }}\n onMouseEnter={() => {\n if (containerRef.current) {\n bindKeys()\n }\n }}\n >\n {children}\n {dimensionToolVisible && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: arrowScreenBounds.left,\n width: arrowScreenBounds.width,\n textAlign: \"center\",\n top: screenDStart.y + 2,\n color: \"red\",\n mixBlendMode: \"difference\",\n pointerEvents: \"none\",\n marginTop: arrowScreenBounds.flipY ? 0 : -20,\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n {Math.abs(dStart.x - dEnd.x).toFixed(2)}\n </div>\n <div\n style={{\n position: \"absolute\",\n left: screenDEnd.x,\n height: arrowScreenBounds.height,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n top: arrowScreenBounds.top,\n color: \"red\",\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n <div\n style={{\n marginLeft: arrowScreenBounds.flipX ? \"-100%\" : 4,\n paddingRight: 4,\n }}\n >\n {Math.abs(dStart.y - dEnd.y).toFixed(2)}\n </div>\n </div>\n <svg\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n zIndex: 30,\n }}\n width={containerBounds?.width || \"100%\"}\n height={containerBounds?.height || \"100%\"}\n >\n <defs>\n <marker\n id=\"head\"\n orient=\"auto\"\n markerWidth=\"3\"\n markerHeight=\"4\"\n refX=\"2\"\n refY=\"2\"\n >\n <path d=\"M0,0 V4 L2,2 Z\" fill=\"red\" />\n </marker>\n </defs>\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n markerEnd=\"url(#head)\"\n strokeWidth={1.5}\n fill=\"none\"\n stroke=\"red\"\n />\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDStart.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n <line\n x1={screenDEnd.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n </svg>\n <div\n style={{\n right: 0,\n bottom: 0,\n position: \"absolute\",\n color: \"red\",\n fontFamily: \"sans-serif\",\n fontSize: 12,\n margin: 4,\n }}\n >\n ({dStart.x.toFixed(2)},{dStart.y.toFixed(2)})<br />(\n {dEnd.x.toFixed(2)},{dEnd.y.toFixed(2)})<br />\n dist:{\" \"}\n {Math.sqrt(\n (dEnd.x - dStart.x) ** 2 + (dEnd.y - dStart.y) ** 2,\n ).toFixed(2)}\n </div>\n </>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport function getMaxStep(graphics: GraphicsObject) {\n // Helper function to safely get max step from an array\n const getMaxStepFromArray = (items?: any[]) => {\n if (!items || items.length === 0) return 0\n\n // Use reduce instead of spreading a potentially large array\n return items.reduce((max, item) => {\n const step = Number.isNaN(item.step) ? 0 : item.step || 0\n return Math.max(max, step)\n }, 0)\n }\n\n const maxPointStep = getMaxStepFromArray(graphics.points)\n const maxLineStep = getMaxStepFromArray(graphics.lines)\n const maxRectStep = getMaxStepFromArray(graphics.rects)\n const maxCircleStep = getMaxStepFromArray(graphics.circles)\n\n return Math.max(maxPointStep, maxLineStep, maxRectStep, maxCircleStep)\n}\n","import { useEffect, useRef } from \"react\"\n\ntype ContextMenuProps = {\n x: number\n y: number\n onSaveCamera: () => void\n onClearCamera: () => void\n onAddMark: () => void\n onClearMarks: () => void\n onClose: () => void\n}\n\nexport const ContextMenu = ({\n x,\n y,\n onSaveCamera,\n onClearCamera,\n onAddMark,\n onClearMarks,\n onClose,\n}: ContextMenuProps) => {\n const menuRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(event.target as Node)) {\n onClose()\n }\n }\n\n document.addEventListener(\"mousedown\", handleClickOutside)\n return () => {\n document.removeEventListener(\"mousedown\", handleClickOutside)\n }\n }, [onClose])\n\n const menuStyle: React.CSSProperties = {\n position: \"absolute\",\n left: x,\n top: y,\n backgroundColor: \"white\",\n border: \"1px solid #ccc\",\n borderRadius: 3,\n boxShadow: \"0 2px 6px rgba(0,0,0,0.1)\",\n padding: 0,\n zIndex: 1000,\n minWidth: 160,\n fontSize: \"12px\",\n }\n\n const menuItemStyle: React.CSSProperties = {\n padding: \"4px 8px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n lineHeight: \"1.5\",\n }\n const handleItemHover = (e: React.MouseEvent<HTMLElement>) => {\n e.currentTarget.style.backgroundColor = \"#f5f5f5\"\n }\n\n const handleItemLeave = (e: React.MouseEvent<HTMLElement>) => {\n e.currentTarget.style.backgroundColor = \"\"\n }\n\n return (\n <div ref={menuRef} style={menuStyle}>\n <div\n style={menuItemStyle}\n onClick={() => {\n onSaveCamera()\n onClose()\n }}\n onMouseEnter={handleItemHover}\n onMouseLeave={handleItemLeave}\n >\n Save Camera Position\n </div>\n <div\n style={menuItemStyle}\n onClick={() => {\n onClearCamera()\n onClose()\n }}\n onMouseEnter={handleItemHover}\n onMouseLeave={handleItemLeave}\n >\n Clear Saved Camera Position\n </div>\n <div\n style={menuItemStyle}\n onClick={() => {\n onAddMark()\n onClose()\n }}\n onMouseEnter={handleItemHover}\n onMouseLeave={handleItemLeave}\n >\n Add Mark\n </div>\n <div\n style={menuItemStyle}\n onClick={() => {\n onClearMarks()\n onClose()\n }}\n onMouseEnter={handleItemHover}\n onMouseLeave={handleItemLeave}\n >\n Clear Marks\n </div>\n </div>\n )\n}\n","import { Matrix, applyToPoint } from \"transformation-matrix\"\n\nexport type MarkerPoint = {\n x: number\n y: number\n}\n\ntype MarkerProps = {\n marker: MarkerPoint\n index: number\n transform: Matrix\n}\n\nexport const Marker = ({ marker, transform }: MarkerProps) => {\n const [screenX, screenY] = applyToPoint(transform, [marker.x, marker.y])\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n pointerEvents: \"none\",\n zIndex: 900,\n }}\n >\n <g transform={`translate(${screenX}, ${screenY})`}>\n <circle\n r={7}\n fill=\"rgba(255, 0, 0, 0.5)\"\n stroke=\"rgba(255, 0, 0, 0.8)\"\n strokeWidth={2}\n />\n <circle r={2} fill=\"rgba(255, 0, 0, 0.9)\" />\n </g>\n </svg>\n )\n}\n","import React, { useRef, useEffect, useState, useMemo } from \"react\"\nimport { drawGraphicsToCanvas, getBounds, type GraphicsObject } from \"../../lib\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"./DimensionOverlay\"\nimport { getMaxStep } from \"site/utils/getMaxStep\"\nimport { getGraphicsFilteredByStep } from \"site/utils/getGraphicsFilteredByStep\"\nimport { getGraphicsBoundsWithPadding } from \"site/utils/getGraphicsBoundsWithPadding\"\n\ninterface InteractiveGraphicsCanvasProps {\n graphics: GraphicsObject\n showLabelsByDefault?: boolean\n showGrid?: boolean\n height?: number | string\n width?: number | string\n}\n\nexport function InteractiveGraphicsCanvas({\n graphics,\n showLabelsByDefault = true,\n showGrid = true,\n height = 500,\n width = \"100%\",\n}: InteractiveGraphicsCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLabels, setShowLabels] = useState(showLabelsByDefault)\n const [showLastStep, setShowLastStep] = useState(true)\n\n // Calculate the maximum step value from all graphics objects\n const maxStep = getMaxStep(graphics)\n\n // Filter graphics objects based on step\n const filteredGraphics = getGraphicsFilteredByStep(graphics, {\n activeStep,\n showLastStep,\n maxStep,\n })\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = getGraphicsBoundsWithPadding(graphics)\n\n // Use mouse transform hook for panning/zooming\n const { transform, ref: mouseTransformRef } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = () => {\n if (!canvasRef.current) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(filteredGraphics, canvasRef.current, {\n transform: transform,\n disableLabels: !showLabels,\n })\n\n // Draw a grid for reference if requested\n if (showGrid) {\n drawGrid(canvasRef.current, transform)\n }\n }\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: any) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Determine grid spacing based on zoom level\n const gridSize = 10\n\n // Draw vertical grid lines\n for (let x = -100; x <= 100; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -100 }, transform)\n const end = transformPoint({ x, y: 100 }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -100; y <= 100; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -100, y }, transform)\n const end = transformPoint({ x: 100, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: any) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [transform, size, filteredGraphics, showGrid, showLabels])\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n <div style={{ display: \"flex\", gap: \"12px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(Number.isNaN(value) ? 0 : Math.min(value, maxStep))\n }}\n disabled={activeStep === null}\n style={{ width: \"60px\" }}\n />\n\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLabels}\n onChange={(e) => {\n setShowLabels(e.target.checked)\n }}\n />\n Show labels\n </label>\n </div>\n </div>\n\n <div\n ref={(node) => {\n // Using a callback ref approach\n containerRef.current = node\n // Apply the mouse transform ref if available\n if (mouseTransformRef && node) {\n mouseTransformRef.current = node\n }\n }}\n style={{\n position: \"relative\",\n width: width,\n height: height,\n border: \"1px solid #ccc\",\n overflow: \"hidden\",\n }}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n }}\n />\n </div>\n </div>\n )\n}\n\nexport default InteractiveGraphicsCanvas\n","import { GraphicsObject } from \"lib/types\"\n\nexport function getGraphicsFilteredByStep(\n graphics: GraphicsObject,\n {\n showLastStep,\n activeStep,\n maxStep,\n }: {\n showLastStep?: boolean\n activeStep?: number | null\n maxStep?: number | null\n },\n) {\n const selectedStep = showLastStep ? maxStep : activeStep\n\n if (selectedStep === null) {\n return graphics\n }\n\n const filteredGraphics = {\n ...graphics,\n points: graphics.points?.filter(\n (p) => p.step === undefined || p.step === selectedStep,\n ),\n lines: graphics.lines?.filter(\n (l) => l.step === undefined || l.step === selectedStep,\n ),\n rects: graphics.rects?.filter(\n (r) => r.step === undefined || r.step === selectedStep,\n ),\n circles: graphics.circles?.filter(\n (c) => c.step === undefined || c.step === selectedStep,\n ),\n }\n\n return filteredGraphics\n}\n","import { getBounds } from \"lib/drawGraphicsToCanvas\"\nimport { GraphicsObject } from \"lib/types\"\n\nexport function getGraphicsBoundsWithPadding(graphics: GraphicsObject) {\n const bounds = getBounds(graphics)\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - width / 10,\n minY: bounds.minY - height / 10,\n maxX: bounds.maxX + width / 10,\n maxY: bounds.maxY + height / 10,\n }\n}\n","import React, { useRef, useEffect, useState } from \"react\"\nimport { GraphicsObject } from \"../../../lib/types\"\nimport {\n drawGraphicsToCanvas,\n getBounds,\n} from \"../../../lib/drawGraphicsToCanvas\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate, type Matrix } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\ninterface CanvasGraphicsProps {\n graphics: GraphicsObject\n width?: number\n height?: number\n withGrid?: boolean\n initialTransform?: Matrix\n disableLabels?: boolean\n}\n\n// Create a container component that handles the mouse matrix transform\nfunction TransformContainer({\n initialTransform,\n children,\n onTransformChange,\n}: {\n initialTransform: Matrix\n children: React.ReactNode\n onTransformChange: (transform: Matrix) => void\n}) {\n const { transform, ref } = useMouseMatrixTransform({\n initialTransform,\n })\n\n // Update parent with transform changes\n useEffect(() => {\n onTransformChange(transform)\n }, [transform, onTransformChange])\n\n return (\n <div\n ref={ref}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {children}\n </div>\n )\n}\n\nexport const CanvasGraphics = ({\n graphics,\n width = 600,\n height = 600,\n withGrid = true,\n disableLabels = false,\n initialTransform,\n}: CanvasGraphicsProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [size, setSize] = useState({ width, height })\n const [currentTransform, setCurrentTransform] = useState<Matrix | null>(null)\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = React.useMemo(() => {\n const bounds = getBounds(graphics)\n const bWidth = bounds.maxX - bounds.minX\n const bHeight = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - bWidth / 10,\n minY: bounds.minY - bHeight / 10,\n maxX: bounds.maxX + bWidth / 10,\n maxY: bounds.maxY + bHeight / 10,\n }\n }, [graphics])\n\n // Compute initial transform if not provided\n const computedInitialTransform = React.useMemo(() => {\n if (initialTransform) return initialTransform\n\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n yFlip\n ? -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n )\n : Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [graphics, graphicsBoundsWithPadding, initialTransform, size])\n\n // Track transform changes from the mouse transform hook\n const handleTransformChange = React.useCallback((transform: Matrix) => {\n setCurrentTransform(transform)\n }, [])\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = React.useCallback(() => {\n if (!canvasRef.current || !currentTransform) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(graphics, canvasRef.current, {\n transform: currentTransform,\n disableLabels,\n })\n\n // Draw a grid for reference if enabled\n if (withGrid) {\n drawGrid(canvasRef.current, currentTransform)\n }\n }, [canvasRef, currentTransform, graphics, size, withGrid])\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: Matrix) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Calculate a good grid size based on zoom level\n // This is an approximate calculation\n const zoomLevel = Math.abs(transform.a) // Scale factor\n const gridSize = Math.pow(10, Math.floor(Math.log10(100 / zoomLevel)))\n\n const gridRange = Math.ceil(1000 / gridSize) * gridSize\n\n // Draw vertical grid lines\n for (let x = -gridRange; x <= gridRange; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -gridRange }, transform)\n const end = transformPoint({ x, y: gridRange }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -gridRange; y <= gridRange; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -gridRange, y }, transform)\n const end = transformPoint({ x: gridRange, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: Matrix) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [drawCanvas])\n\n // Initialize transform\n useEffect(() => {\n setCurrentTransform(computedInitialTransform)\n }, [computedInitialTransform])\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n border: \"1px solid #eee\",\n overflow: \"hidden\",\n }}\n >\n <TransformContainer\n initialTransform={computedInitialTransform}\n onTransformChange={handleTransformChange}\n >\n <DimensionOverlay\n transform={currentTransform || computedInitialTransform}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n />\n </DimensionOverlay>\n </TransformContainer>\n </div>\n )\n}\n"],"mappings":"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","names":["inverse","applyToPoint","useMemo","useState","useEffect","jsx","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useMemo","applyToPoint","useMemo","applyToPoint","useMemo","useMemo","useMemo","applyToPoint","useMemo","useMemo","applyToPoint","scale","useState","applyToPoint","jsx","jsxs","container","useEffect","useRef","jsx","jsxs","applyToPoint","jsx","jsxs","jsx","jsxs","useState","useMemo","useEffect","inverse","applyToPoint","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","jsxs","useRef","useState","useMouseMatrixTransform","compose","translate","scale","useResizeObserver","transform","useEffect","React","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","useMouseMatrixTransform","useEffect","useRef","useState","React","compose","translate","scale","useResizeObserver"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "graphics-debug",
3
3
  "main": "dist/lib/index.js",
4
4
  "type": "module",
5
- "version": "0.0.40",
5
+ "version": "0.0.42",
6
6
  "files": [
7
7
  "dist"
8
8
  ],