canvu-react 0.3.34 → 0.3.36

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/react.js CHANGED
@@ -1818,6 +1818,67 @@ function useCanvuChromeContext() {
1818
1818
  return useContext(CanvuChromeContext);
1819
1819
  }
1820
1820
 
1821
+ // src/math/item-transform.ts
1822
+ init_rect();
1823
+ function getItemRotationRad(item) {
1824
+ return item.rotation ?? 0;
1825
+ }
1826
+ function itemLocalToWorld(lx, ly, itemX, itemY, w, h, rotationRad) {
1827
+ const c = { x: w / 2, y: h / 2 };
1828
+ const dlx = lx - c.x;
1829
+ const dly = ly - c.y;
1830
+ const cos = Math.cos(rotationRad);
1831
+ const sin = Math.sin(rotationRad);
1832
+ return {
1833
+ x: itemX + c.x + cos * dlx - sin * dly,
1834
+ y: itemY + c.y + sin * dlx + cos * dly
1835
+ };
1836
+ }
1837
+ function worldToItemLocal(wx, wy, itemX, itemY, w, h, rotationRad) {
1838
+ const c = { x: w / 2, y: h / 2 };
1839
+ const vx = wx - itemX;
1840
+ const vy = wy - itemY;
1841
+ const dx = vx - c.x;
1842
+ const dy = vy - c.y;
1843
+ const cos = Math.cos(-rotationRad);
1844
+ const sin = Math.sin(-rotationRad);
1845
+ const lx = cos * dx - sin * dy;
1846
+ const ly = sin * dx + cos * dy;
1847
+ return { x: c.x + lx, y: c.y + ly };
1848
+ }
1849
+ function itemPivotWorld(item) {
1850
+ const r = normalizeRect(item.bounds);
1851
+ return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
1852
+ }
1853
+ function boundsAabbForRotatedItem(item) {
1854
+ const rot = getItemRotationRad(item);
1855
+ if (Math.abs(rot) < 1e-12 && item.bounds.width >= 0 && item.bounds.height >= 0) {
1856
+ return item.bounds;
1857
+ }
1858
+ const r = normalizeRect(item.bounds);
1859
+ if (Math.abs(rot) < 1e-12) {
1860
+ return r;
1861
+ }
1862
+ const corners = [
1863
+ [0, 0],
1864
+ [r.width, 0],
1865
+ [r.width, r.height],
1866
+ [0, r.height]
1867
+ ];
1868
+ let minX = Infinity;
1869
+ let minY = Infinity;
1870
+ let maxX = -Infinity;
1871
+ let maxY = -Infinity;
1872
+ for (const [lx, ly] of corners) {
1873
+ const p = itemLocalToWorld(lx, ly, item.x, item.y, r.width, r.height, rot);
1874
+ minX = Math.min(minX, p.x);
1875
+ minY = Math.min(minY, p.y);
1876
+ maxX = Math.max(maxX, p.x);
1877
+ maxY = Math.max(maxY, p.y);
1878
+ }
1879
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
1880
+ }
1881
+
1821
1882
  // src/scene/clone-item.ts
1822
1883
  init_shape_builders();
1823
1884
  function cloneVectorSceneItemWithNewId(item) {
@@ -1857,20 +1918,25 @@ function markImageAsManaged(item) {
1857
1918
  };
1858
1919
  }
