@tsdraw/react 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, CSSProperties } from 'react';
3
- import { ZoomRange, ToolId, ColorStyle, DashStyle, FillStyle, SizeStyle, Editor, ToolDefinition, TsdrawBackgroundOptions, TsdrawEditorSnapshot, TsdrawDocumentSnapshot, Viewport } from '@tsdraw/core';
4
- export { TsdrawBackgroundCustom, TsdrawBackgroundOptions, TsdrawBackgroundPreset, TsdrawBackgroundType } from '@tsdraw/core';
3
+ import { ZoomRange, ToolId, ColorStyle, DashStyle, FillStyle, SizeStyle, Editor, ToolDefinition, AutoShapeOptions, TsdrawBackgroundOptions, TsdrawEditorSnapshot, TsdrawDocumentSnapshot, Viewport } from '@tsdraw/core';
4
+ export { AutoShapeKind, AutoShapeOptions, AutoShapeThresholds, TsdrawBackgroundCustom, TsdrawBackgroundOptions, TsdrawBackgroundPreset, TsdrawBackgroundType } from '@tsdraw/core';
5
5
 
6
6
  interface TsdrawCameraOptions {
7
7
  panSpeed?: number;
@@ -60,6 +60,7 @@ interface TsdrawCursorContext {
60
60
  isMovingSelection: boolean;
61
61
  isResizingSelection: boolean;
62
62
  isRotatingSelection: boolean;
63
+ isDraggingVertex: boolean;
63
64
  }
64
65
  interface TsdrawToolOverlayState {
65
66
  visible: boolean;
@@ -156,6 +157,7 @@ interface TsdrawProps {
156
157
  touchOptions?: TsdrawTouchOptions;
157
158
  keyboardShortcuts?: TsdrawKeyboardShortcutOptions;
158
159
  penOptions?: TsdrawPenOptions;
160
+ autoShape?: boolean | AutoShapeOptions;
159
161
  background?: TsdrawBackgroundOptions;
160
162
  readOnly?: boolean;
161
163
  autoFocus?: boolean;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, CSSProperties } from 'react';
3
- import { ZoomRange, ToolId, ColorStyle, DashStyle, FillStyle, SizeStyle, Editor, ToolDefinition, TsdrawBackgroundOptions, TsdrawEditorSnapshot, TsdrawDocumentSnapshot, Viewport } from '@tsdraw/core';
4
- export { TsdrawBackgroundCustom, TsdrawBackgroundOptions, TsdrawBackgroundPreset, TsdrawBackgroundType } from '@tsdraw/core';
3
+ import { ZoomRange, ToolId, ColorStyle, DashStyle, FillStyle, SizeStyle, Editor, ToolDefinition, AutoShapeOptions, TsdrawBackgroundOptions, TsdrawEditorSnapshot, TsdrawDocumentSnapshot, Viewport } from '@tsdraw/core';
4
+ export { AutoShapeKind, AutoShapeOptions, AutoShapeThresholds, TsdrawBackgroundCustom, TsdrawBackgroundOptions, TsdrawBackgroundPreset, TsdrawBackgroundType } from '@tsdraw/core';
5
5
 
6
6
  interface TsdrawCameraOptions {
7
7
  panSpeed?: number;
@@ -60,6 +60,7 @@ interface TsdrawCursorContext {
60
60
  isMovingSelection: boolean;
61
61
  isResizingSelection: boolean;
62
62
  isRotatingSelection: boolean;
63
+ isDraggingVertex: boolean;
63
64
  }
64
65
  interface TsdrawToolOverlayState {
65
66
  visible: boolean;
@@ -156,6 +157,7 @@ interface TsdrawProps {
156
157
  touchOptions?: TsdrawTouchOptions;
157
158
  keyboardShortcuts?: TsdrawKeyboardShortcutOptions;
158
159
  penOptions?: TsdrawPenOptions;
160
+ autoShape?: boolean | AutoShapeOptions;
159
161
  background?: TsdrawBackgroundOptions;
160
162
  readOnly?: boolean;
161
163
  autoFocus?: boolean;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useState, useMemo, useEffect, useCallback, useRef, useLayoutEffect } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { DEFAULT_COLORS, renderCanvasBackground, getSelectionBoundsPage, buildTransformSnapshots, Editor, STROKE_WIDTHS, ERASER_MARGIN, resolveThemeColor, pageToScreen, getTopShapeAtPoint, buildStartPositions, applyRotation, applyResize, applyMove, normalizeSelectionBounds, getShapesInBounds, HandDraggingState, startCameraSlide, isSelectTool, beginCameraPan, moveCameraPan } from '@tsdraw/core';
3
+ import { DEFAULT_COLORS, renderCanvasBackground, getSelectionBoundsPage, buildTransformSnapshots, Editor, getVertexHandlePagePositions, pageToScreen, STROKE_WIDTHS, ERASER_MARGIN, resolveThemeColor, findVertexHit, getTopShapeAtPoint, buildStartPositions, applyRotation, applyResize, applyMove, applyVertexDrag, normalizeSelectionBounds, getShapesInBounds, HandDraggingState, startCameraSlide, isSelectTool, beginCameraPan, moveCameraPan } from '@tsdraw/core';
4
4
  import { IconPointer, IconPencil, IconSquare, IconCircle, IconEraser, IconHandStop, IconArrowBackUp, IconArrowForwardUp } from '@tabler/icons-react';
5
5
 
6
6
  // src/components/TsdrawCanvas.tsx
@@ -8,6 +8,7 @@ function SelectionOverlay({
8
8
  selectionBrush,
9
9
  selectionBounds,
10
10
  selectionRotationDeg,
11
+ vertexHandleScreenPositions,
11
12
  currentTool,
12
13
  selectedCount,
13
14
  onRotatePointerDown,
@@ -35,7 +36,8 @@ function SelectionOverlay({
35
36
  top: selectionBounds.top,
36
37
  width: selectionBounds.width,
37
38
  height: selectionBounds.height,
38
- transform: `rotate(${selectionRotationDeg}deg)`
39
+ transform: `rotate(${selectionRotationDeg}deg)`,
40
+ transformOrigin: "center center"
39
41
  },
40
42
  children: [
41
43
  /* @__PURE__ */ jsx("div", { className: "tsdraw-selection-bounds" }),
@@ -93,7 +95,15 @@ function SelectionOverlay({
93
95
  ] })
94
96
  ]
95
97
  }
96
- )
98
+ ),
99
+ currentTool === "select" && vertexHandleScreenPositions.map((pos, index) => /* @__PURE__ */ jsx(
100
+ "div",
101
+ {
102
+ className: "tsdraw-vertex-handle",
103
+ style: { position: "absolute", left: pos.left, top: pos.top, transform: "translate(-50%, -50%)", pointerEvents: "none", zIndex: 95 }
104
+ },
105
+ `vertex-${index.toString()}`
106
+ ))
97
107
  ] });
