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.cjs CHANGED
@@ -1825,6 +1825,67 @@ function useCanvuChromeContext() {
1825
1825
  return react.useContext(CanvuChromeContext);
1826
1826
  }
1827
1827
 
1828
+ // src/math/item-transform.ts
1829
+ init_rect();
1830
+ function getItemRotationRad(item) {
1831
+ return item.rotation ?? 0;
1832
+ }
1833
+ function itemLocalToWorld(lx, ly, itemX, itemY, w, h, rotationRad) {
1834
+ const c = { x: w / 2, y: h / 2 };
1835
+ const dlx = lx - c.x;
1836
+ const dly = ly - c.y;
1837
+ const cos = Math.cos(rotationRad);
1838
+ const sin = Math.sin(rotationRad);
1839
+ return {
1840
+ x: itemX + c.x + cos * dlx - sin * dly,
1841
+ y: itemY + c.y + sin * dlx + cos * dly
1842
+ };
1843
+ }
1844
+ function worldToItemLocal(wx, wy, itemX, itemY, w, h, rotationRad) {
1845
+ const c = { x: w / 2, y: h / 2 };
1846
+ const vx = wx - itemX;
1847
+ const vy = wy - itemY;
1848
+ const dx = vx - c.x;
1849
+ const dy = vy - c.y;
1850
+ const cos = Math.cos(-rotationRad);
1851
+ const sin = Math.sin(-rotationRad);
1852
+ const lx = cos * dx - sin * dy;
1853
+ const ly = sin * dx + cos * dy;
1854
+ return { x: c.x + lx, y: c.y + ly };
1855
+ }
1856
+ function itemPivotWorld(item) {
1857
+ const r = normalizeRect(item.bounds);
1858
+ return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
1859
+ }
1860
+ function boundsAabbForRotatedItem(item) {
1861
+ const rot = getItemRotationRad(item);
1862
+ if (Math.abs(rot) < 1e-12 && item.bounds.width >= 0 && item.bounds.height >= 0) {
1863
+ return item.bounds;
1864
+ }
1865
+ const r = normalizeRect(item.bounds);
1866
+ if (Math.abs(rot) < 1e-12) {
1867
+ return r;
1868
+ }
1869
+ const corners = [
1870
+ [0, 0],
1871
+ [r.width, 0],
1872
+ [r.width, r.height],
1873
+ [0, r.height]
1874
+ ];
1875
+ let minX = Infinity;
1876
+ let minY = Infinity;
1877
+ let maxX = -Infinity;
1878
+ let maxY = -Infinity;
1879
+ for (const [lx, ly] of corners) {
1880
+ const p = itemLocalToWorld(lx, ly, item.x, item.y, r.width, r.height, rot);
1881
+ minX = Math.min(minX, p.x);
1882
+ minY = Math.min(minY, p.y);
1883
+ maxX = Math.max(maxX, p.x);
1884
+ maxY = Math.max(maxY, p.y);
1885
+ }
1886
+ return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
1887
+ }
1888
+
1828
1889
  // src/scene/clone-item.ts
1829
1890
  init_shape_builders();
1830
1891
  function cloneVectorSceneItemWithNewId(item) {
@@ -1864,20 +1925,25 @@ function markImageAsManaged(item) {
1864
1925
  };
1865
1926
  }