1859
1920
  function restackManagedImages(items) {
1860
- let anchor;
1921
+ let anchorAabbY = Infinity;
1922
+ let anchorCenterX = 0;
1861
1923
  for (const item of items) {
1862
1924
  if (!isManagedImage(item)) continue;
1863
- if (!anchor || item.bounds.y < anchor.bounds.y) anchor = item;
1925
+ const aabb = boundsAabbForRotatedItem(item);
1926
+ if (aabb.y < anchorAabbY) {
1927
+ anchorAabbY = aabb.y;
1928
+ anchorCenterX = aabb.x + aabb.width / 2;
1929
+ }
1864
1930
  }
1865
- if (!anchor) return [...items];
1866
- const anchorCenterX = anchor.bounds.x + anchor.bounds.width / 2;
1867
- const anchorTopY = anchor.bounds.y;
1868
- let cursorY = anchorTopY;
1931
+ if (!Number.isFinite(anchorAabbY)) return [...items];
1932
+ let cursorY = anchorAabbY;
1869
1933
  return items.map((item) => {
1870
1934
  if (!isManagedImage(item)) return item;
1935
+ const aabb = boundsAabbForRotatedItem(item);
1936
+ const centerY = cursorY + aabb.height / 2;
1871
1937
  const newX = anchorCenterX - item.bounds.width / 2;
1872
- const newY = cursorY;
1873
- cursorY = newY + item.bounds.height + STACK_GAP_WORLD;
1938
+ const newY = centerY - item.bounds.height / 2;
1939
+ cursorY += aabb.height + STACK_GAP_WORLD;
1874
1940
  if (item.bounds.x === newX && item.bounds.y === newY) return item;
1875
1941
  return {
1876
1942
  ...item,
@@ -1890,8 +1956,10 @@ function copyManagedImage(items, id) {
1890
1956
  return restackManagedImages(inserted);
1891
1957
  }
1892
1958
  function rotateManagedImage(items, id) {
1893
- return items.map(
1894
- (i) => i.id === id ? { ...i, rotation: ((i.rotation ?? 0) + Math.PI / 2) % (Math.PI * 2) } : i
1959
+ return restackManagedImages(
1960
+ items.map(
1961
+ (i) => i.id === id ? { ...i, rotation: ((i.rotation ?? 0) + Math.PI / 2) % (Math.PI * 2) } : i
1962
+ )
1895
1963
  );
1896
1964
  }
1897
1965
  function deleteManagedImage(items, id) {
@@ -2338,69 +2406,6 @@ function getBoardPositionStyle(position, inset = 12, zIndex = 40) {
2338
2406
  return base2;
2339
2407
  }
2340
2408
  }
2341
-
2342
- // src/math/item-transform.ts
2343
- init_rect();
2344
- function getItemRotationRad(item) {
2345
- return item.rotation ?? 0;
2346
- }
2347
- function itemLocalToWorld(lx, ly, itemX, itemY, w, h, rotationRad) {
2348
- const c = { x: w / 2, y: h / 2 };
2349
- const dlx = lx - c.x;
2350
- const dly = ly - c.y;
2351
- const cos = Math.cos(rotationRad);
2352
- const sin = Math.sin(rotationRad);
2353
- return {
2354
- x: itemX + c.x + cos * dlx - sin * dly,
2355
- y: itemY + c.y + sin * dlx + cos * dly
2356
- };
2357
- }
2358
- function worldToItemLocal(wx, wy, itemX, itemY, w, h, rotationRad) {
2359
- const c = { x: w / 2, y: h / 2 };
2360
- const vx = wx - itemX;
2361
- const vy = wy - itemY;
2362
- const dx = vx - c.x;
2363
- const dy = vy - c.y;
2364
- const cos = Math.cos(-rotationRad);
2365
- const sin = Math.sin(-rotationRad);
2366
- const lx = cos * dx - sin * dy;
2367
- const ly = sin * dx + cos * dy;
2368
- return { x: c.x + lx, y: c.y + ly };
2369
- }
2370
- function itemPivotWorld(item) {
2371
- const r = normalizeRect(item.bounds);
2372
- return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
2373
- }
2374
- function boundsAabbForRotatedItem(item) {
2375
- const rot = getItemRotationRad(item);
2376
- if (Math.abs(rot) < 1e-12 && item.bounds.width >= 0 && item.bounds.height >= 0) {
2377
- return item.bounds;
2378
- }
2379
- const r = normalizeRect(item.bounds);
2380
- if (Math.abs(rot) < 1e-12) {
2381
- return r;
2382
- }
2383
- const corners = [
2384
- [0, 0],
2385
- [r.width, 0],
2386
- [r.width, r.height],
2387
- [0, r.height]
2388
- ];
2389
- let minX = Infinity;
2390
- let minY = Infinity;
2391
- let maxX = -Infinity;
2392
- let maxY = -Infinity;
2393
- for (const [lx, ly] of corners) {
2394
- const p = itemLocalToWorld(lx, ly, item.x, item.y, r.width, r.height, rot);
2395
- minX = Math.min(minX, p.x);
2396
- minY = Math.min(minY, p.y);
2397
- maxX = Math.max(maxX, p.x);
2398
- maxY = Math.max(maxY, p.y);
2399
- }
2400
- return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
2401
- }
2402
-
2403
- // src/react/navmenu/minimap.tsx
2404
2409
  init_rect();
2405
2410
  var NavMenuMinimapSlotContext = createContext(null);
2406
2411
  function noop() {
@@ -7275,6 +7280,8 @@ body[data-canvu-pen-active="true"] [data-slot="shape-context-menu"] * {
7275
7280
  -webkit-touch-callout: none !important;
7276
7281
  }
7277
7282
  `;
7283
+ var STRAIGHT_STROKE_HOLD_DURATION_MS = 1e3;
7284
+ var STRAIGHT_STROKE_JITTER_TOLERANCE_SQUARED = 5 * 5;
7278
7285
  function debugApplePencilPointer(phase, detail) {
7279
7286
  return;
7280
7287
  }
@@ -7422,6 +7429,28 @@ function appendTouchToStrokePoints(points, touch, zoom, screenToWorldFn) {
7422
7429
  );
7423
7430
  return appendInterpolatedPoints(points, nextPoint);
7424
7431
  }
7432
+ function createStraightStrokeState(anchorPoint, clientX, clientY) {
7433
+ return {
7434
+ active: false,
7435
+ anchorPoint,
7436
+ holdScreen: { x: clientX, y: clientY },
7437
+ holdTimer: null
7438
+ };
7439
+ }
7440
+ function clearStraightStrokeHoldTimer(strokeState) {
7441
+ const straightLine = strokeState.straightLine;
7442
+ if (!straightLine?.holdTimer) return;
7443
+ clearTimeout(straightLine.holdTimer);
7444
+ straightLine.holdTimer = null;
7445
+ }
7446
+ function lastStrokePoint(points) {
7447
+ return points[points.length - 1] ?? null;
7448
+ }
7449
+ function hasMovedPastStraightStrokeJitter(straightLine, clientX, clientY) {
7450
+ const deltaX = clientX - straightLine.holdScreen.x;
7451
+ const deltaY = clientY - straightLine.holdScreen.y;
7452
+ return deltaX * deltaX + deltaY * deltaY > STRAIGHT_STROKE_JITTER_TOLERANCE_SQUARED;
7453
+ }
7425
7454
  var VectorViewport = forwardRef(
7426
7455
  function VectorViewport2({
7427
7456
  items,
@@ -7956,6 +7985,76 @@ var VectorViewport = forwardRef(
7956
7985
  },
7957
7986
  []
7958
7987
  );
7988
+ const updateStrokePreviewPoints = useCallback(
7989
+ (strokeState, points) => {
7990
+ strokeState.points = points;
7991
+ if (strokeState.itemId && strokeState.tool !== "laser") {
7992
+ const item = createFreehandStrokeItem(
7993
+ strokeState.itemId,
7994
+ points,
7995
+ strokeState.tool,
7996
+ strokeStyleRef.current
7997
+ );
7998
+ if (item) {
7999
+ renderSceneWithLivePenStroke(item);
8000
+ }
8001
+ setPlacementPreview(null);
8002
+ emitRemoteStrokePreview(strokeState.tool, points);
8003
+ return;
8004
+ }
8005
+ if (strokeState.tool === "laser") return;
8006
+ setPlacementPreview({
8007
+ kind: "stroke",
8008
+ tool: strokeState.tool,
8009
+ points,
8010
+ style: { ...strokeStyleRef.current }
8011
+ });
8012
+ },
8013
+ [emitRemoteStrokePreview, renderSceneWithLivePenStroke]
8014
+ );
8015
+ const setStraightStrokeEndpoint = useCallback(
8016
+ (strokeState, endpoint) => {
8017
+ const straightLine = strokeState.straightLine;
8018
+ if (!straightLine) return;
8019
+ straightLine.active = true;
8020
+ updateStrokePreviewPoints(strokeState, [straightLine.anchorPoint, endpoint]);
8021
+ },
8022
+ [updateStrokePreviewPoints]
8023
+ );
8024
+ const startOrRestartStraightStrokeHoldTimer = useCallback(
8025
+ (strokeState) => {
8026
+ const straightLine = strokeState.straightLine;
8027
+ if (!straightLine || strokeState.tool !== "draw") return;
8028
+ clearStraightStrokeHoldTimer(strokeState);
8029
+ straightLine.holdTimer = window.setTimeout(() => {
8030
+ straightLine.holdTimer = null;
8031
+ const currentStrokeState = dragStateRef.current;
8032
+ if (currentStrokeState.kind !== "stroke" || currentStrokeState !== strokeState) {
8033
+ return;
8034
+ }
8035
+ const endpoint = lastStrokePoint(currentStrokeState.points);
8036
+ if (!endpoint) return;
8037
+ setStraightStrokeEndpoint(currentStrokeState, endpoint);
8038
+ }, STRAIGHT_STROKE_HOLD_DURATION_MS);
8039
+ },
8040
+ [setStraightStrokeEndpoint]
8041
+ );
8042
+ const updateStraightStrokeForMove = useCallback(
8043
+ (strokeState, clientX, clientY, endpoint) => {
8044
+ const straightLine = strokeState.straightLine;
8045
+ if (!straightLine || strokeState.tool !== "draw") return false;
8046
+ if (straightLine.active) {
8047
+ setStraightStrokeEndpoint(strokeState, endpoint);
8048
+ return true;
8049
+ }
8050
+ if (straightLine.holdTimer && hasMovedPastStraightStrokeJitter(straightLine, clientX, clientY)) {
8051
+ straightLine.holdScreen = { x: clientX, y: clientY };
8052
+ startOrRestartStraightStrokeHoldTimer(strokeState);
8053
+ }
8054
+ return false;
8055
+ },
8056
+ [setStraightStrokeEndpoint, startOrRestartStraightStrokeHoldTimer]
8057
+ );
7959
8058
  const finalizeStrokeDragState = useCallback(
7960
8059
  (strokeState) => {
7961
8060
  const tool = strokeState.tool;
@@ -7966,6 +8065,7 @@ var VectorViewport = forwardRef(
7966
8065
  debugApplePencilPointer("finalize-stroke", {
7967
8066
  points: pts.length
7968
8067
  });
8068
+ clearStraightStrokeHoldTimer(strokeState);
7969
8069
  dragStateRef.current = { kind: "idle" };
7970
8070
  releaseInteractionPointer();
7971
8071
  if (itemId) {
@@ -9077,6 +9177,7 @@ var VectorViewport = forwardRef(
9077
9177
  e.clientY,
9078
9178
  e.pointerType === "pen" ? e.pressure : void 0
9079
9179
  );
9180
+ const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, e.clientX, e.clientY) : void 0;
9080
9181
  const directPenStroke = e.pointerType === "pen" && (tool === "draw" || tool === "marker");
9081
9182
  let itemId;
9082
9183
  if (directPenStroke) {
@@ -9091,13 +9192,16 @@ var VectorViewport = forwardRef(
9091
9192
  renderSceneWithLivePenStroke(item);
9092
9193
  }
9093
9194
  }
9094
- dragStateRef.current = {
9195
+ const nextDragState = {
9095
9196
  kind: "stroke",
9096
9197
  tool,
9097
9198
  points: [startPoint],
9098
9199
  pointerType: e.pointerType,
9099
- ...itemId ? { itemId } : {}
9200
+ ...itemId ? { itemId } : {},
9201
+ ...straightLine ? { straightLine } : {}
9100
9202
  };
9203
+ dragStateRef.current = nextDragState;
9204
+ startOrRestartStraightStrokeHoldTimer(nextDragState);
9101
9205
  if (tool === "laser") {
9102
9206
  setLaserTrail([{ x: worldX, y: worldY, t: Date.now() }]);
9103
9207
  setPlacementPreview(null);
@@ -9149,7 +9253,8 @@ var VectorViewport = forwardRef(
9149
9253
  emitRemoteStrokePreview,
9150
9254
  finalizeStrokeDragState,
9151
9255
  renderSceneWithLivePenStroke,
9152
- screenToWorld
9256
+ screenToWorld,
9257
+ startOrRestartStraightStrokeHoldTimer
9153
9258
  ]
9154
9259
  );
9155
9260
  useEffect(() => {
@@ -9185,6 +9290,7 @@ var VectorViewport = forwardRef(
9185
9290
  e.clientY,
9186
9291
  e.pressure
9187
9292
  );
9293
+ const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, e.clientX, e.clientY) : void 0;
9188
9294
  const itemId = createShapeId();
9189
9295
  const item = createFreehandStrokeItem(
9190
9296
  itemId,
@@ -9195,13 +9301,16 @@ var VectorViewport = forwardRef(
9195
9301
  if (item) {
9196
9302
  renderSceneWithLivePenStroke(item);
9197
9303
  }
9198
- dragStateRef.current = {
9304
+ const nextDragState = {
9199
9305
  kind: "stroke",
9200
9306
  tool,
9201
9307
  points: [startPoint],
9202
9308
  pointerType: e.pointerType,
9203
- itemId
9309
+ itemId,
9310
+ ...straightLine ? { straightLine } : {}
9204
9311
  };
9312
+ dragStateRef.current = nextDragState;
9313
+ startOrRestartStraightStrokeHoldTimer(nextDragState);
9205
9314
  activeInteractionPointerIdRef.current = e.pointerId;
9206
9315
  activeInteractionPointerTargetRef.current = null;
9207
9316
  setPlacementPreview(null);
@@ -9227,7 +9336,8 @@ var VectorViewport = forwardRef(
9227
9336
  finalizeStrokeDragState,
9228
9337
  interactive,
9229
9338
  renderSceneWithLivePenStroke,
9230
- screenToWorld
9339
+ screenToWorld,
9340
+ startOrRestartStraightStrokeHoldTimer
9231
9341
  ]);
9232
9342
  useEffect(() => {
9233
9343
  if (!interactive) return;
@@ -9286,6 +9396,7 @@ var VectorViewport = forwardRef(
9286
9396
  touch.clientY,
9287
9397
  touchPressure(touch)
9288
9398
  );
9399
+ const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, touch.clientX, touch.clientY) : void 0;
9289
9400
  const itemId = createShapeId();
9290
9401
  const item = createFreehandStrokeItem(
9291
9402
  itemId,
@@ -9296,13 +9407,16 @@ var VectorViewport = forwardRef(
9296
9407
  if (item) {
9297
9408
  renderSceneWithLivePenStroke(item);
9298
9409
  }
9299
- dragStateRef.current = {
9410
+ const nextDragState = {
9300
9411
  kind: "stroke",
9301
9412
  tool,
9302
9413
  points: [startPoint],
9303
9414
  pointerType: "pen",
9304
- itemId
9415
+ itemId,
9416
+ ...straightLine ? { straightLine } : {}
9305
9417
  };
9418
+ dragStateRef.current = nextDragState;
9419
+ startOrRestartStraightStrokeHoldTimer(nextDragState);
9306
9420
  activeInteractionPointerIdRef.current = null;
9307
9421
  activeInteractionPointerTargetRef.current = null;
9308
9422
  activeInteractionTouchIdRef.current = touch.identifier;
@@ -9321,6 +9435,21 @@ var VectorViewport = forwardRef(
9321
9435
  if (!touch) return;
9322
9436
  const cam = cameraRef.current;
9323
9437
  if (!cam) return;
9438
+ const endpoint = pointerSampleToWorldPoint(
9439
+ screenToWorld,
9440
+ touch.clientX,
9441
+ touch.clientY,
9442
+ touchPressure(touch)
9443
+ );
9444
+ if (updateStraightStrokeForMove(st, touch.clientX, touch.clientY, endpoint)) {
9445
+ debugApplePencilPointer("touchmove-stroke", {
9446
+ touchId: touch.identifier,
9447
+ points: st.points.length,
9448
+ force: touchPressure(touch)
9449
+ });
9450
+ stopTouchEvent(ev);
9451
+ return;
9452
+ }
9324
9453
  const interpolated = appendTouchToStrokePoints(
9325
9454
  st.points,
9326
9455
  touch,
@@ -9355,13 +9484,23 @@ var VectorViewport = forwardRef(
9355
9484
  if (!touch) return;
9356
9485
  const cam = cameraRef.current;
9357
9486
  if (cam) {
9358
- const completedPoints = appendTouchToStrokePoints(
9359
- st.points,
9360
- touch,
9361
- cam.zoom,
9362
- screenToWorld
9363
- );
9364
- st.points = completedPoints;
9487
+ if (st.straightLine?.active) {
9488
+ const endpoint = pointerSampleToWorldPoint(
9489
+ screenToWorld,
9490
+ touch.clientX,
9491
+ touch.clientY,
9492
+ touchPressure(touch)
9493
+ );
9494
+ setStraightStrokeEndpoint(st, endpoint);
9495
+ } else {
9496
+ const completedPoints = appendTouchToStrokePoints(
9497
+ st.points,
9498
+ touch,
9499
+ cam.zoom,
9500
+ screenToWorld
9501
+ );
9502
+ st.points = completedPoints;
9503
+ }
9365
9504
  }
9366
9505
  debugApplePencilPointer("touchend-stroke", {
9367
9506
  touchId: touch.identifier,
@@ -9406,7 +9545,10 @@ var VectorViewport = forwardRef(
9406
9545
  finalizeStrokeDragState,
9407
9546
  interactive,
9408
9547
  renderSceneWithLivePenStroke,
9409
- screenToWorld
9548
+ screenToWorld,
9549
+ setStraightStrokeEndpoint,
9550
+ startOrRestartStraightStrokeHoldTimer,
9551
+ updateStraightStrokeForMove
9410
9552
  ]);
9411
9553
  useEffect(() => {
9412
9554
  if (!interactive) return;
@@ -9439,6 +9581,15 @@ var VectorViewport = forwardRef(
9439
9581
  pressure: ev.pointerType === "pen" ? ev.pressure : void 0
9440
9582
  });
9441
9583
  }
9584
+ const endpoint = pointerSampleToWorldPoint(
9585
+ screenToWorld,
9586
+ ev.clientX,
9587
+ ev.clientY,
9588
+ ev.pointerType === "pen" ? ev.pressure : void 0
9589
+ );
9590
+ if (updateStraightStrokeForMove(st, ev.clientX, ev.clientY, endpoint)) {
9591
+ return;
9592
+ }
9442
9593
  const interpolated = appendPointerEventSamplesToStrokePoints(
9443
9594
  st.points,
9444
9595
  ev,
@@ -9606,6 +9757,7 @@ var VectorViewport = forwardRef(
9606
9757
  const cam = cameraRef.current;
9607
9758
  if (!cam) {
9608
9759
  if (st.kind === "stroke") {
9760
+ clearStraightStrokeHoldTimer(st);
9609
9761
  emitRemoteStrokePreviewClear();
9610
9762
  }
9611
9763
  if (st.kind === "erase") {
@@ -9661,13 +9813,26 @@ var VectorViewport = forwardRef(
9661
9813
  return;
9662
9814
  }
9663
9815
  if (st.kind === "stroke") {
9664
- const completedPoints = appendPointerEventSamplesToStrokePoints(
9665
- st.points,
9666
- ev,
9667
- cam.zoom,
9668
- screenToWorld
9669
- );
9670
- st.points = completedPoints;
9816
+ const completedPoints = (() => {
9817
+ if (st.straightLine?.active) {
9818
+ const endpoint = pointerSampleToWorldPoint(
9819
+ screenToWorld,
9820
+ ev.clientX,
9821
+ ev.clientY,
9822
+ ev.pointerType === "pen" ? ev.pressure : void 0
9823
+ );
9824
+ setStraightStrokeEndpoint(st, endpoint);
9825
+ return st.points;
9826
+ }
9827
+ const points = appendPointerEventSamplesToStrokePoints(
9828
+ st.points,
9829
+ ev,
9830
+ cam.zoom,
9831
+ screenToWorld
9832
+ );
9833
+ st.points = points;
9834
+ return points;
9835
+ })();
9671
9836
  debugApplePencilPointer("pointerup-stroke-points", {
9672
9837
  pointerType: ev.pointerType,
9673
9838
  pointerId: ev.pointerId,
@@ -9854,7 +10019,9 @@ var VectorViewport = forwardRef(
9854
10019
  renderSceneWithLivePenStroke,
9855
10020
  releaseInteractionPointer,
9856
10021
  requestAutoResetTool,
9857
- screenToWorld
10022
+ screenToWorld,
10023
+ setStraightStrokeEndpoint,
10024
+ updateStraightStrokeForMove
9858
10025
  ]);
9859
10026
  const selectedItemsForOverlay = useMemo(() => {
9860
10027
  return effectiveSelectedIds.map((id) => resolvedItems.find((i) => i.id === id)).filter((i) => i != null);