98
108
  }
99
109
  function parseAnchor(anchor) {
@@ -452,6 +462,7 @@ function getCanvasCursor(currentTool, state) {
452
462
  if (state.isRotatingSelection) return "grabbing";
453
463
  if (state.isResizingSelection) return "nwse-resize";
454
464
  if (state.isMovingSelection) return "grabbing";
465
+ if (state.isDraggingVertex) return "grabbing";
455
466
  if (state.isHoveringSelectionBounds) return "move";
456
467
  return "default";
457
468
  }
@@ -894,6 +905,16 @@ function toScreenRect(editor, bounds) {
894
905
  height: Math.max(0, maxY - minY)
895
906
  };
896
907
  }
908
+ function selectionCenteredOnRotation(editor, startBoundsPage, centerPage) {
909
+ const startScreen = toScreenRect(editor, startBoundsPage);
910
+ const centerScreen = pageToScreen(editor.viewport, centerPage.x, centerPage.y);
911
+ return {
912
+ left: centerScreen.x - startScreen.width / 2,
913
+ top: centerScreen.y - startScreen.height / 2,
914
+ width: startScreen.width,
915
+ height: startScreen.height
916
+ };
917
+ }
897
918
  function resolveDrawColor(colorStyle, theme) {
898
919
  return resolveThemeColor(colorStyle, theme);
899
920
  }
@@ -909,6 +930,11 @@ function getHandlePagePoint(bounds, handle) {
909
930
  return { x: bounds.maxX, y: bounds.maxY };
910
931
  }
911
932
  }
