@inditextech/weave-sdk 3.9.1 → 3.10.0

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/sdk.js CHANGED
@@ -4,6 +4,7 @@ import { WEAVE_ASYNC_STATUS, WEAVE_AWARENESS_LAYER_ID, WEAVE_EXPORT_BACKGROUND_C
4
4
  import { getYjsDoc, getYjsValue, observeDeep, syncedStore } from "@syncedstore/core";
5
5
  import * as Y$1 from "yjs";
6
6
  import * as Y from "yjs";
7
+ import simplify from "simplify-js";
7
8
  import "konva/lib/types";
8
9
 
9
10
  //#region rolldown:runtime
@@ -18834,7 +18835,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18834
18835
  const nodesSelected = tr.nodes();
18835
18836
  if (nodesSelected.length === 1) {
18836
18837
  const node = nodesSelected[0];
18837
- stage.container().style.cursor = node.defineMousePointer() ?? "grab";
18838
+ stage.container().style.cursor = (typeof node?.defineMousePointer === "function" ? node.defineMousePointer() : null) ?? "grab";
18838
18839
  } else stage.container().style.cursor = "grab";
18839
18840
  });
18840
18841
  tr.on("mouseout", (e) => {
@@ -18891,8 +18892,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18891
18892
  let selectedNodes = [];
18892
18893
  tr.on("dragstart", (e) => {
18893
18894
  this.dragInProcess = true;
18895
+ if (!e?.evt) return;
18894
18896
  let isWheelMousePressed = false;
18895
- if (e.evt.button === 1) isWheelMousePressed = true;
18897
+ if (e.evt?.button === 1) isWheelMousePressed = true;
18896
18898
  const mainLayer = this.instance.getMainLayer();
18897
18899
  if (!mainLayer) return;
18898
18900
  initialPos = {
@@ -18929,7 +18931,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18929
18931
  y: e.target.y()
18930
18932
  };
18931
18933
  let isWheelMousePressed = false;
18932
- if (e.evt.button === 1) isWheelMousePressed = true;
18934
+ if (e.evt?.button === 1) isWheelMousePressed = true;
18933
18935
  e.cancelBubble = true;
18934
18936
  if (initialPos) {
18935
18937
  const moved = this.checkMovedDrag(initialPos, actualPos);
@@ -19272,8 +19274,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19272
19274
  this.handledClickOrTap = false;
19273
19275
  this.pointers[e.evt.pointerId] = e.evt;
19274
19276
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
19275
- if (e.evt.pointerType === "mouse" && e.evt.button !== 0) return;
19276
- if (e.evt.pointerType === "pen" && e.evt.pressure <= .05) return;
19277
+ if (e.evt.pointerType === "mouse" && e.evt?.button !== 0) return;
19278
+ if (e.evt.pointerType === "pen" && e.evt?.pressure <= .05) return;
19277
19279
  if (!this.initialized) return;
19278
19280
  if (!this.active) return;
19279
19281
  if (stage.mode() !== WEAVE_STAGE_DEFAULT_MODE) return;
@@ -19326,8 +19328,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19326
19328
  this.panLoopId = requestAnimationFrame(() => this.panLoop());
19327
19329
  });
19328
19330
  const handleMouseMove = (e) => {
19331
+ if (!e?.evt) return;
19329
19332
  const moved = this.checkMoved(e);
19330
- if (e.evt.buttons === 0) return;
19333
+ if (e.evt?.buttons === 0) return;
19331
19334
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
19332
19335
  if (!this.initialized) return;
19333
19336
  if (!this.active) return;
@@ -19497,7 +19500,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19497
19500
  this.hideHoverState();
19498
19501
  const selectedGroup = getTargetedNode(this.instance);
19499
19502
  if (!this.initialized) return;
19500
- if (e.evt.pointerType === "mouse" && e.evt.button && e.evt.button !== 0) return;
19503
+ if (e.evt.pointerType === "mouse" && e.evt?.button && e.evt?.button !== 0) return;
19501
19504
  let areNodesSelected = false;
19502
19505
  let nodeTargeted = selectedGroup && !(selectedGroup.getAttrs().active ?? false) ? selectedGroup : e.target;
19503
19506
  if (e.target === this.instance.getStage()) {
@@ -19560,7 +19563,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19560
19563
  if (areNodesSelected) {
19561
19564
  stage.container().tabIndex = 1;
19562
19565
  stage.container().focus();
19563
- stage.container().style.cursor = nodeTargeted.defineMousePointer() ?? "grab";
19566
+ stage.container().style.cursor = (typeof nodeTargeted?.defineMousePointer === "function" ? nodeTargeted.defineMousePointer() : null) ?? "grab";
19564
19567
  }
19565
19568
  this.triggerSelectedNodesEvent();
19566
19569
  }
@@ -19728,6 +19731,10 @@ const WEAVE_COPY_PASTE_CONFIG_DEFAULT = {
19728
19731
  }
19729
19732
  };
19730
19733
 
19734
+ //#endregion
19735
+ //#region src/actions/fit-to-selection-tool/constants.ts
19736
+ const FIT_TO_SELECTION_TOOL_ACTION_NAME = "fitToSelectionTool";
19737
+
19731
19738
  //#endregion
19732
19739
  //#region src/plugins/copy-paste-nodes/copy-paste-nodes.ts
19733
19740
  var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
@@ -19939,8 +19946,8 @@ var WeaveCopyPasteNodesPlugin = class extends WeavePlugin {
19939
19946
  }
19940
19947
  const nodesSelectionPlugin = this.getNodesSelectionPlugin();
19941
19948
  nodesSelectionPlugin?.setSelectedNodes(realNodes);
19942
- this.instance?.triggerAction("fitToSelectionTool", {
19943
- previousAction: "selectionTool",
19949
+ this.instance?.triggerAction(FIT_TO_SELECTION_TOOL_ACTION_NAME, {
19950
+ previousAction: SELECTION_TOOL_ACTION_NAME,
19944
19951
  smartZoom: true
19945
19952
  });
19946
19953
  this.instance.emitEvent("onPaste", {
@@ -20215,6 +20222,33 @@ const augmentKonvaNodeClass = (config) => {
20215
20222
  Konva.Node.prototype.closeCrop = function() {};
20216
20223
  Konva.Node.prototype.resetCrop = function() {};
20217
20224
  Konva.Node.prototype.dblClick = function() {};
20225
+ Konva.Node.prototype.allowedAnchors = function() {
20226
+ return [];
20227
+ };
20228
+ Konva.Node.prototype.isSelectable = function() {
20229
+ return true;
20230
+ };
20231
+ Konva.Node.prototype.handleMouseover = function() {};
20232
+ Konva.Node.prototype.handleMouseout = function() {};
20233
+ Konva.Node.prototype.handleSelectNode = function() {};
20234
+ Konva.Node.prototype.handleDeselectNode = function() {};
20235
+ Konva.Node.prototype.defineMousePointer = function() {
20236
+ return "default";
20237
+ };
20238
+ Konva.Node.prototype.canBeHovered = function() {
20239
+ return false;
20240
+ };
20241
+ Konva.Node.prototype.canDrag = function() {
20242
+ return false;
20243
+ };
20244
+ Konva.Node.prototype.canMoveToContainer = function() {
20245
+ return false;
20246
+ };
20247
+ Konva.Node.prototype.getNodeAnchors = function() {
20248
+ return [];
20249
+ };
20250
+ Konva.Node.prototype.lockMutex = function() {};
20251
+ Konva.Node.prototype.releaseMutex = function() {};
20218
20252
  };
20219
20253
  var WeaveNode = class {
20220
20254
  async register(instance) {
@@ -20506,10 +20540,11 @@ var WeaveNode = class {
20506
20540
  node.off("dragstart");
20507
20541
  node.on("dragstart", (e) => {
20508
20542
  const nodeTarget = e.target;
20543
+ if (!e.evt) return;
20509
20544
  let isWheelMousePressed = false;
20510
- if (e.evt.button === 1) isWheelMousePressed = true;
20545
+ if (e.evt?.button === 1) isWheelMousePressed = true;
20511
20546
  this.getNodesSelectionFeedbackPlugin()?.hideSelectionHalo(nodeTarget);
20512
- const canMove = nodeTarget?.canDrag() ?? false;
20547
+ const canMove = typeof nodeTarget?.canDrag === "function" ? nodeTarget.canDrag() : false;
20513
20548
  if (!canMove) {
20514
20549
  nodeTarget.stopDrag();
20515
20550
  return;
@@ -20561,7 +20596,7 @@ var WeaveNode = class {
20561
20596
  nodesSelectionPlugin?.setSelectedNodes([]);
20562
20597
  requestAnimationFrame(() => {
20563
20598
  nodesSelectionPlugin?.setSelectedNodes(this.instance.getCloningManager().getClones());
20564
- clone?.startDrag(e.evt);
20599
+ if (clone?.getStage()) clone.startDrag(e.evt);
20565
20600
  });
20566
20601
  }
20567
20602
  if (this.getNodesSelectionPlugin()?.getSelectedNodes().length === 1) this.instance.setMutexLock({
@@ -20572,7 +20607,7 @@ var WeaveNode = class {
20572
20607
  const handleDragMove = (e) => {
20573
20608
  const nodeTarget = e.target;
20574
20609
  let isWheelMousePressed = false;
20575
- if (e.evt.button === 1) isWheelMousePressed = true;
20610
+ if (e.evt?.button === 1) isWheelMousePressed = true;
20576
20611
  e.cancelBubble = true;
20577
20612
  if (e.evt?.buttons === 0) {
20578
20613
  nodeTarget.stopDrag();
@@ -20764,12 +20799,12 @@ var WeaveNode = class {
20764
20799
  }
20765
20800
  if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20766
20801
  showHover = true;
20767
- stage.container().style.cursor = realNode?.defineMousePointer() ?? "pointer";
20802
+ stage.container().style.cursor = (typeof node?.defineMousePointer === "function" ? node.defineMousePointer() : null) ?? "pointer";
20768
20803
  cancelBubble = true;
20769
20804
  }
20770
20805
  if (isNodeSelectionEnabled && this.isSelecting() && this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !(isLocked || isMutexLocked) && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
20771
20806
  showHover = true;
20772
- stage.container().style.cursor = realNode?.defineMousePointer() ?? "grab";
20807
+ stage.container().style.cursor = (typeof node?.defineMousePointer === "function" ? node.defineMousePointer() : null) ?? "grab";
20773
20808
  cancelBubble = true;
20774
20809
  }
20775
20810
  if (!isTargetable) cancelBubble = true;
@@ -22041,7 +22076,7 @@ var WeaveRegisterManager = class {
22041
22076
 
22042
22077
  //#endregion
22043
22078
  //#region package.json
22044
- var version = "3.9.1";
22079
+ var version = "3.10.0";
22045
22080
 
22046
22081
  //#endregion
22047
22082
  //#region src/managers/setup.ts
@@ -24219,6 +24254,7 @@ function loadImageSource(image, options) {
24219
24254
  }
24220
24255
  async function downscaleImageFile(file, ratio) {
24221
24256
  const bitmap = await createImageBitmap(file);
24257
+ if (bitmap.width === 0) throw new Error("Invalid image", { cause: "InvalidImage" });
24222
24258
  const width = Math.round(bitmap.width * ratio);
24223
24259
  const height = Math.round(bitmap.height * ratio);
24224
24260
  const canvas = document.createElement("canvas");
@@ -24235,13 +24271,19 @@ function getImageSizeFromFile(file) {
24235
24271
  const img = new Image();
24236
24272
  const url = URL.createObjectURL(file);
24237
24273
  img.onload = () => {
24274
+ if (img.naturalWidth === 0) {
24275
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24276
+ return;
24277
+ }
24238
24278
  resolve({
24239
24279
  width: img.naturalWidth,
24240
24280
  height: img.naturalHeight
24241
24281
  });
24242
24282
  URL.revokeObjectURL(url);
24243
24283
  };
24244
- img.onerror = reject;
24284
+ img.onerror = () => {
24285
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24286
+ };
24245
24287
  img.src = url;
24246
24288
  });
24247
24289
  }
@@ -24265,6 +24307,10 @@ const downscaleImageFromURL = (url, options) => {
24265
24307
  const img = new Image();
24266
24308
  img.crossOrigin = crossOrigin;
24267
24309
  img.onload = () => {
24310
+ if (img.naturalWidth === 0) {
24311
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24312
+ return;
24313
+ }
24268
24314
  const ratio = Math.min(maxWidth / img.width, maxHeight / img.height, 1);
24269
24315
  const width = Math.round(img.width * ratio);
24270
24316
  const height = Math.round(img.height * ratio);
@@ -24275,7 +24321,9 @@ const downscaleImageFromURL = (url, options) => {
24275
24321
  ctx.drawImage(img, 0, 0, width, height);
24276
24322
  resolve(canvas.toDataURL(type));
24277
24323
  };
24278
- img.onerror = reject;
24324
+ img.onerror = () => {
24325
+ reject(new Error("Invalid image", { cause: "InvalidImage" }));
24326
+ };
24279
24327
  img.src = url;
24280
24328
  });
24281
24329
  };
@@ -27033,15 +27081,24 @@ var WeaveImageNode = class extends WeaveNode {
27033
27081
  const imageURLToLoad = imageURL ?? "http://localhost/false-image";
27034
27082
  this.imageFallback[imageId] = Konva.Util.createImageElement();
27035
27083
  this.imageFallback[imageId].crossOrigin = this.config.crossOrigin;
27036
- this.imageFallback[imageId].onerror = (error) => {
27084
+ this.imageFallback[imageId].onerror = () => {
27037
27085
  this.imageState[imageId] = {
27038
27086
  status: "error-fallback",
27039
27087
  loaded: false,
27040
27088
  error: true
27041
27089
  };
27042
- onError(error);
27090
+ onError(new Error(`Failed to load fallback image from provided URL`, { cause: "ErrorLoadingFallbackImage" }));
27043
27091
  };
27044
27092
  this.imageFallback[imageId].onload = async () => {
27093
+ if (this.imageFallback[imageId].width === 0) {
27094
+ this.imageState[imageId] = {
27095
+ status: "error-fallback",
27096
+ loaded: false,
27097
+ error: true
27098
+ };
27099
+ onError(new Error(`Invalid fallback image provided`, { cause: "InvalidFallbackImage" }));
27100
+ return;
27101
+ }
27045
27102
  this.imageState[imageId] = {
27046
27103
  status: "loading",
27047
27104
  loaded: true,
@@ -27068,15 +27125,19 @@ var WeaveImageNode = class extends WeaveNode {
27068
27125
  }
27069
27126
  this.imageSource[imageId] = Konva.Util.createImageElement();
27070
27127
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
27071
- this.imageSource[imageId].onerror = (error) => {
27128
+ this.imageSource[imageId].onerror = () => {
27072
27129
  if (!loadingTryout) {
27073
27130
  const stage = this.instance.getStage();
27074
27131
  const image = stage.findOne(`#${imageId}`);
27075
27132
  if (image) this.setErrorState(imageId, image);
27076
27133
  }
27077
- onError(error);
27134
+ onError(new Error(`Failed to load image from provided URL`, { cause: "ErrorLoadingImage" }));
27078
27135
  };
27079
27136
  this.imageSource[imageId].onload = async () => {
27137
+ if (this.imageSource[imageId].width === 0) {
27138
+ onError(new Error(`Invalid image provided`, { cause: "InvalidImage" }));
27139
+ return;
27140
+ }
27080
27141
  const stage = this.instance.getStage();
27081
27142
  if (!this.instance.isServerSide()) stage.container().style.cursor = "pointer";
27082
27143
  this.imageState[imageId] = {
@@ -27168,14 +27229,16 @@ var WeaveImageNode = class extends WeaveNode {
27168
27229
  }
27169
27230
  },
27170
27231
  onError: (error) => {
27171
- if (!this.config.useFallbackImage) {
27232
+ let isInvalidImage = false;
27233
+ if (error.cause === "InvalidImage") isInvalidImage = true;
27234
+ if (!this.config.useFallbackImage && !isInvalidImage) {
27172
27235
  const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
27173
27236
  if (tryoutAttempts - 1 < this.config.imageLoading.maxRetryAttempts) {
27174
27237
  this.loadImageTryout(id);
27175
27238
  return;
27176
27239
  } else this.setErrorState(id, image);
27177
27240
  }
27178
- if (loadTryout) {
27241
+ if (loadTryout && !isInvalidImage) {
27179
27242
  const tryoutAttempts = this.imageTryoutAttempts[id] ?? 0;
27180
27243
  if (tryoutAttempts - 1 < this.config.imageLoading.maxRetryAttempts) {
27181
27244
  this.loadImageTryout(id);
@@ -27188,12 +27251,7 @@ var WeaveImageNode = class extends WeaveNode {
27188
27251
  return;
27189
27252
  }
27190
27253
  this.setErrorState(id, image);
27191
- image.setAttrs({ image: void 0 });
27192
- console.error("Error loading image", error);
27193
27254
  this.resolveAsyncElement(id);
27194
- imagePlaceholder?.setAttrs({ visible: true });
27195
- internalImage?.setAttrs({ visible: false });
27196
- this.cacheNode(image);
27197
27255
  }
27198
27256
  }, loadTryout);
27199
27257
  }
@@ -27994,8 +28052,8 @@ var WeaveStrokeNode = class extends WeaveNode {
27994
28052
  const segLen = Math.hypot(dx, dy) || 1;
27995
28053
  const nx = -dy / segLen;
27996
28054
  const ny = dx / segLen;
27997
- const w0 = baseW * p0.pressure / 2;
27998
- const w1 = baseW * p1.pressure / 2;
28055
+ const w0 = Math.max(baseW * p0.pressure / 2, .5);
28056
+ const w1 = Math.max(baseW * p1.pressure / 2, .5);
27999
28057
  let traveled = 0;
28000
28058
  while (traveled < segLen) {
28001
28059
  const step = Math.min(dashRemaining, segLen - traveled);
@@ -29685,8 +29743,7 @@ var WeaveVideoNode = class extends WeaveNode {
29685
29743
  this.videoPlaceholder[id] = Konva.Util.createImageElement();
29686
29744
  this.videoPlaceholder[id].crossOrigin = this.config.crossOrigin;
29687
29745
  this.videoPlaceholder[id].src = realVideoPlaceholderURL;
29688
- this.videoPlaceholder[id].onerror = (error) => {
29689
- console.error("Error loading video placeholder", realVideoPlaceholderURL, error);
29746
+ this.videoPlaceholder[id].onerror = () => {
29690
29747
  this.resolveAsyncElement(id);
29691
29748
  };
29692
29749
  this.videoPlaceholder[id].onload = () => {
@@ -32724,13 +32781,13 @@ var WeaveZoomOutToolAction = class extends WeaveAction {
32724
32781
  const stageZoomPlugin = this.getStageZoomPlugin();
32725
32782
  if (!stageZoomPlugin.canZoomOut()) return;
32726
32783
  stageZoomPlugin.zoomOut();
32727
- this.previousAction = params.previousAction;
32784
+ this.previousAction = params?.previousAction;
32728
32785
  this.cancelAction = cancelAction;
32729
32786
  this.cancelAction();
32730
32787
  }
32731
32788
  cleanup() {
32732
32789
  const stage = this.instance.getStage();
32733
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32790
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32734
32791
  stage.container().style.cursor = "default";
32735
32792
  }
32736
32793
  };
@@ -32762,13 +32819,13 @@ var WeaveZoomInToolAction = class extends WeaveAction {
32762
32819
  const stageZoomPlugin = this.getStageZoomPlugin();
32763
32820
  if (!stageZoomPlugin.canZoomIn()) return;
32764
32821
  stageZoomPlugin.zoomIn();
32765
- this.previousAction = params.previousAction;
32822
+ this.previousAction = params?.previousAction;
32766
32823
  this.cancelAction = cancelAction;
32767
32824
  this.cancelAction();
32768
32825
  }
32769
32826
  cleanup() {
32770
32827
  const stage = this.instance.getStage();
32771
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32828
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32772
32829
  stage.container().style.cursor = "default";
32773
32830
  }
32774
32831
  };
@@ -32799,21 +32856,17 @@ var WeaveFitToScreenToolAction = class extends WeaveAction {
32799
32856
  trigger(cancelAction, params) {
32800
32857
  const stageZoomPlugin = this.getStageZoomPlugin();
32801
32858
  if (stageZoomPlugin) stageZoomPlugin.fitToScreen({ overrideZoom: params?.overrideZoom ?? true });
32802
- this.previousAction = params.previousAction;
32859
+ this.previousAction = params?.previousAction;
32803
32860
  this.cancelAction = cancelAction;
32804
32861
  this.cancelAction();
32805
32862
  }
32806
32863
  cleanup() {
32807
32864
  const stage = this.instance.getStage();
32808
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32865
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32809
32866
  stage.container().style.cursor = "default";
32810
32867
  }
32811
32868
  };
32812
32869
 
32813
- //#endregion
32814
- //#region src/actions/fit-to-selection-tool/constants.ts
32815
- const FIT_TO_SELECTION_TOOL_ACTION_NAME = "fitToSelectionTool";
32816
-
32817
32870
  //#endregion
32818
32871
  //#region src/actions/fit-to-selection-tool/fit-to-selection-tool.ts
32819
32872
  var WeaveFitToSelectionToolAction = class extends WeaveAction {
@@ -32845,13 +32898,13 @@ var WeaveFitToSelectionToolAction = class extends WeaveAction {
32845
32898
  smartZoom: params?.smartZoom ?? false,
32846
32899
  overrideZoom: params?.overrideZoom ?? true
32847
32900
  });
32848
- this.previousAction = params.previousAction;
32901
+ this.previousAction = params?.previousAction;
32849
32902
  this.cancelAction = cancelAction;
32850
32903
  this.cancelAction();
32851
32904
  }
32852
32905
  cleanup() {
32853
32906
  const stage = this.instance.getStage();
32854
- if (this.previousAction !== void 0) this.instance.triggerAction(this.previousAction);
32907
+ if (this.previousAction) this.instance.triggerAction(this.previousAction);
32855
32908
  stage.container().style.cursor = "default";
32856
32909
  }
32857
32910
  };
@@ -34077,6 +34130,11 @@ const BRUSH_TOOL_DEFAULT_CONFIG = { interpolationSteps: 10 };
34077
34130
  var WeaveBrushToolAction = class extends WeaveAction {
34078
34131
  initialized = false;
34079
34132
  isSpacePressed = false;
34133
+ penActive = false;
34134
+ lastSmoothedPressure = .5;
34135
+ lastPointerPos = null;
34136
+ lastPointerTime = 0;
34137
+ predictedCount = 0;
34080
34138
  onPropsChange = void 0;
34081
34139
  onInit = void 0;
34082
34140
  constructor(params) {
@@ -34106,11 +34164,29 @@ var WeaveBrushToolAction = class extends WeaveAction {
34106
34164
  };
34107
34165
  }
34108
34166
  getEventPressure(e) {
34109
- if (e.evt.pointerType && e.evt.pointerType === "pen") return e.evt.pressure || .5;
34110
- return .5;
34167
+ const now$2 = performance.now();
34168
+ let velocity = 0;
34169
+ if (this.lastPointerPos && now$2 - this.lastPointerTime > 0) {
34170
+ const dx = e.evt.clientX - this.lastPointerPos.x;
34171
+ const dy = e.evt.clientY - this.lastPointerPos.y;
34172
+ velocity = Math.hypot(dx, dy) / (now$2 - this.lastPointerTime) * 1e3;
34173
+ }
34174
+ this.lastPointerPos = {
34175
+ x: e.evt.clientX,
34176
+ y: e.evt.clientY
34177
+ };
34178
+ this.lastPointerTime = now$2;
34179
+ const alpha = Math.min(Math.max(velocity / 1500, .15), .6);
34180
+ let raw;
34181
+ if (e.evt.pointerType === "pen") raw = e.evt.pressure || .5;
34182
+ else raw = .5;
34183
+ this.lastSmoothedPressure = alpha * raw + (1 - alpha) * this.lastSmoothedPressure;
34184
+ return Math.max(this.lastSmoothedPressure, .15);
34111
34185
  }
34112
34186
  setupEvents() {
34113
34187
  const stage = this.instance.getStage();
34188
+ this.prevTouchAction = stage.container().style.touchAction;
34189
+ stage.container().style.touchAction = "none";
34114
34190
  window.addEventListener("keyup", (e) => {
34115
34191
  if (e.code === "Space" && this.instance.getActiveAction() === BRUSH_TOOL_ACTION_NAME) this.isSpacePressed = false;
34116
34192
  }, { signal: this.instance.getEventsController()?.signal });
@@ -34135,7 +34211,9 @@ var WeaveBrushToolAction = class extends WeaveAction {
34135
34211
  if (this.state !== BRUSH_TOOL_STATE.IDLE) return;
34136
34212
  if (this.getZoomPlugin()?.isPinching()) return;
34137
34213
  if (this.isSpacePressed) return;
34138
- if (e.evt.button !== 0) return;
34214
+ if (e?.evt?.button !== 0) return;
34215
+ if (e.evt.pointerType === "touch" && this.penActive) return;
34216
+ if (e.evt.pointerType === "pen") this.penActive = true;
34139
34217
  const pointPressure = this.getEventPressure(e);
34140
34218
  this.handleStartStroke(pointPressure);
34141
34219
  e.evt.stopPropagation();
@@ -34146,12 +34224,27 @@ var WeaveBrushToolAction = class extends WeaveAction {
34146
34224
  this.setCursor();
34147
34225
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
34148
34226
  if (this.getZoomPlugin()?.isPinching()) return;
34149
- const pointPressure = this.getEventPressure(e);
34150
- this.handleMovement(pointPressure);
34227
+ const coalescedEvents = e.evt.getCoalescedEvents ? e.evt.getCoalescedEvents() : [];
34228
+ if (coalescedEvents.length > 1) {
34229
+ for (const ce of coalescedEvents) {
34230
+ const pointPressure = ce.pointerType === "pen" && typeof ce.pressure === "number" ? ce.pressure : .5;
34231
+ this.handleMovement(pointPressure, void 0, false);
34232
+ }
34233
+ const predictedEvents = e.evt.getPredictedEvents ? e.evt.getPredictedEvents() : [];
34234
+ if (predictedEvents.length > 0) {
34235
+ const last = predictedEvents[predictedEvents.length - 1];
34236
+ const predPressure = last.pointerType === "pen" && typeof last.pressure === "number" ? last.pressure : .5;
34237
+ this.handleMovement(predPressure, last, true);
34238
+ }
34239
+ } else {
34240
+ const pointPressure = this.getEventPressure(e);
34241
+ this.handleMovement(pointPressure, void 0, false);
34242
+ }
34151
34243
  e.evt.stopPropagation();
34152
34244
  };
34153
34245
  stage.on("pointermove", handlePointerMove);
34154
34246
  const handlePointerUp = (e) => {
34247
+ this.penActive = false;
34155
34248
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
34156
34249
  if (this.getZoomPlugin()?.isPinching()) return;
34157
34250
  this.handleEndStroke();
@@ -34188,6 +34281,10 @@ var WeaveBrushToolAction = class extends WeaveAction {
34188
34281
  };
34189
34282
  }
34190
34283
  handleStartStroke(pressure) {
34284
+ this.lastSmoothedPressure = .5;
34285
+ this.lastPointerPos = null;
34286
+ this.lastPointerTime = 0;
34287
+ this.predictedCount = 0;
34191
34288
  const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
34192
34289
  this.clickPoint = mousePoint;
34193
34290
  this.container = container;
@@ -34216,17 +34313,25 @@ var WeaveBrushToolAction = class extends WeaveAction {
34216
34313
  }
34217
34314
  this.setState(BRUSH_TOOL_STATE.DEFINE_STROKE);
34218
34315
  }
34219
- handleMovement(pressure) {
34316
+ handleMovement(pressure, predictedEvent, isPredicted = false) {
34220
34317
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
34318
+ const stage = this.instance.getStage();
34221
34319
  const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
34222
34320
  if (this.measureContainer && tempStroke) {
34321
+ if (predictedEvent) stage.setPointersPositions(predictedEvent);
34223
34322
  const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
34224
34323
  const currentPoint = {
34225
34324
  x: mousePoint.x - tempStroke.x(),
34226
34325
  y: mousePoint.y - tempStroke.y(),
34227
34326
  pressure
34228
34327
  };
34229
- const newStrokeElements = [...tempStroke.getAttrs().strokeElements, currentPoint];
34328
+ let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
34329
+ if (!isPredicted && this.predictedCount > 0) {
34330
+ newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
34331
+ this.predictedCount = 0;
34332
+ }
34333
+ newStrokeElements.push(currentPoint);
34334
+ if (isPredicted) this.predictedCount++;
34230
34335
  const box = this.getBoundingBox(newStrokeElements);
34231
34336
  tempStroke.setAttrs({
34232
34337
  width: box.width,
@@ -34246,17 +34351,22 @@ var WeaveBrushToolAction = class extends WeaveAction {
34246
34351
  if (nodeHandler) {
34247
34352
  const box = this.getBoundingBox(tempStroke.getAttrs().strokeElements);
34248
34353
  let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
34354
+ if (this.predictedCount > 0) {
34355
+ newStrokeElements = newStrokeElements.slice(0, -1 * this.predictedCount);
34356
+ this.predictedCount = 0;
34357
+ }
34249
34358
  newStrokeElements = newStrokeElements.map((point) => ({
34250
34359
  ...point,
34251
34360
  x: point.x - box.x,
34252
34361
  y: point.y - box.y
34253
34362
  }));
34363
+ const compressedPoints = simplify(newStrokeElements, 1, true);
34254
34364
  tempStroke.setAttrs({
34255
34365
  width: box.width,
34256
34366
  height: box.height,
34257
34367
  x: box.x,
34258
34368
  y: box.y,
34259
- strokeElements: newStrokeElements
34369
+ strokeElements: compressedPoints
34260
34370
  });
34261
34371
  const realNode = this.instance.getStage().findOne(`#${tempStroke.getAttrs().id}`);
34262
34372
  if (realNode) realNode.destroy();
@@ -34292,6 +34402,7 @@ var WeaveBrushToolAction = class extends WeaveAction {
34292
34402
  }
34293
34403
  cleanup() {
34294
34404
  const stage = this.instance.getStage();
34405
+ stage.container().style.touchAction = this.prevTouchAction;
34295
34406
  stage.container().style.cursor = "default";
34296
34407
  this.instance.emitEvent("onAddedBrush");
34297
34408
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
@@ -37946,13 +38057,13 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
37946
38057
  });
37947
38058
  stage.on("pointerdown", (e) => {
37948
38059
  const activeAction = this.instance.getActiveAction();
37949
- if (e && e.evt.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = true;
37950
- if (e && (e.evt.button === 2 || e.evt.buttons === 4)) this.isMouseMiddleButtonPressed = true;
38060
+ if (e && e?.evt?.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = true;
38061
+ if (e && (e?.evt?.button === 2 || e?.evt?.buttons === 4)) this.isMouseMiddleButtonPressed = true;
37951
38062
  });
37952
38063
  stage.on("pointerup", (e) => {
37953
38064
  const activeAction = this.instance.getActiveAction();
37954
- if (e && e.evt.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = false;
37955
- if (e && (e.evt.button === 1 || e.evt.buttons === 0)) this.isMouseMiddleButtonPressed = false;
38065
+ if (e && e?.evt?.button === 0 && activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = false;
38066
+ if (e && (e?.evt?.button === 1 || e?.evt?.buttons === 0)) this.isMouseMiddleButtonPressed = false;
37956
38067
  });
37957
38068
  const handleMouseMove = () => {
37958
38069
  if (!this.enabled || !(this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed || this.moveToolActive)) return;
@@ -38273,16 +38384,16 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
38273
38384
  let lastPos = null;
38274
38385
  stage.on("pointerdown", (e) => {
38275
38386
  this.pointers.set(e.evt.pointerId, {
38276
- x: e.evt.clientX,
38277
- y: e.evt.clientY
38387
+ x: e?.evt?.clientX ?? 0,
38388
+ y: e?.evt?.clientY ?? 0
38278
38389
  });
38279
38390
  if (this.pointers.size > 1) return;
38280
38391
  const activeAction = this.instance.getActiveAction();
38281
38392
  this.enableMove = false;
38282
38393
  if (activeAction === MOVE_TOOL_ACTION_NAME) this.moveToolActive = true;
38283
- if (e.evt.pointerType === "mouse" && e.evt.buttons === 1) this.isMouseLeftButtonPressed = true;
38284
- if (e.evt.pointerType === "mouse" && e.evt.buttons === 4) this.isMouseMiddleButtonPressed = true;
38285
- const isTouchOrPen = ["touch", "pen"].includes(e.evt.pointerType);
38394
+ if (e.evt.pointerType === "mouse" && e?.evt?.buttons === 1) this.isMouseLeftButtonPressed = true;
38395
+ if (e.evt.pointerType === "mouse" && e?.evt?.buttons === 4) this.isMouseMiddleButtonPressed = true;
38396
+ const isTouchOrPen = ["touch", "pen"].includes(e?.evt?.pointerType);
38286
38397
  if (this.enabled && (this.isSpaceKeyPressed || this.moveToolActive && (this.isMouseLeftButtonPressed || isTouchOrPen) || this.isMouseMiddleButtonPressed)) this.enableMove = true;
38287
38398
  if (this.enableMove) {
38288
38399
  this.isDragging = true;
@@ -38291,7 +38402,7 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
38291
38402
  }
38292
38403
  });
38293
38404
  stage.on("pointercancel", (e) => {
38294
- this.pointers.delete(e.evt.pointerId);
38405
+ if (e?.evt?.pointerId) this.pointers.delete(e.evt.pointerId);
38295
38406
  lastPos = null;
38296
38407
  });
38297
38408
  const handleMouseMove = (e) => {