1866
1927
  function restackManagedImages(items) {
1867
- let anchor;
1928
+ let anchorAabbY = Infinity;
1929
+ let anchorCenterX = 0;
1868
1930
  for (const item of items) {
1869
1931
  if (!isManagedImage(item)) continue;
1870
- if (!anchor || item.bounds.y < anchor.bounds.y) anchor = item;
1932
+ const aabb = boundsAabbForRotatedItem(item);
1933
+ if (aabb.y < anchorAabbY) {
1934
+ anchorAabbY = aabb.y;
1935
+ anchorCenterX = aabb.x + aabb.width / 2;
1936
+ }
1871
1937
  }
1872
- if (!anchor) return [...items];
1873
- const anchorCenterX = anchor.bounds.x + anchor.bounds.width / 2;
1874
- const anchorTopY = anchor.bounds.y;
1875
- let cursorY = anchorTopY;
1938
+ if (!Number.isFinite(anchorAabbY)) return [...items];
1939
+ let cursorY = anchorAabbY;
1876
1940
  return items.map((item) => {
1877
1941
  if (!isManagedImage(item)) return item;
1942
+ const aabb = boundsAabbForRotatedItem(item);
1943
+ const centerY = cursorY + aabb.height / 2;
1878
1944
  const newX = anchorCenterX - item.bounds.width / 2;
1879
- const newY = cursorY;
1880
- cursorY = newY + item.bounds.height + STACK_GAP_WORLD;
1945
+ const newY = centerY - item.bounds.height / 2;
1946
+ cursorY += aabb.height + STACK_GAP_WORLD;
1881
1947
  if (item.bounds.x === newX && item.bounds.y === newY) return item;
1882
1948
  return {
1883
1949
  ...item,
@@ -1897,8 +1963,10 @@ function copyManagedImage(items, id) {
1897
1963
  return restackManagedImages(inserted);
1898
1964
  }
1899
1965
  function rotateManagedImage(items, id) {
1900
- return items.map(
1901
- (i) => i.id === id ? { ...i, rotation: ((i.rotation ?? 0) + Math.PI / 2) % (Math.PI * 2) } : i
1966
+ return restackManagedImages(
1967
+ items.map(
1968
+ (i) => i.id === id ? { ...i, rotation: ((i.rotation ?? 0) + Math.PI / 2) % (Math.PI * 2) } : i
1969
+ )
1902
1970
  );
1903
1971
  }
1904
1972
  function deleteManagedImage(items, id) {
@@ -2345,69 +2413,6 @@ function getBoardPositionStyle(position, inset = 12, zIndex = 40) {
2345
2413
  return base2;
2346
2414
  }
2347
2415
  }
2348
-
2349
- // src/math/item-transform.ts
2350
- init_rect();
2351
- function getItemRotationRad(item) {
2352
- return item.rotation ?? 0;
2353
- }
2354
- function itemLocalToWorld(lx, ly, itemX, itemY, w, h, rotationRad) {
2355
- const c = { x: w / 2, y: h / 2 };
2356
- const dlx = lx - c.x;
2357
- const dly = ly - c.y;
2358
- const cos = Math.cos(rotationRad);
2359
- const sin = Math.sin(rotationRad);
2360
- return {
2361
- x: itemX + c.x + cos * dlx - sin * dly,
2362
- y: itemY + c.y + sin * dlx + cos * dly
2363
- };
2364
- }
2365
- function worldToItemLocal(wx, wy, itemX, itemY, w, h, rotationRad) {
2366
- const c = { x: w / 2, y: h / 2 };
2367
- const vx = wx - itemX;
2368
- const vy = wy - itemY;
2369
- const dx = vx - c.x;
2370
- const dy = vy - c.y;
2371
- const cos = Math.cos(-rotationRad);
2372
- const sin = Math.sin(-rotationRad);
2373
- const lx = cos * dx - sin * dy;
2374
- const ly = sin * dx + cos * dy;
2375
- return { x: c.x + lx, y: c.y + ly };
2376
- }
2377
- function itemPivotWorld(item) {
2378
- const r = normalizeRect(item.bounds);
2379
- return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
2380
- }
2381
- function boundsAabbForRotatedItem(item) {
2382
- const rot = getItemRotationRad(item);
2383
- if (Math.abs(rot) < 1e-12 && item.bounds.width >= 0 && item.bounds.height >= 0) {
2384
- return item.bounds;
2385
- }
2386
- const r = normalizeRect(item.bounds);
2387
- if (Math.abs(rot) < 1e-12) {
2388
- return r;
2389
- }
2390
- const corners = [
2391
- [0, 0],
2392
- [r.width, 0],
2393
- [r.width, r.height],
2394
- [0, r.height]
2395
- ];
2396
- let minX = Infinity;
2397
- let minY = Infinity;
2398
- let maxX = -Infinity;
2399
- let maxY = -Infinity;
2400
- for (const [lx, ly] of corners) {
2401
- const p = itemLocalToWorld(lx, ly, item.x, item.y, r.width, r.height, rot);
2402
- minX = Math.min(minX, p.x);
2403
- minY = Math.min(minY, p.y);
2404
- maxX = Math.max(maxX, p.x);
2405
- maxY = Math.max(maxY, p.y);
2406
- }
2407
- return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
2408
- }
2409
-
2410
- // src/react/navmenu/minimap.tsx
2411
2416
  init_rect();
2412
2417
  var NavMenuMinimapSlotContext = react.createContext(null);
2413
2418
  function noop() {
@@ -7282,6 +7287,8 @@ body[data-canvu-pen-active="true"] [data-slot="shape-context-menu"] * {
7282
7287
  -webkit-touch-callout: none !important;
7283
7288
  }
7284
7289
  `;
7290
+ var STRAIGHT_STROKE_HOLD_DURATION_MS = 1e3;
7291
+ var STRAIGHT_STROKE_JITTER_TOLERANCE_SQUARED = 5 * 5;
7285
7292
  function debugApplePencilPointer(phase, detail) {
7286
7293
  return;
7287
7294
  }
@@ -7429,6 +7436,28 @@ function appendTouchToStrokePoints(points, touch, zoom, screenToWorldFn) {
7429
7436
  );
7430
7437
  return appendInterpolatedPoints(points, nextPoint);
7431
7438
  }
7439
+ function createStraightStrokeState(anchorPoint, clientX, clientY) {
7440
+ return {
7441
+ active: false,
7442
+ anchorPoint,
7443
+ holdScreen: { x: clientX, y: clientY },
7444
+ holdTimer: null
7445
+ };
7446
+ }
7447
+ function clearStraightStrokeHoldTimer(strokeState) {
7448
+ const straightLine = strokeState.straightLine;
7449
+ if (!straightLine?.holdTimer) return;
7450
+ clearTimeout(straightLine.holdTimer);
7451
+ straightLine.holdTimer = null;
7452
+ }
7453
+ function lastStrokePoint(points) {
7454
+ return points[points.length - 1] ?? null;
7455
+ }
7456
+ function hasMovedPastStraightStrokeJitter(straightLine, clientX, clientY) {
7457
+ const deltaX = clientX - straightLine.holdScreen.x;
7458
+ const deltaY = clientY - straightLine.holdScreen.y;
7459
+ return deltaX * deltaX + deltaY * deltaY > STRAIGHT_STROKE_JITTER_TOLERANCE_SQUARED;
7460
+ }
7432
7461
  var VectorViewport = react.forwardRef(
7433
7462
  function VectorViewport2({
7434
7463
  items,
@@ -7963,6 +7992,76 @@ var VectorViewport = react.forwardRef(
7963
7992
  },
7964
7993
  []
7965
7994
  );
7995
+ const updateStrokePreviewPoints = react.useCallback(
7996
+ (strokeState, points) => {
7997
+ strokeState.points = points;
7998
+ if (strokeState.itemId && strokeState.tool !== "laser") {
7999
+ const item = createFreehandStrokeItem(
8000
+ strokeState.itemId,
8001
+ points,
8002
+ strokeState.tool,
8003
+ strokeStyleRef.current
8004
+ );
8005
+ if (item) {
8006
+ renderSceneWithLivePenStroke(item);
8007
+ }
8008
+ setPlacementPreview(null);
8009
+ emitRemoteStrokePreview(strokeState.tool, points);
8010
+ return;
8011
+ }
8012
+ if (strokeState.tool === "laser") return;
8013
+ setPlacementPreview({
8014
+ kind: "stroke",
8015
+ tool: strokeState.tool,
8016
+ points,
8017
+ style: { ...strokeStyleRef.current }
8018
+ });
8019
+ },
8020
+ [emitRemoteStrokePreview, renderSceneWithLivePenStroke]
8021
+ );
8022
+ const setStraightStrokeEndpoint = react.useCallback(
8023
+ (strokeState, endpoint) => {
8024
+ const straightLine = strokeState.straightLine;
8025
+ if (!straightLine) return;
8026
+ straightLine.active = true;
8027
+ updateStrokePreviewPoints(strokeState, [straightLine.anchorPoint, endpoint]);
8028
+ },
8029
+ [updateStrokePreviewPoints]
8030
+ );
8031
+ const startOrRestartStraightStrokeHoldTimer = react.useCallback(
8032
+ (strokeState) => {
8033
+ const straightLine = strokeState.straightLine;
8034
+ if (!straightLine || strokeState.tool !== "draw") return;
8035
+ clearStraightStrokeHoldTimer(strokeState);
8036
+ straightLine.holdTimer = window.setTimeout(() => {
8037
+ straightLine.holdTimer = null;
8038
+ const currentStrokeState = dragStateRef.current;
8039
+ if (currentStrokeState.kind !== "stroke" || currentStrokeState !== strokeState) {
8040
+ return;
8041
+ }
8042
+ const endpoint = lastStrokePoint(currentStrokeState.points);
8043
+ if (!endpoint) return;
8044
+ setStraightStrokeEndpoint(currentStrokeState, endpoint);
8045
+ }, STRAIGHT_STROKE_HOLD_DURATION_MS);
8046
+ },
8047
+ [setStraightStrokeEndpoint]
8048
+ );
8049
+ const updateStraightStrokeForMove = react.useCallback(
8050
+ (strokeState, clientX, clientY, endpoint) => {
8051
+ const straightLine = strokeState.straightLine;
8052
+ if (!straightLine || strokeState.tool !== "draw") return false;
8053
+ if (straightLine.active) {
8054
+ setStraightStrokeEndpoint(strokeState, endpoint);
8055
+ return true;
8056
+ }
8057
+ if (straightLine.holdTimer && hasMovedPastStraightStrokeJitter(straightLine, clientX, clientY)) {
8058
+ straightLine.holdScreen = { x: clientX, y: clientY };
8059
+ startOrRestartStraightStrokeHoldTimer(strokeState);
8060
+ }
8061
+ return false;
8062
+ },
8063
+ [setStraightStrokeEndpoint, startOrRestartStraightStrokeHoldTimer]
8064
+ );
7966
8065
  const finalizeStrokeDragState = react.useCallback(
7967
8066
  (strokeState) => {
7968
8067
  const tool = strokeState.tool;
@@ -7973,6 +8072,7 @@ var VectorViewport = react.forwardRef(
7973
8072
  debugApplePencilPointer("finalize-stroke", {
7974
8073
  points: pts.length
7975
8074
  });
8075
+ clearStraightStrokeHoldTimer(strokeState);
7976
8076
  dragStateRef.current = { kind: "idle" };
7977
8077
  releaseInteractionPointer();
7978
8078
  if (itemId) {
@@ -9084,6 +9184,7 @@ var VectorViewport = react.forwardRef(
9084
9184
  e.clientY,
9085
9185
  e.pointerType === "pen" ? e.pressure : void 0
9086
9186
  );
9187
+ const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, e.clientX, e.clientY) : void 0;
9087
9188
  const directPenStroke = e.pointerType === "pen" && (tool === "draw" || tool === "marker");
9088
9189
  let itemId;
9089
9190
  if (directPenStroke) {
@@ -9098,13 +9199,16 @@ var VectorViewport = react.forwardRef(
9098
9199
  renderSceneWithLivePenStroke(item);
9099
9200
  }
9100
9201
  }
9101
- dragStateRef.current = {
9202
+ const nextDragState = {
9102
9203
  kind: "stroke",
9103
9204
  tool,
9104
9205
  points: [startPoint],
9105
9206
  pointerType: e.pointerType,
9106
- ...itemId ? { itemId } : {}
9207
+ ...itemId ? { itemId } : {},
9208
+ ...straightLine ? { straightLine } : {}
9107
9209
  };
9210
+ dragStateRef.current = nextDragState;
9211
+ startOrRestartStraightStrokeHoldTimer(nextDragState);
9108
9212
  if (tool === "laser") {
9109
9213
  setLaserTrail([{ x: worldX, y: worldY, t: Date.now() }]);
9110
9214
  setPlacementPreview(null);
@@ -9156,7 +9260,8 @@ var VectorViewport = react.forwardRef(
9156
9260
  emitRemoteStrokePreview,
9157
9261
  finalizeStrokeDragState,
9158
9262
  renderSceneWithLivePenStroke,
9159
- screenToWorld
9263
+ screenToWorld,
9264
+ startOrRestartStraightStrokeHoldTimer
9160
9265
  ]
9161
9266
  );
9162
9267
  react.useEffect(() => {
@@ -9192,6 +9297,7 @@ var VectorViewport = react.forwardRef(
9192
9297
  e.clientY,
9193
9298
  e.pressure
9194
9299
  );
9300
+ const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, e.clientX, e.clientY) : void 0;
9195
9301
  const itemId = createShapeId();
9196
9302
  const item = createFreehandStrokeItem(
9197
9303
  itemId,
@@ -9202,13 +9308,16 @@ var VectorViewport = react.forwardRef(
9202
9308
  if (item) {
9203
9309
  renderSceneWithLivePenStroke(item);
9204
9310
  }
9205
- dragStateRef.current = {
9311
+ const nextDragState = {
9206
9312
  kind: "stroke",
9207
9313
  tool,
9208
9314
  points: [startPoint],
9209
9315
  pointerType: e.pointerType,
9210
- itemId
9316
+ itemId,
9317
+ ...straightLine ? { straightLine } : {}
9211
9318
  };
9319
+ dragStateRef.current = nextDragState;
9320
+ startOrRestartStraightStrokeHoldTimer(nextDragState);
9212
9321
  activeInteractionPointerIdRef.current = e.pointerId;
9213
9322
  activeInteractionPointerTargetRef.current = null;
9214
9323
  setPlacementPreview(null);
@@ -9234,7 +9343,8 @@ var VectorViewport = react.forwardRef(
9234
9343
  finalizeStrokeDragState,
9235
9344
  interactive,
9236
9345
  renderSceneWithLivePenStroke,
9237
- screenToWorld
9346
+ screenToWorld,
9347
+ startOrRestartStraightStrokeHoldTimer
9238
9348
  ]);
9239
9349
  react.useEffect(() => {
9240
9350
  if (!interactive) return;
@@ -9293,6 +9403,7 @@ var VectorViewport = react.forwardRef(
9293
9403
  touch.clientY,
9294
9404
  touchPressure(touch)
9295
9405
  );
9406
+ const straightLine = tool === "draw" ? createStraightStrokeState(startPoint, touch.clientX, touch.clientY) : void 0;
9296
9407
  const itemId = createShapeId();
9297
9408
  const item = createFreehandStrokeItem(
9298
9409
  itemId,
@@ -9303,13 +9414,16 @@ var VectorViewport = react.forwardRef(
9303
9414
  if (item) {
9304
9415
  renderSceneWithLivePenStroke(item);
9305
9416
  }
9306
- dragStateRef.current = {
9417
+ const nextDragState = {
9307
9418
  kind: "stroke",
9308
9419
  tool,
9309
9420
  points: [startPoint],
9310
9421
  pointerType: "pen",
9311
- itemId
9422
+ itemId,
9423
+ ...straightLine ? { straightLine } : {}
9312
9424
  };
9425
+ dragStateRef.current = nextDragState;
9426
+ startOrRestartStraightStrokeHoldTimer(nextDragState);
9313
9427
  activeInteractionPointerIdRef.current = null;
9314
9428
  activeInteractionPointerTargetRef.current = null;
9315
9429
  activeInteractionTouchIdRef.current = touch.identifier;
@@ -9328,6 +9442,21 @@ var VectorViewport = react.forwardRef(
9328
9442
  if (!touch) return;
9329
9443
  const cam = cameraRef.current;
9330
9444
  if (!cam) return;
9445
+ const endpoint = pointerSampleToWorldPoint(
9446
+ screenToWorld,
9447
+ touch.clientX,
9448
+ touch.clientY,
9449
+ touchPressure(touch)
9450
+ );
9451
+ if (updateStraightStrokeForMove(st, touch.clientX, touch.clientY, endpoint)) {
9452
+ debugApplePencilPointer("touchmove-stroke", {
9453
+ touchId: touch.identifier,
9454
+ points: st.points.length,
9455
+ force: touchPressure(touch)
9456
+ });
9457
+ stopTouchEvent(ev);
9458
+ return;
9459
+ }
9331
9460
  const interpolated = appendTouchToStrokePoints(
9332
9461
  st.points,
9333
9462
  touch,
@@ -9362,13 +9491,23 @@ var VectorViewport = react.forwardRef(
9362
9491
  if (!touch) return;
9363
9492
  const cam = cameraRef.current;
9364
9493
  if (cam) {
9365
- const completedPoints = appendTouchToStrokePoints(
9366
- st.points,
9367
- touch,
9368
- cam.zoom,
9369
- screenToWorld
9370
- );
9371
- st.points = completedPoints;
9494
+ if (st.straightLine?.active) {
9495
+ const endpoint = pointerSampleToWorldPoint(
9496
+ screenToWorld,
9497
+ touch.clientX,
9498
+ touch.clientY,
9499
+ touchPressure(touch)
9500
+ );
9501
+ setStraightStrokeEndpoint(st, endpoint);
9502
+ } else {
9503
+ const completedPoints = appendTouchToStrokePoints(
9504
+ st.points,
9505
+ touch,
9506
+ cam.zoom,
9507
+ screenToWorld
9508
+ );
9509
+ st.points = completedPoints;
9510
+ }
9372
9511
  }
9373
9512
  debugApplePencilPointer("touchend-stroke", {
9374
9513
  touchId: touch.identifier,
@@ -9413,7 +9552,10 @@ var VectorViewport = react.forwardRef(
9413
9552
  finalizeStrokeDragState,
9414
9553
  interactive,
9415
9554
  renderSceneWithLivePenStroke,
9416
- screenToWorld
9555
+ screenToWorld,
9556
+ setStraightStrokeEndpoint,
9557
+ startOrRestartStraightStrokeHoldTimer,
9558
+ updateStraightStrokeForMove
9417
9559
  ]);
9418
9560
  react.useEffect(() => {
9419
9561
  if (!interactive) return;
@@ -9446,6 +9588,15 @@ var VectorViewport = react.forwardRef(
9446
9588
  pressure: ev.pointerType === "pen" ? ev.pressure : void 0
9447
9589
  });
9448
9590
  }
9591
+ const endpoint = pointerSampleToWorldPoint(
9592
+ screenToWorld,
9593
+ ev.clientX,
9594
+ ev.clientY,
9595
+ ev.pointerType === "pen" ? ev.pressure : void 0
9596
+ );
9597
+ if (updateStraightStrokeForMove(st, ev.clientX, ev.clientY, endpoint)) {
9598
+ return;
9599
+ }
9449
9600
  const interpolated = appendPointerEventSamplesToStrokePoints(
9450
9601
  st.points,
9451
9602
  ev,
@@ -9613,6 +9764,7 @@ var VectorViewport = react.forwardRef(
9613
9764
  const cam = cameraRef.current;
9614
9765
  if (!cam) {
9615
9766
  if (st.kind === "stroke") {
9767
+ clearStraightStrokeHoldTimer(st);
9616
9768
  emitRemoteStrokePreviewClear();
9617
9769
  }
9618
9770
  if (st.kind === "erase") {
@@ -9668,13 +9820,26 @@ var VectorViewport = react.forwardRef(
9668
9820
  return;
9669
9821
  }
9670
9822
  if (st.kind === "stroke") {
9671
- const completedPoints = appendPointerEventSamplesToStrokePoints(
9672
- st.points,
9673
- ev,
9674
- cam.zoom,
9675
- screenToWorld
9676
- );
9677
- st.points = completedPoints;
9823
+ const completedPoints = (() => {
9824
+ if (st.straightLine?.active) {
9825
+ const endpoint = pointerSampleToWorldPoint(
9826
+ screenToWorld,
9827
+ ev.clientX,
9828
+ ev.clientY,
9829
+ ev.pointerType === "pen" ? ev.pressure : void 0
9830
+ );
9831
+ setStraightStrokeEndpoint(st, endpoint);
9832
+ return st.points;
9833
+ }
9834
+ const points = appendPointerEventSamplesToStrokePoints(
9835
+ st.points,
9836
+ ev,
9837
+ cam.zoom,
9838
+ screenToWorld
9839
+ );
9840
+ st.points = points;
9841
+ return points;
9842
+ })();
9678
9843
  debugApplePencilPointer("pointerup-stroke-points", {
9679
9844
  pointerType: ev.pointerType,
9680
9845
  pointerId: ev.pointerId,
@@ -9861,7 +10026,9 @@ var VectorViewport = react.forwardRef(
9861
10026
  renderSceneWithLivePenStroke,
9862
10027
  releaseInteractionPointer,
9863
10028
  requestAutoResetTool,
9864
- screenToWorld
10029
+ screenToWorld,
10030
+ setStraightStrokeEndpoint,
10031
+ updateStraightStrokeForMove
9865
10032
  ]);
9866
10033
  const selectedItemsForOverlay = react.useMemo(() => {
9867
10034
  return effectiveSelectedIds.map((id) => resolvedItems.find((i) => i.id === id)).filter((i) => i != null);