933
+ function resolveAutoShapeOption(input) {
934
+ if (input === false) return { enabled: false };
935
+ if (input === true || input == null) return { enabled: true };
936
+ return { enabled: input.enabled ?? true, ...input };
937
+ }
912
938
  var ZOOM_WHEEL_CAP = 10;
913
939
  var VIEW_ONLY_TOOLS = /* @__PURE__ */ new Set(["select", "hand"]);
914
940
  function useTsdrawCanvasController(options = {}) {
@@ -920,6 +946,7 @@ function useTsdrawCanvasController(options = {}) {
920
946
  const touchOptionsRef = useRef(options.touchOptions);
921
947
  const keyboardShortcutsRef = useRef(options.keyboardShortcuts);
922
948
  const penOptionsRef = useRef(options.penOptions);
949
+ const autoShapeRef = useRef(options.autoShape);
923
950
  const backgroundRef = useRef(options.background);
924
951
  const readOnlyRef = useRef(options.readOnly ?? false);
925
952
  const containerRef = useRef(null);
@@ -948,7 +975,8 @@ function useTsdrawCanvasController(options = {}) {
948
975
  center: null,
949
976
  startAngle: 0,
950
977
  startSelectionRotationDeg: 0,
951
- startShapes: /* @__PURE__ */ new Map()
978
+ startShapes: /* @__PURE__ */ new Map(),
979
+ startBoundsPage: null
952
980
  });
953
981
  const selectDragRef = useRef({
954
982
  mode: "none",
@@ -970,6 +998,8 @@ function useTsdrawCanvasController(options = {}) {
970
998
  const [isMovingSelection, setIsMovingSelection] = useState(false);
971
999
  const [isResizingSelection, setIsResizingSelection] = useState(false);
972
1000
  const [isRotatingSelection, setIsRotatingSelection] = useState(false);
1001
+ const [isDraggingVertex, setIsDraggingVertex] = useState(false);
1002
+ const [vertexHandleScreenPositions, setVertexHandleScreenPositions] = useState([]);
973
1003
  const [canUndo, setCanUndo] = useState(false);
974
1004
  const [canRedo, setCanRedo] = useState(false);
975
1005
  const [isPersistenceReady, setIsPersistenceReady] = useState(!options.persistenceKey);
@@ -1002,6 +1032,11 @@ function useTsdrawCanvasController(options = {}) {
1002
1032
  useEffect(() => {
1003
1033
  penOptionsRef.current = options.penOptions;
1004
1034
  }, [options.penOptions]);
1035
+ useEffect(() => {
1036
+ autoShapeRef.current = options.autoShape;
1037
+ const editor = editorRef.current;
1038
+ if (editor) editor.setAutoShape(resolveAutoShapeOption(options.autoShape));
1039
+ }, [options.autoShape]);
1005
1040
  useEffect(() => {
1006
1041
  backgroundRef.current = options.background;
1007
1042
  }, [options.background]);
@@ -1058,9 +1093,12 @@ function useTsdrawCanvasController(options = {}) {
1058
1093
  setIsMovingSelection(false);
1059
1094
  setIsResizingSelection(false);
1060
1095
  setIsRotatingSelection(false);
1096
+ setIsDraggingVertex(false);
1061
1097
  selectDragRef.current.mode = "none";
1098
+ selectDragRef.current.vertexRefs = void 0;
1099
+ selectDragRef.current.vertexSnapshots = void 0;
1062
1100
  resizeRef.current = { handle: null, startBounds: null, startShapes: /* @__PURE__ */ new Map(), cursorHandleOffset: { x: 0, y: 0 } };
1063
- rotateRef.current = { center: null, startAngle: 0, startSelectionRotationDeg: 0, startShapes: /* @__PURE__ */ new Map() };
1101
+ rotateRef.current = { center: null, startAngle: 0, startSelectionRotationDeg: 0, startShapes: /* @__PURE__ */ new Map(), startBoundsPage: null };
1064
1102
  }, []);
1065
1103
  const handleResizePointerDown = useCallback(
1066
1104
  (e, handle) => {
@@ -1114,8 +1152,10 @@ function useTsdrawCanvasController(options = {}) {
1114
1152
  center,
1115
1153
  startAngle: Math.atan2(p.y - center.y, p.x - center.x),
1116
1154
  startSelectionRotationDeg: selectionRotationRef.current,
1117
- startShapes: buildTransformSnapshots(editor, selectedShapeIdsRef.current)
1155
+ startShapes: buildTransformSnapshots(editor, selectedShapeIdsRef.current),
1156
+ startBoundsPage: bounds
1118
1157
  };
1158
+ setSelectionBounds(selectionCenteredOnRotation(editor, bounds, center));
1119
1159
  isPointerActiveRef.current = true;
1120
1160
  activePointerIdsRef.current.add(e.pointerId);
1121
1161
  canvas.setPointerCapture(e.pointerId);
@@ -1140,7 +1180,8 @@ function useTsdrawCanvasController(options = {}) {
1140
1180
  const editor = new Editor({
1141
1181
  toolDefinitions: options.toolDefinitions,
1142
1182
  initialToolId: initialTool,
1143
- zoomRange: cameraOpts?.zoomRange
1183
+ zoomRange: cameraOpts?.zoomRange,
1184
+ autoShape: resolveAutoShapeOption(autoShapeRef.current)
1144
1185
  });
1145
1186
  editor.renderer.setTheme(options.theme ?? "light");
1146
1187
  if (!editor.tools.hasTool(initialTool)) {
@@ -1380,6 +1421,30 @@ function useTsdrawCanvasController(options = {}) {
1380
1421
  const pressure = (first.pressure ?? 0.5) * pressureSensitivity;
1381
1422
  const isPen = first.pointerType === "pen" || hasRealPressure(first.pressure);
1382
1423
  if (currentToolRef.current === "select") {
1424
+ if (!readOnlyRef.current) {
1425
+ const zoom = editor.viewport.zoom;
1426
+ const marginPage = 12 / zoom;
1427
+ const clusterTolerance = 20 / zoom;
1428
+ const vertexHit = findVertexHit(editor, { x, y }, marginPage, clusterTolerance);
1429
+ if (vertexHit) {
1430
+ const involvedIds = [...new Set(vertexHit.refs.map((r) => r.shapeId))];
1431
+ selectDragRef.current = {
1432
+ mode: "vertex",
1433
+ startPage: { x, y },
1434
+ currentPage: { x, y },
1435
+ startPositions: /* @__PURE__ */ new Map(),
1436
+ additive: false,
1437
+ initialSelection: [...selectedShapeIdsRef.current],
1438
+ vertexRefs: vertexHit.refs,
1439
+ vertexSnapshots: vertexHit.snapshots
1440
+ };
1441
+ setIsDraggingVertex(true);
1442
+ setSelectedShapeIds(involvedIds);
1443
+ selectedShapeIdsRef.current = involvedIds;
1444
+ refreshSelectionBounds(editor, involvedIds);
1445
+ return;
1446
+ }
1447
+ }
1383
1448
  const hit = getTopShapeAtPoint(editor, { x, y });
1384
1449
  const isHitSelected = !!(hit && selectedShapeIdsRef.current.includes(hit.id));
1385
1450
  const isInsideSelectionBounds = (() => {
@@ -1395,7 +1460,8 @@ function useTsdrawCanvasController(options = {}) {
1395
1460
  currentPage: { x, y },
1396
1461
  startPositions: buildStartPositions(editor, selectedShapeIdsRef.current),
1397
1462
  additive: false,
1398
- initialSelection: [...selectedShapeIdsRef.current]
1463
+ initialSelection: [...selectedShapeIdsRef.current],
1464
+ moveFromEmptyInsideBounds: isInsideSelectionBounds && !hit
1399
1465
  };
1400
1466
  setIsMovingSelection(true);
1401
1467
  return;
@@ -1451,13 +1517,14 @@ function useTsdrawCanvasController(options = {}) {
1451
1517
  const mode = selectDragRef.current.mode;
1452
1518
  const { x: px, y: py } = editor.input.getCurrentPagePoint();
1453
1519
  if (mode === "rotate") {
1454
- const { center, startAngle, startSelectionRotationDeg, startShapes } = rotateRef.current;
1455
- if (!center) return;
1520
+ const { center, startAngle, startSelectionRotationDeg, startShapes, startBoundsPage } = rotateRef.current;
1521
+ if (!center || !startBoundsPage) return;
1456
1522
  const angle = Math.atan2(py - center.y, px - center.x);
1457
1523
  const delta = angle - startAngle;
1458
1524
  setSelectionRotationDeg(startSelectionRotationDeg + delta * 180 / Math.PI);
1459
1525
  applyRotation(editor, startShapes, center, delta);
1460
1526
  render();
1527
+ setSelectionBounds(selectionCenteredOnRotation(editor, startBoundsPage, center));
1461
1528
  return;
1462
1529
  }
1463
1530
  if (mode === "resize") {
@@ -1475,6 +1542,20 @@ function useTsdrawCanvasController(options = {}) {
1475
1542
  refreshSelectionBounds(editor);
1476
1543
  return;
1477
1544
  }
1545
+ if (mode === "vertex") {
1546
+ const drag = selectDragRef.current;
1547
+ const refs = drag.vertexRefs;
1548
+ const snapshots = drag.vertexSnapshots;
1549
+ if (refs && snapshots) {
1550
+ applyVertexDrag(editor, snapshots, refs, {
1551
+ x: px - drag.startPage.x,
1552
+ y: py - drag.startPage.y
1553
+ });
1554
+ render();
1555
+ refreshSelectionBounds(editor);
1556
+ }
1557
+ return;
1558
+ }
1478
1559
  if (mode === "marquee") {
1479
1560
  selectDragRef.current.currentPage = { x: px, y: py };
1480
1561
  const pageRect = normalizeSelectionBounds(selectDragRef.current.startPage, selectDragRef.current.currentPage);
@@ -1512,7 +1593,7 @@ function useTsdrawCanvasController(options = {}) {
1512
1593
  setIsRotatingSelection(false);
1513
1594
  selectDragRef.current.mode = "none";
1514
1595
  setSelectionRotationDeg(0);
1515
- rotateRef.current = { center: null, startAngle: 0, startSelectionRotationDeg: 0, startShapes: /* @__PURE__ */ new Map() };
1596
+ rotateRef.current = { center: null, startAngle: 0, startSelectionRotationDeg: 0, startShapes: /* @__PURE__ */ new Map(), startBoundsPage: null };
1516
1597
  render();
1517
1598
  refreshSelectionBounds(editor);
1518
1599
  editor.endHistoryEntry();
@@ -1530,6 +1611,24 @@ function useTsdrawCanvasController(options = {}) {
1530
1611
  if (drag.mode === "move") {
1531
1612
  setIsMovingSelection(false);
1532
1613
  selectDragRef.current.mode = "none";
1614
+ const distSq = (x - drag.startPage.x) ** 2 + (y - drag.startPage.y) ** 2;
1615
+ if (drag.moveFromEmptyInsideBounds && distSq < 4) {
1616
+ setSelectedShapeIds([]);
1617
+ selectedShapeIdsRef.current = [];
1618
+ setSelectionBounds(null);
1619
+ } else {
1620
+ refreshSelectionBounds(editor);
1621
+ }
1622
+ selectDragRef.current.moveFromEmptyInsideBounds = void 0;
1623
+ render();
1624
+ editor.endHistoryEntry();
1625
+ return;
1626
+ }
1627
+ if (drag.mode === "vertex") {
1628
+ setIsDraggingVertex(false);
1629
+ selectDragRef.current.mode = "none";
1630
+ selectDragRef.current.vertexRefs = void 0;
1631
+ selectDragRef.current.vertexSnapshots = void 0;
1533
1632
  render();
1534
1633
  refreshSelectionBounds(editor);
1535
1634
  editor.endHistoryEntry();
@@ -1608,9 +1707,21 @@ function useTsdrawCanvasController(options = {}) {
1608
1707
  editor.input.pointerUp();
1609
1708
  if (currentToolRef.current === "select") {
1610
1709
  const drag = selectDragRef.current;
1611
- if (drag.mode === "rotate") setIsRotatingSelection(false);
1710
+ if (drag.mode === "rotate") {
1711
+ setIsRotatingSelection(false);
1712
+ setSelectionRotationDeg(0);
1713
+ rotateRef.current = { center: null, startAngle: 0, startSelectionRotationDeg: 0, startShapes: /* @__PURE__ */ new Map(), startBoundsPage: null };
1714
+ }
1612
1715
  if (drag.mode === "resize") setIsResizingSelection(false);
1613
- if (drag.mode === "move") setIsMovingSelection(false);
1716
+ if (drag.mode === "move") {
1717
+ setIsMovingSelection(false);
1718
+ selectDragRef.current.moveFromEmptyInsideBounds = void 0;
1719
+ }
1720
+ if (drag.mode === "vertex") {
1721
+ setIsDraggingVertex(false);
1722
+ selectDragRef.current.vertexRefs = void 0;
1723
+ selectDragRef.current.vertexSnapshots = void 0;
1724
+ }
1614
1725
  if (drag.mode === "marquee") setSelectionBrush(null);
1615
1726
  if (drag.mode !== "none") {
1616
1727
  selectDragRef.current.mode = "none";
@@ -1947,10 +2058,25 @@ function useTsdrawCanvasController(options = {}) {
1947
2058
  }, [render]);
1948
2059
  const isHoveringSelectionBounds = isPointerInsideCanvas && currentTool === "select" && selectedShapeIds.length > 0 && selectionBounds != null && pointerScreenPoint.x >= selectionBounds.left && pointerScreenPoint.x <= selectionBounds.left + selectionBounds.width && pointerScreenPoint.y >= selectionBounds.top && pointerScreenPoint.y <= selectionBounds.top + selectionBounds.height;
1949
2060
  const showToolOverlay = isPointerInsideCanvas && (currentTool === "pen" || currentTool === "eraser");
2061
+ useEffect(() => {
2062
+ const editor = editorRef.current;
2063
+ if (!editor || currentTool !== "select" || selectedShapeIds.length === 0) {
2064
+ setVertexHandleScreenPositions([]);
2065
+ return;
2066
+ }
2067
+ const pagePts = getVertexHandlePagePositions(editor, selectedShapeIds);
2068
+ setVertexHandleScreenPositions(
2069
+ pagePts.map((pg) => {
2070
+ const s = pageToScreen(editor.viewport, pg.x, pg.y);
2071
+ return { left: s.x, top: s.y };
2072
+ })
2073
+ );
2074
+ }, [currentTool, selectedShapeIds, selectionBounds, selectionRotationDeg, isPersistenceReady]);
1950
2075
  const canvasCursor = getCanvasCursor(currentTool, {
1951
2076
  isMovingSelection,
1952
2077
  isResizingSelection,
1953
2078
  isRotatingSelection,
2079
+ isDraggingVertex,
1954
2080
  isHoveringSelectionBounds,
1955
2081
  showToolOverlay
1956
2082
  });
@@ -1960,7 +2086,8 @@ function useTsdrawCanvasController(options = {}) {
1960
2086
  showToolOverlay,
1961
2087
  isMovingSelection,
1962
2088
  isResizingSelection,
1963
- isRotatingSelection
2089
+ isRotatingSelection,
2090
+ isDraggingVertex
1964
2091
  };
1965
2092
  const toolOverlay = {
1966
2093
  visible: showToolOverlay,
@@ -1983,6 +2110,7 @@ function useTsdrawCanvasController(options = {}) {
1983
2110
  selectionBrush,
1984
2111
  selectionBounds,
1985
2112
  selectionRotationDeg,
2113
+ vertexHandleScreenPositions,
1986
2114
  canvasCursor,
1987
2115
  cursorContext,
1988
2116
  toolOverlay,
@@ -2093,6 +2221,7 @@ function Tsdraw(props) {
2093
2221
  selectionBrush,
2094
2222
  selectionBounds,
2095
2223
  selectionRotationDeg,
2224
+ vertexHandleScreenPositions,
2096
2225
  canvasCursor: defaultCanvasCursor,
2097
2226
  cursorContext,
2098
2227
  toolOverlay,
@@ -2115,6 +2244,7 @@ function Tsdraw(props) {
2115
2244
  touchOptions: props.touchOptions,
2116
2245
  keyboardShortcuts: props.keyboardShortcuts,
2117
2246
  penOptions: props.penOptions,
2247
+ autoShape: props.autoShape,
2118
2248
  background: props.background,
2119
2249
  readOnly: props.readOnly,
2120
2250
  autoFocus: props.autoFocus,
@@ -2273,6 +2403,7 @@ function Tsdraw(props) {
2273
2403
  selectionBrush,
2274
2404
  selectionBounds,
2275
2405
  selectionRotationDeg,
2406
+ vertexHandleScreenPositions,
2276
2407
  currentTool,
2277
2408
  selectedCount: selectedShapeIds.length,
2278
2409
  onRotatePointerDown: handleRotatePointerDown,