@inditextech/weave-sdk 0.37.0 → 0.38.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.cjs CHANGED
@@ -15655,6 +15655,9 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
15655
15655
  initLayer = void 0;
15656
15656
  constructor(params) {
15657
15657
  super();
15658
+ this.onAction = void 0;
15659
+ this.dragging = false;
15660
+ this.transforming = false;
15658
15661
  this.touchTimer = void 0;
15659
15662
  this.tapHold = false;
15660
15663
  this.contextMenuVisible = false;
@@ -15729,11 +15732,16 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
15729
15732
  }
15730
15733
  initEvents() {
15731
15734
  const stage = this.instance.getStage();
15735
+ this.instance.addEventListener("onActiveActionChange", (activeAction) => {
15736
+ this.onAction = activeAction;
15737
+ });
15732
15738
  this.instance.addEventListener("onDrag", (node) => {
15739
+ this.actualNode = node;
15733
15740
  if (node) this.dragging = true;
15734
15741
  else this.dragging = false;
15735
15742
  });
15736
15743
  this.instance.addEventListener("onTransform", (node) => {
15744
+ this.actualNode = node;
15737
15745
  if (node) this.transforming = true;
15738
15746
  else this.transforming = false;
15739
15747
  });
@@ -15743,15 +15751,22 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
15743
15751
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
15744
15752
  this.touchTimer = setTimeout(() => {
15745
15753
  this.tapHold = true;
15746
- if (this.touchTimer && (this.dragging || this.transforming)) {
15754
+ const actualActions = this.instance.getActiveAction();
15755
+ if (actualActions !== "selectionTool") return;
15756
+ const shouldKillLongPressTimer = this.touchTimer && (typeof this.onAction === "undefined" || typeof this.onAction !== "undefined" && ["selectionTool"].includes(this.onAction)) && (typeof this.dragging !== "undefined" && this.dragging || typeof this.transforming !== "undefined" && this.transforming);
15757
+ if (shouldKillLongPressTimer) {
15747
15758
  clearTimeout(this.touchTimer);
15748
15759
  return;
15749
15760
  }
15761
+ this.actualNode?.stopDrag();
15762
+ delete this.pointers[e.evt.pointerId];
15750
15763
  this.triggerContextMenu(e.target);
15751
15764
  }, this.tapHoldTimeout);
15752
15765
  });
15753
15766
  stage.on("pointermove", (e) => {
15754
- if (e.evt.pointerType === "mouse") return;
15767
+ if (["mouse"].includes(e.evt.pointerType)) return;
15768
+ if (["pen"].includes(e.evt.pointerType) && e.evt.pressure === 0) return;
15769
+ if (["pen"].includes(e.evt.pointerType) && (e.evt.movementX >= -1 && e.evt.movementX <= 1 || e.evt.movementY >= -1 && e.evt.movementY >= 1)) return;
15755
15770
  if (this.touchTimer) clearTimeout(this.touchTimer);
15756
15771
  });
15757
15772
  stage.on("pointerup", (e) => {
@@ -15822,8 +15837,11 @@ function checkIfOverContainer(instance, node) {
15822
15837
  if (!node.getAttrs().containerId && nodesIntersected && nodeActualContainer?.getAttrs().id !== nodesIntersected.getAttrs().id) layerToMove = nodesIntersected;
15823
15838
  return layerToMove;
15824
15839
  }
15825
- function moveNodeToContainer(instance, node) {
15840
+ function moveNodeToContainer(instance, node, ignoreContainers = []) {
15826
15841
  const nodeIntersected = instance.pointIntersectsContainerElement();
15842
+ let realNodeIntersected = nodeIntersected;
15843
+ if (realNodeIntersected && realNodeIntersected.getAttrs().nodeType === "frame" && !realNodeIntersected.getAttrs().nodeId) realNodeIntersected = instance.getStage().findOne(`#${realNodeIntersected.getAttrs().id}-selector-area`);
15844
+ if (realNodeIntersected && ignoreContainers.includes(realNodeIntersected)) return void 0;
15827
15845
  const isLocked = instance.allNodesLocked([node]);
15828
15846
  if (isLocked) return;
15829
15847
  let nodeActualContainer = node.getParent();
@@ -15980,6 +15998,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15980
15998
  ];
15981
15999
  this.active = false;
15982
16000
  this.cameFromSelectingMultiple = false;
16001
+ this.didMove = false;
16002
+ this.selectionTriggered = false;
15983
16003
  this.selecting = false;
15984
16004
  this.dragging = false;
15985
16005
  this.initialized = false;
@@ -16044,6 +16064,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16044
16064
  });
16045
16065
  tr.on("dragstart", (e) => {
16046
16066
  this.dragging = true;
16067
+ this.didMove = false;
16047
16068
  const stage$1 = this.instance.getStage();
16048
16069
  if (stage$1.isMouseWheelPressed()) {
16049
16070
  e.cancelBubble = true;
@@ -16053,7 +16074,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16053
16074
  const selectedNodes = tr.nodes();
16054
16075
  for (let i = 0; i < selectedNodes.length; i++) {
16055
16076
  const node = selectedNodes[i];
16056
- node.updatePosition(e.target.getAbsolutePosition());
16077
+ node.updatePosition(node.getAbsolutePosition());
16057
16078
  }
16058
16079
  tr.forceUpdate();
16059
16080
  e.cancelBubble = true;
@@ -16065,40 +16086,47 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16065
16086
  e.target.stopDrag();
16066
16087
  return;
16067
16088
  }
16089
+ this.didMove = true;
16090
+ e.cancelBubble = true;
16068
16091
  const selectedNodes = tr.nodes();
16092
+ let hasFrames = false;
16069
16093
  for (let i = 0; i < selectedNodes.length; i++) {
16070
16094
  const node = selectedNodes[i];
16071
- node.updatePosition(e.target.getAbsolutePosition());
16095
+ if (node.getAttrs().nodeType === "frame") hasFrames = hasFrames || true;
16096
+ node.updatePosition(node.getAbsolutePosition());
16072
16097
  }
16073
- e.cancelBubble = true;
16074
16098
  if (this.isSelecting() && selectedNodes.length > 1) {
16075
16099
  clearContainerTargets(this.instance);
16076
16100
  const layerToMove = checkIfOverContainer(this.instance, e.target);
16077
- if (layerToMove) layerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
16101
+ if (layerToMove && !hasFrames) layerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
16078
16102
  }
16079
16103
  tr.forceUpdate();
16080
16104
  };
16081
- tr.on("dragmove", (0, import_lodash.throttle)(handleDragMove, 50));
16105
+ tr.on("dragmove", handleDragMove);
16082
16106
  tr.on("dragend", (e) => {
16107
+ if (!this.didMove) return;
16083
16108
  this.dragging = false;
16084
16109
  e.cancelBubble = true;
16085
16110
  const selectedNodes = tr.nodes();
16111
+ let hasFrames = false;
16086
16112
  for (let i = 0; i < selectedNodes.length; i++) {
16087
16113
  const node = selectedNodes[i];
16088
- node.updatePosition(e.target.getAbsolutePosition());
16114
+ if (node.getAttrs().nodeType === "frame") hasFrames = hasFrames || true;
16115
+ node.updatePosition(node.getAbsolutePosition());
16089
16116
  }
16090
16117
  if (this.isSelecting() && tr.nodes().length > 1) {
16091
16118
  const actualCursor = stage.container().style.cursor;
16092
16119
  stage.container().style.cursor = "wait";
16093
16120
  clearContainerTargets(this.instance);
16121
+ const toSelect = [];
16094
16122
  const toUpdate = [];
16095
16123
  const nodeUpdatePromise = (node) => {
16096
16124
  return new Promise((resolve) => {
16097
16125
  setTimeout(() => {
16098
- const layerToMove = moveNodeToContainer(this.instance, node);
16099
- if (layerToMove) return resolve();
16126
+ moveNodeToContainer(this.instance, node, selectedNodes);
16100
16127
  const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
16101
16128
  if (!nodeHandler) return resolve();
16129
+ toSelect.push(node.getAttrs().id ?? "");
16102
16130
  toUpdate.push(nodeHandler.serialize(node));
16103
16131
  resolve();
16104
16132
  }, 0);
@@ -16110,6 +16138,15 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16110
16138
  if (results.length > 0) this.instance.updateNodes(toUpdate);
16111
16139
  stage.container().style.cursor = actualCursor;
16112
16140
  });
16141
+ setTimeout(() => {
16142
+ const finalSelectedNodes = [];
16143
+ toSelect.forEach((nodeId) => {
16144
+ const actNode = this.instance.getStage().findOne(`#${nodeId}`);
16145
+ if (actNode) finalSelectedNodes.push(actNode);
16146
+ });
16147
+ tr.nodes(finalSelectedNodes);
16148
+ tr.forceUpdate();
16149
+ }, 0);
16113
16150
  }
16114
16151
  tr.forceUpdate();
16115
16152
  });
@@ -16188,6 +16225,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16188
16225
  if (!this.initialized) return;
16189
16226
  if (!this.active) return;
16190
16227
  if (e.evt.pointerType === "mouse" && e.evt.button !== 0) return;
16228
+ if (e.evt.pointerType === "pen" && e.evt.pressure <= .05) return;
16191
16229
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
16192
16230
  const selectedGroup = this.instance.getInstanceRecursive(e.target);
16193
16231
  if (!(e.target instanceof konva.default.Stage) && !(selectedGroup && selectedGroup.getAttrs().nodeType === "frame")) return;
@@ -16202,11 +16240,16 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16202
16240
  this.selectionRectangle.height(0);
16203
16241
  this.selecting = true;
16204
16242
  this.instance.emitEvent("onSelectionState", true);
16205
- if (!(e.target instanceof konva.default.Stage)) this.cameFromSelectingMultiple = true;
16206
16243
  });
16207
16244
  const handleMouseMove = (e) => {
16245
+ if (this.selectionTriggered) {
16246
+ this.selectionTriggered = false;
16247
+ this.selectionRectangle.setAttrs({ visible: false });
16248
+ return;
16249
+ }
16208
16250
  if (!this.initialized) return;
16209
16251
  if (!this.active) return;
16252
+ if (e.evt.pointerType === "pen" && e.evt.pressure <= .05) return;
16210
16253
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length > 1) return;
16211
16254
  const contextMenuPlugin = this.instance.getPlugin("contextMenu");
16212
16255
  if (contextMenuPlugin && contextMenuPlugin.isContextMenuVisible()) {
@@ -16228,12 +16271,18 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16228
16271
  height: Math.abs(y2 - y1)
16229
16272
  });
16230
16273
  };
16231
- stage.on("pointermove", (0, import_lodash.throttle)(handleMouseMove, 50));
16274
+ stage.on("pointermove", handleMouseMove);
16232
16275
  stage.on("pointerup", (e) => {
16233
16276
  delete this.pointers[e.evt.pointerId];
16277
+ if (this.selectionTriggered) {
16278
+ this.selectionTriggered = false;
16279
+ this.selectionRectangle.setAttrs({ visible: false });
16280
+ return;
16281
+ }
16234
16282
  if (!this.initialized) return;
16235
16283
  if (!this.active) return;
16236
16284
  if (!this.selecting) return;
16285
+ if (e.evt.pointerType === "pen" && e.evt.pressure > 0) return;
16237
16286
  if (e.evt.pointerType === "touch" && Object.keys(this.pointers).length + 1 > 1) return;
16238
16287
  const contextMenuPlugin = this.instance.getPlugin("contextMenu");
16239
16288
  if (contextMenuPlugin && contextMenuPlugin.isContextMenuVisible()) {
@@ -16246,7 +16295,6 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16246
16295
  this.cameFromSelectingMultiple = false;
16247
16296
  return;
16248
16297
  }
16249
- this.tr.nodes([]);
16250
16298
  this.selectionRectangle.visible(false);
16251
16299
  const shapes = stage.find((node) => {
16252
16300
  return ["Shape", "Group"].includes(node.getType()) && typeof node.getAttrs().id !== "undefined";
@@ -16266,9 +16314,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16266
16314
  });
16267
16315
  const selectedNodes = new Set();
16268
16316
  const framesNodes = selected.filter((shape) => {
16269
- return shape.getAttrs().nodeType === "frame";
16317
+ return shape instanceof konva.default.Rect && shape.getAttrs().nodeType === "frame";
16270
16318
  });
16271
- const framesNodesIds = framesNodes.map((shape) => {
16319
+ let framesNodesIds = framesNodes.map((shape) => {
16272
16320
  if (shape.getAttrs().nodeType === "frame" && shape.getAttrs().nodeId) return stage.findOne(`#${shape.getAttrs().nodeId}`);
16273
16321
  return shape;
16274
16322
  }).filter((shape) => {
@@ -16276,6 +16324,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16276
16324
  }).map((shape) => {
16277
16325
  return shape.getAttrs().id;
16278
16326
  });
16327
+ const uniqueFramesNodesIds = new Set(framesNodesIds);
16328
+ framesNodesIds = Array.from(uniqueFramesNodesIds);
16279
16329
  const otherNodes = selected.filter((shape) => shape.getAttrs().nodeType !== "frame");
16280
16330
  otherNodes.forEach((node) => {
16281
16331
  let parent = this.instance.getInstanceRecursive(node.getParent());
@@ -16286,12 +16336,15 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16286
16336
  const frameNode = node;
16287
16337
  if (!frameNode.getAttrs().locked) selectedNodes.add(frameNode);
16288
16338
  });
16339
+ this.selecting = false;
16289
16340
  this.tr.nodes([...selectedNodes]);
16290
16341
  this.triggerSelectedNodesEvent();
16291
16342
  stage.container().tabIndex = 1;
16292
16343
  stage.container().focus();
16293
16344
  });
16294
16345
  stage.on("pointerclick", (e) => {
16346
+ e.cancelBubble = true;
16347
+ this.selectionTriggered = false;
16295
16348
  if (!this.enabled) return;
16296
16349
  if (this.instance.getActiveAction() !== "selectionTool") return;
16297
16350
  if (this.dragging) return;
@@ -16307,17 +16360,17 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16307
16360
  let selectedGroup = void 0;
16308
16361
  const mousePos = stage.getPointerPosition();
16309
16362
  if (mousePos) {
16310
- const inter = stage.getIntersection(mousePos);
16311
- if (inter) selectedGroup = this.instance.getInstanceRecursive(inter);
16363
+ const allInter = stage.getAllIntersections(mousePos);
16364
+ if (allInter && allInter.length === 1) selectedGroup = this.instance.getInstanceRecursive(allInter[0]);
16312
16365
  }
16313
16366
  if (!this.initialized) return;
16314
- if (e.evt.button && e.evt.button !== 0) return;
16315
- if (this.selectionRectangle.visible()) return;
16367
+ if (e.evt.pointerType === "mouse" && e.evt.button && e.evt.button !== 0) return;
16316
16368
  if (e.target instanceof konva.default.Stage && !selectedGroup) {
16369
+ e.evt.preventDefault();
16317
16370
  this.tr.nodes([]);
16318
16371
  this.triggerSelectedNodesEvent();
16319
16372
  if (contextMenuPlugin && !contextMenuPlugin.isTapHold()) this.instance.emitEvent("onStageSelection");
16320
- return;
16373
+ return false;
16321
16374
  }
16322
16375
  let areNodesSelected = false;
16323
16376
  let nodeTargeted = selectedGroup && !(selectedGroup.getAttrs().active ?? false) ? selectedGroup : e.target;
@@ -16364,6 +16417,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
16364
16417
  stage.container().focus();
16365
16418
  stage.container().style.cursor = "grab";
16366
16419
  }
16420
+ this.selectionTriggered = true;
16367
16421
  this.triggerSelectedNodesEvent();
16368
16422
  });
16369
16423
  }
@@ -16747,7 +16801,13 @@ var WeaveNode = class {
16747
16801
  if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(node$1));
16748
16802
  });
16749
16803
  node.on("dragstart", (e) => {
16804
+ this.didMove = false;
16750
16805
  const stage = this.instance.getStage();
16806
+ const isErasing = this.instance.getActiveAction() === "eraseTool";
16807
+ if (isErasing) {
16808
+ e.target.stopDrag();
16809
+ return;
16810
+ }
16751
16811
  this.instance.emitEvent("onDrag", e.target);
16752
16812
  if (stage.isMouseWheelPressed()) {
16753
16813
  e.cancelBubble = true;
@@ -16755,7 +16815,13 @@ var WeaveNode = class {
16755
16815
  }
16756
16816
  });
16757
16817
  const handleDragMove = (e) => {
16818
+ this.didMove = true;
16758
16819
  const stage = this.instance.getStage();
16820
+ const isErasing = this.instance.getActiveAction() === "eraseTool";
16821
+ if (isErasing) {
16822
+ e.target.stopDrag();
16823
+ return;
16824
+ }
16759
16825
  if (stage.isMouseWheelPressed()) {
16760
16826
  e.cancelBubble = true;
16761
16827
  e.target.stopDrag();
@@ -16765,12 +16831,16 @@ var WeaveNode = class {
16765
16831
  clearContainerTargets(this.instance);
16766
16832
  const layerToMove = checkIfOverContainer(this.instance, e.target);
16767
16833
  if (layerToMove) layerToMove.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetEnter, { bubbles: true });
16768
- const nodeHandler = this.instance.getNodeHandler(node.getAttrs().nodeType);
16769
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(node));
16770
16834
  }
16771
16835
  };
16772
16836
  node.on("dragmove", (0, import_lodash.throttle)(handleDragMove, 100));
16773
16837
  node.on("dragend", (e) => {
16838
+ if (!this.didMove) return;
16839
+ const isErasing = this.instance.getActiveAction() === "eraseTool";
16840
+ if (isErasing) {
16841
+ e.target.stopDrag();
16842
+ return;
16843
+ }
16774
16844
  this.instance.emitEvent("onDrag", null);
16775
16845
  if (this.isSelecting() && this.isNodeSelected(node)) {
16776
16846
  clearContainerTargets(this.instance);
@@ -16874,14 +16944,19 @@ var WeaveNode = class {
16874
16944
  }
16875
16945
  unlock(instance) {
16876
16946
  if (instance.getAttrs().nodeType !== this.getNodeType()) return;
16877
- instance.setAttrs({ locked: false });
16878
- this.instance.updateNode(this.serialize(instance));
16879
- this.setupDefaultNodeEvents(instance);
16947
+ let realInstance = instance;
16948
+ if (instance.getAttrs().nodeId) realInstance = this.instance.getStage().findOne(`#${instance.getAttrs().nodeId}`);
16949
+ if (!realInstance) return;
16950
+ realInstance.setAttrs({ locked: false });
16951
+ this.instance.updateNode(this.serialize(realInstance));
16952
+ this.setupDefaultNodeEvents(realInstance);
16880
16953
  const stage = this.instance.getStage();
16881
16954
  stage.container().style.cursor = "default";
16882
16955
  }
16883
16956
  isLocked(instance) {
16884
- return instance.getAttrs().locked ?? false;
16957
+ let realInstance = instance;
16958
+ if (instance.getAttrs().nodeId === false) realInstance = this.instance.getInstanceRecursive(instance);
16959
+ return realInstance.getAttrs().locked ?? false;
16885
16960
  }
16886
16961
  };
16887
16962
 
@@ -16889,6 +16964,11 @@ var WeaveNode = class {
16889
16964
  //#region src/actions/action.ts
16890
16965
  var WeaveAction = class {
16891
16966
  constructor() {
16967
+ this.tapStart = {
16968
+ x: 0,
16969
+ y: 0,
16970
+ time: 0
16971
+ };
16892
16972
  return new Proxy(this, { set: (target, key, value) => {
16893
16973
  Reflect.set(target, key, value);
16894
16974
  this.onPropsChange?.();
@@ -16920,6 +17000,26 @@ var WeaveAction = class {
16920
17000
  getProps() {
16921
17001
  return this.props;
16922
17002
  }
17003
+ isPressed(e) {
17004
+ return e.evt.buttons > 0;
17005
+ }
17006
+ setTapStart(e) {
17007
+ this.tapStart = {
17008
+ x: e.evt.clientX,
17009
+ y: e.evt.clientY,
17010
+ time: performance.now()
17011
+ };
17012
+ }
17013
+ isTap(e) {
17014
+ if (!this.tapStart) return false;
17015
+ const dx = e.evt.clientX - this.tapStart.x;
17016
+ const dy = e.evt.clientY - this.tapStart.y;
17017
+ const dist = Math.sqrt(dx * dx + dy * dy);
17018
+ const dt = performance.now() - this.tapStart.time;
17019
+ const TAP_DISTANCE = 10;
17020
+ const TAP_TIME = 300;
17021
+ return (e.evt.pointerType === "pen" || e.evt.pointerType === "touch") && dist < TAP_DISTANCE && dt < TAP_TIME;
17022
+ }
16923
17023
  };
16924
17024
 
16925
17025
  //#endregion
@@ -17975,23 +18075,30 @@ var WeaveZIndexManager = class {
17975
18075
  this.instance.moveNode(node, __inditextech_weave_types.WEAVE_NODE_POSITION.DOWN);
17976
18076
  }
17977
18077
  }
17978
- sendToBack(instance) {
17979
- this.logger.debug(`Moving instance with id [${instance.getAttrs().id}], to bottom of z-index`);
17980
- instance.moveToBottom();
17981
- const handler = this.instance.getNodeHandler(instance.getAttrs().nodeType);
17982
- if (handler) {
17983
- const node = handler.serialize(instance);
17984
- this.instance.moveNode(node, __inditextech_weave_types.WEAVE_NODE_POSITION.BACK);
18078
+ sendToBack(instances) {
18079
+ const nodes = Array.isArray(instances) ? instances : [instances];
18080
+ const nodesDescending = nodes.toSorted((a, b) => b.zIndex() - a.zIndex());
18081
+ for (const node of nodesDescending) {
18082
+ node.moveToBottom();
18083
+ const handler = this.instance.getNodeHandler(node.getAttrs().nodeType);
18084
+ if (handler) {
18085
+ const nodeState = handler.serialize(node);
18086
+ this.instance.updateNode(nodeState);
18087
+ this.instance.moveNode(nodeState, __inditextech_weave_types.WEAVE_NODE_POSITION.BACK);
18088
+ }
17985
18089
  }
17986
18090
  }
17987
- bringToFront(instance) {
17988
- this.logger.debug(`Moving instance with id [${instance.getAttrs().id}], to top of z-index`);
17989
- instance.moveToTop();
17990
- const handler = this.instance.getNodeHandler(instance.getAttrs().nodeType);
17991
- if (handler) {
17992
- const node = handler.serialize(instance);
17993
- this.instance.updateNode(node);
17994
- this.instance.moveNode(node, __inditextech_weave_types.WEAVE_NODE_POSITION.FRONT);
18091
+ bringToFront(instances) {
18092
+ const nodes = Array.isArray(instances) ? instances : [instances];
18093
+ const nodesAscending = nodes.toSorted((a, b) => a.zIndex() - b.zIndex());
18094
+ for (const node of nodesAscending) {
18095
+ node.moveToTop();
18096
+ const handler = this.instance.getNodeHandler(node.getAttrs().nodeType);
18097
+ if (handler) {
18098
+ const nodeState = handler.serialize(node);
18099
+ this.instance.updateNode(nodeState);
18100
+ this.instance.moveNode(nodeState, __inditextech_weave_types.WEAVE_NODE_POSITION.FRONT);
18101
+ }
17995
18102
  }
17996
18103
  }
17997
18104
  };
@@ -18063,7 +18170,7 @@ var WeaveStateManager = class {
18063
18170
  };
18064
18171
  return this.findNodeById(state, nodeKey);
18065
18172
  }
18066
- addNode(node, parentId = "mainLayer", index = void 0, doRender = true) {
18173
+ addNode(node, parentId = "mainLayer", index = void 0) {
18067
18174
  const userName = this.instance.getStore().getUser().name;
18068
18175
  this.instance.getStore().getDocument().transact(() => {
18069
18176
  const state = this.instance.getStore().getState();
@@ -18071,8 +18178,7 @@ var WeaveStateManager = class {
18071
18178
  const msg = `State is empty, cannot add the node`;
18072
18179
  this.logger.warn({
18073
18180
  node,
18074
- parentId,
18075
- doRender
18181
+ parentId
18076
18182
  }, msg);
18077
18183
  return;
18078
18184
  }
@@ -18081,8 +18187,7 @@ var WeaveStateManager = class {
18081
18187
  const msg = `Node with key [${node.key}] already exists, cannot add it`;
18082
18188
  this.logger.warn({
18083
18189
  node,
18084
- parentId,
18085
- doRender
18190
+ parentId
18086
18191
  }, msg);
18087
18192
  return;
18088
18193
  }
@@ -18091,8 +18196,7 @@ var WeaveStateManager = class {
18091
18196
  const msg = `Parent container with key [${node.key}] doesn't exists, cannot add it`;
18092
18197
  this.logger.warn({
18093
18198
  node,
18094
- parentId,
18095
- doRender
18199
+ parentId
18096
18200
  }, msg);
18097
18201
  return;
18098
18202
  }
@@ -18122,28 +18226,21 @@ var WeaveStateManager = class {
18122
18226
  parent.props.children.push(finalNode);
18123
18227
  }
18124
18228
  this.instance.emitEvent("onNodeAdded", node);
18125
- if (doRender) this.instance.render();
18126
18229
  }, userName);
18127
18230
  }
18128
- updateNode(node, doRender = true) {
18231
+ updateNode(node) {
18129
18232
  const userName = this.instance.getStore().getUser().name;
18130
18233
  this.instance.getStore().getDocument().transact(() => {
18131
18234
  const state = this.instance.getStore().getState();
18132
18235
  if ((0, import_lodash.isEmpty)(state.weave)) {
18133
18236
  const msg = `State is empty, cannot update the node`;
18134
- this.logger.warn({
18135
- node,
18136
- doRender
18137
- }, msg);
18237
+ this.logger.warn({ node }, msg);
18138
18238
  return;
18139
18239
  }
18140
18240
  const { node: nodeState } = this.findNodeById(state.weave, node.key);
18141
18241
  if (!nodeState) {
18142
18242
  const msg = `Node with key [${node.key}] doesn't exists, cannot update it`;
18143
- this.logger.warn({
18144
- node,
18145
- doRender
18146
- }, msg);
18243
+ this.logger.warn({ node }, msg);
18147
18244
  return;
18148
18245
  }
18149
18246
  const nodeNew = JSON.parse(JSON.stringify({
@@ -18152,28 +18249,21 @@ var WeaveStateManager = class {
18152
18249
  }));
18153
18250
  nodeState.props = { ...nodeNew };
18154
18251
  this.instance.emitEvent("onNodeUpdated", node);
18155
- if (doRender) this.instance.render();
18156
18252
  }, userName);
18157
18253
  }
18158
- removeNode(node, doRender = true) {
18254
+ removeNode(node) {
18159
18255
  const userName = this.instance.getStore().getUser().name;
18160
18256
  this.instance.getStore().getDocument().transact(() => {
18161
18257
  const state = this.instance.getStore().getState();
18162
18258
  if ((0, import_lodash.isEmpty)(state.weave)) {
18163
18259
  const msg = `State is empty, cannot update the node`;
18164
- this.logger.warn({
18165
- node,
18166
- doRender
18167
- }, msg);
18260
+ this.logger.warn({ node }, msg);
18168
18261
  return;
18169
18262
  }
18170
18263
  const { node: nodeState, parent: parentState } = this.findNodeById(state.weave, node.key);
18171
18264
  if (!nodeState) {
18172
18265
  const msg = `Node with key [${node.key}] doesn't exists, cannot remove it`;
18173
- this.logger.warn({
18174
- node,
18175
- doRender
18176
- }, msg);
18266
+ this.logger.warn({ node }, msg);
18177
18267
  return;
18178
18268
  }
18179
18269
  if (parentState) {
@@ -18182,32 +18272,24 @@ var WeaveStateManager = class {
18182
18272
  parentState.props.children = filteredChildren;
18183
18273
  }
18184
18274
  this.instance.emitEvent("onNodeRemoved", node);
18185
- if (doRender) this.instance.render();
18186
18275
  }, userName);
18187
18276
  }
18188
- removeNodes(nodes, doRender = true) {
18189
- for (const node of nodes) this.removeNode(node, false);
18190
- if (doRender) this.instance.render();
18277
+ removeNodes(nodes) {
18278
+ for (const node of nodes) this.removeNode(node);
18191
18279
  }
18192
- moveNode(node, position, doRender = true) {
18280
+ moveNode(node, position) {
18193
18281
  const userName = this.instance.getStore().getUser().name;
18194
18282
  this.instance.getStore().getDocument().transact(() => {
18195
18283
  const state = this.instance.getStore().getState();
18196
18284
  if ((0, import_lodash.isEmpty)(state.weave)) {
18197
18285
  const msg = `State is empty, cannot update the node`;
18198
- this.logger.warn({
18199
- node,
18200
- doRender
18201
- }, msg);
18286
+ this.logger.warn({ node }, msg);
18202
18287
  return;
18203
18288
  }
18204
18289
  const { node: nodeState, parent: nodeParent } = this.findNodeById(state.weave, node.key);
18205
18290
  if (!nodeState) {
18206
18291
  const msg = `Node with key [${node.key}] doesn't exists, cannot update it`;
18207
- this.logger.warn({
18208
- node,
18209
- doRender
18210
- }, msg);
18292
+ this.logger.warn({ node }, msg);
18211
18293
  return;
18212
18294
  }
18213
18295
  if (nodeParent) {
@@ -18231,7 +18313,6 @@ var WeaveStateManager = class {
18231
18313
  });
18232
18314
  if (!nodeParent.props.children) nodeParent.props.children = [];
18233
18315
  nodeParent.props.children = nodeParentNewChildren;
18234
- if (doRender) this.instance.render();
18235
18316
  }
18236
18317
  }, userName);
18237
18318
  }
@@ -18317,7 +18398,7 @@ var WeaveRegisterManager = class {
18317
18398
 
18318
18399
  //#endregion
18319
18400
  //#region package.json
18320
- var version = "0.37.0";
18401
+ var version = "0.38.0";
18321
18402
 
18322
18403
  //#endregion
18323
18404
  //#region src/managers/setup.ts
@@ -18859,31 +18940,27 @@ var Weave = class {
18859
18940
  getNode(nodeKey) {
18860
18941
  return this.stateManager.getNode(nodeKey);
18861
18942
  }
18862
- addNode(node, parentId = "mainLayer", index = void 0, doRender = true) {
18863
- this.stateManager.addNode(node, parentId, index, doRender);
18943
+ addNode(node, parentId = "mainLayer", index = void 0) {
18944
+ this.stateManager.addNode(node, parentId, index);
18864
18945
  }
18865
- updateNode(node, doRender = true) {
18866
- this.stateManager.updateNode(node, doRender);
18946
+ updateNode(node) {
18947
+ this.stateManager.updateNode(node);
18867
18948
  }
18868
- updateNodes(nodes, doRender = true) {
18869
- for (const node of nodes) this.updateNode(node, false);
18870
- const selectionPlugin = this.getPlugin("nodesSelection");
18871
- if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
18872
- if (doRender) this.render();
18949
+ updateNodes(nodes) {
18950
+ for (const node of nodes) this.updateNode(node);
18873
18951
  }
18874
- removeNode(node, doRender = true) {
18875
- this.stateManager.removeNode(node, doRender);
18952
+ removeNode(node) {
18953
+ this.stateManager.removeNode(node);
18876
18954
  const selectionPlugin = this.getPlugin("nodesSelection");
18877
18955
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
18878
18956
  }
18879
- removeNodes(nodes, doRender = true) {
18880
- for (const node of nodes) this.removeNode(node, false);
18957
+ removeNodes(nodes) {
18958
+ for (const node of nodes) this.removeNode(node);
18881
18959
  const selectionPlugin = this.getPlugin("nodesSelection");
18882
18960
  if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
18883
- if (doRender) this.render();
18884
18961
  }
18885
- moveNode(node, position, doRender = true) {
18886
- this.stateManager.moveNode(node, position, doRender);
18962
+ moveNode(node, position) {
18963
+ this.stateManager.moveNode(node, position);
18887
18964
  }
18888
18965
  getElementsTree() {
18889
18966
  return this.stateManager.getElementsTree();
@@ -18897,11 +18974,11 @@ var Weave = class {
18897
18974
  moveDown(node) {
18898
18975
  this.zIndexManager.moveDown(node);
18899
18976
  }
18900
- sendToBack(node) {
18901
- this.zIndexManager.sendToBack(node);
18977
+ sendToBack(nodes) {
18978
+ this.zIndexManager.sendToBack(nodes);
18902
18979
  }
18903
- bringToFront(node) {
18904
- this.zIndexManager.bringToFront(node);
18980
+ bringToFront(nodes) {
18981
+ this.zIndexManager.bringToFront(nodes);
18905
18982
  }
18906
18983
  group(nodes) {
18907
18984
  this.groupsManager.group(nodes);
@@ -19660,7 +19737,7 @@ var WeaveTextNode = class extends WeaveNode {
19660
19737
  }
19661
19738
  const measures = textNode.measureSize(textNode.text());
19662
19739
  const px = 0 * stage.scaleX();
19663
- const py = 2 * (measures.fontBoundingBoxAscent - measures.hangingBaseline - measures.fontBoundingBoxDescent) * stage.scaleY();
19740
+ const py = measures.actualBoundingBoxDescent * stage.scaleY();
19664
19741
  let transform = "";
19665
19742
  transform += "translateX(" + px + "px)";
19666
19743
  transform += "translateY(" + py + "px)";
@@ -21046,7 +21123,28 @@ var WeaveFrameNode = class extends WeaveNode {
21046
21123
  width: props.frameWidth,
21047
21124
  height: props.frameHeight,
21048
21125
  fill: "transparent",
21049
- draggable: false
21126
+ draggable: true
21127
+ });
21128
+ selectorArea.on("dragmove", () => {
21129
+ if (this.isSelecting() && this.isNodeSelected(selectorArea)) {
21130
+ clearContainerTargets(this.instance);
21131
+ frame.setAbsolutePosition(selectorArea.getAbsolutePosition());
21132
+ selectorArea.setAttrs({
21133
+ x: 0,
21134
+ y: 0
21135
+ });
21136
+ }
21137
+ });
21138
+ selectorArea.on("dragend", () => {
21139
+ if (this.isSelecting() && this.isNodeSelected(selectorArea)) {
21140
+ clearContainerTargets(this.instance);
21141
+ frame.setAbsolutePosition(selectorArea.getAbsolutePosition());
21142
+ selectorArea.setAttrs({
21143
+ x: 0,
21144
+ y: 0
21145
+ });
21146
+ this.instance.updateNode(this.serialize(selectorArea));
21147
+ }
21050
21148
  });
21051
21149
  selectorArea.getTransformerProperties = () => {
21052
21150
  return this.config.transform;
@@ -21057,7 +21155,6 @@ var WeaveFrameNode = class extends WeaveNode {
21057
21155
  x: 0,
21058
21156
  y: 0
21059
21157
  });
21060
- this.instance.updateNode(this.serialize(selectorArea));
21061
21158
  };
21062
21159
  const updateFrame = (e) => {
21063
21160
  const selectorArea$1 = e.target;
@@ -21128,17 +21225,18 @@ var WeaveFrameNode = class extends WeaveNode {
21128
21225
  width: props.frameWidth - borderWidth * 2,
21129
21226
  height: props.frameHeight - borderWidth * 2,
21130
21227
  strokeScaleEnabled: true,
21228
+ clipFunc: (ctx) => {
21229
+ const width = (frameInternal.width() + borderWidth) * frameInternal.scaleX();
21230
+ const height = (frameInternal.height() + borderWidth) * frameInternal.scaleY();
21231
+ ctx.rect(-(borderWidth / 2) * frameInternal.scaleX(), -(borderWidth / 2) * frameInternal.scaleY(), width, height);
21232
+ },
21131
21233
  draggable: false
21132
21234
  });
21133
- frameInternal.clipFunc((ctx) => {
21134
- const width = (frameInternal.width() + borderWidth) * frameInternal.scaleX();
21135
- const height = (frameInternal.height() + borderWidth) * frameInternal.scaleY();
21136
- ctx.rect(-(borderWidth / 2) * frameInternal.scaleX(), -(borderWidth / 2) * frameInternal.scaleY(), width, height);
21137
- });
21138
21235
  frameInternalGroup.add(frameInternal);
21139
21236
  this.setupDefaultNodeEvents(frame);
21140
- frame.on("dragmove", () => {});
21141
- frame.on("dragend", () => {});
21237
+ frame.off("dragstart");
21238
+ frame.off("dragmove");
21239
+ frame.off("dragend");
21142
21240
  frame.on(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, () => {
21143
21241
  background.setAttrs({
21144
21242
  stroke: onTargetLeaveBorderColor,
@@ -21246,10 +21344,125 @@ var WeaveFrameNode = class extends WeaveNode {
21246
21344
  }
21247
21345
  };
21248
21346
 
21347
+ //#endregion
21348
+ //#region src/nodes/stroke/constants.ts
21349
+ const WEAVE_STROKE_NODE_TYPE = "stroke";
21350
+
21351
+ //#endregion
21352
+ //#region src/nodes/stroke/stroke.ts
21353
+ var WeaveStrokeNode = class extends WeaveNode {
21354
+ nodeType = WEAVE_STROKE_NODE_TYPE;
21355
+ constructor(params) {
21356
+ super();
21357
+ const { config } = params ?? {};
21358
+ this.config = { transform: {
21359
+ ...__inditextech_weave_types.WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
21360
+ ...config?.transform
21361
+ } };
21362
+ }
21363
+ drawStroke(strokeElements, context, shape) {
21364
+ context.strokeStyle = shape.getAttrs().stroke ?? "black";
21365
+ context.lineCap = "round";
21366
+ context.lineJoin = "round";
21367
+ const l = strokeElements.length - 1;
21368
+ if (strokeElements.length >= 3) {
21369
+ const xc = (strokeElements[l].x + strokeElements[l - 1].x) / 2;
21370
+ const yc = (strokeElements[l].y + strokeElements[l - 1].y) / 2;
21371
+ context.lineWidth = strokeElements[l - 1].lineWidth;
21372
+ context.quadraticCurveTo(strokeElements[l - 1].x, strokeElements[l - 1].y, xc, yc);
21373
+ context.stroke();
21374
+ context.beginPath();
21375
+ context.moveTo(xc, yc);
21376
+ } else {
21377
+ const point = strokeElements[l];
21378
+ context.lineWidth = point.lineWidth;
21379
+ context.beginPath();
21380
+ context.moveTo(point.x, point.y);
21381
+ context.stroke();
21382
+ }
21383
+ }
21384
+ onRender(props) {
21385
+ const stroke = new konva.default.Shape({
21386
+ ...props,
21387
+ name: "node",
21388
+ sceneFunc: (context, shape) => {
21389
+ context.beginPath();
21390
+ const strokeElements = shape.getAttrs().strokeElements;
21391
+ const strokePath = [];
21392
+ strokeElements.forEach((point) => {
21393
+ strokePath.push(point);
21394
+ this.drawStroke(strokePath, context, shape);
21395
+ });
21396
+ },
21397
+ hitFunc: (context, shape) => {
21398
+ context.beginPath();
21399
+ context.rect(0, 0, shape.width(), shape.height());
21400
+ context.closePath();
21401
+ context.fillStrokeShape(shape);
21402
+ }
21403
+ });
21404
+ this.setupDefaultNodeAugmentation(stroke);
21405
+ stroke.getTransformerProperties = () => {
21406
+ return this.config.transform;
21407
+ };
21408
+ this.setupDefaultNodeEvents(stroke);
21409
+ return stroke;
21410
+ }
21411
+ onUpdate(nodeInstance, nextProps) {
21412
+ nodeInstance.setAttrs({ ...nextProps });
21413
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
21414
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
21415
+ }
21416
+ scaleReset(node) {
21417
+ const strokeNode = node;
21418
+ const oldPoints = [...strokeNode.getAttrs().strokeElements];
21419
+ const newPoints = [];
21420
+ for (const actPoint of oldPoints) {
21421
+ const point = {
21422
+ ...actPoint,
21423
+ x: actPoint.x * strokeNode.scaleX(),
21424
+ y: actPoint.y * strokeNode.scaleY()
21425
+ };
21426
+ newPoints.push(point);
21427
+ }
21428
+ strokeNode.setAttrs({ strokeElements: newPoints });
21429
+ node.width(Math.max(5, node.width() * node.scaleX()));
21430
+ node.height(Math.max(5, node.height() * node.scaleY()));
21431
+ node.scaleX(1);
21432
+ node.scaleY(1);
21433
+ }
21434
+ serialize(instance) {
21435
+ const attrs = instance.getAttrs();
21436
+ const cleanedAttrs = { ...attrs };
21437
+ delete cleanedAttrs.draggable;
21438
+ delete cleanedAttrs.sceneFunc;
21439
+ delete cleanedAttrs.hitFunc;
21440
+ return {
21441
+ key: attrs.id ?? "",
21442
+ type: attrs.nodeType,
21443
+ props: {
21444
+ ...cleanedAttrs,
21445
+ id: attrs.id ?? "",
21446
+ nodeType: attrs.nodeType,
21447
+ children: []
21448
+ }
21449
+ };
21450
+ }
21451
+ };
21452
+
21249
21453
  //#endregion
21250
21454
  //#region src/plugins/stage-zoom/constants.ts
21455
+ const WEAVE_STAGE_ZOOM_TYPE = {
21456
+ MOUSE_WHEEL: "mouseWheel",
21457
+ PINCH_ZOOM: "pinchZoom"
21458
+ };
21251
21459
  const WEAVE_STAGE_ZOOM_KEY = "stageZoom";
21252
21460
  const WEAVE_STAGE_ZOOM_DEFAULT_CONFIG = {
21461
+ zoomInertia: {
21462
+ friction: .9,
21463
+ mouseWheelStep: .01,
21464
+ trackpadStep: .005
21465
+ },
21253
21466
  zoomSteps: [
21254
21467
  .01,
21255
21468
  .05,
@@ -22953,15 +23166,23 @@ var import_hammer = __toESM(require_hammer(), 1);
22953
23166
  var WeaveStageZoomPlugin = class extends WeavePlugin {
22954
23167
  getLayerName = void 0;
22955
23168
  initLayer = void 0;
23169
+ zooming = false;
23170
+ isTrackpad = false;
23171
+ zoomVelocity = 0;
23172
+ zoomInertiaType = WEAVE_STAGE_ZOOM_TYPE.MOUSE_WHEEL;
23173
+ initialScale = 0;
23174
+ lastTime = 0;
23175
+ center = {
23176
+ x: 0,
23177
+ y: 0
23178
+ };
22956
23179
  defaultStep = 3;
22957
23180
  constructor(params) {
22958
23181
  super();
22959
23182
  const { config } = params ?? {};
22960
- this.config = {
22961
- ...WEAVE_STAGE_ZOOM_DEFAULT_CONFIG,
22962
- ...config
22963
- };
23183
+ this.config = (0, import_lodash.merge)(WEAVE_STAGE_ZOOM_DEFAULT_CONFIG, config);
22964
23184
  if (!this.config.zoomSteps.includes(this.config.defaultZoom)) throw new Error(`Default zoom ${this.config.defaultZoom} is not in zoom steps`);
23185
+ this.isTrackpad = false;
22965
23186
  this.isCtrlOrMetaPressed = false;
22966
23187
  this.updatedMinimumZoom = false;
22967
23188
  this.actualStep = this.config.zoomSteps.findIndex((step) => step === this.config.defaultZoom);
@@ -23214,38 +23435,68 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23214
23435
  threshold: 0,
23215
23436
  pointers: 2
23216
23437
  }));
23217
- let initialScale = null;
23218
- let center = {
23219
- x: 0,
23220
- y: 0
23221
- };
23222
- sc.on("pinchstart", (ev) => {
23223
- initialScale = stage.scaleX();
23224
- center = {
23225
- x: ev.center.x,
23226
- y: ev.center.y
23438
+ sc.on("pinchstart", (e) => {
23439
+ this.initialScale = this.instance.getStage().scaleX();
23440
+ this.center = {
23441
+ x: e.center.x,
23442
+ y: e.center.y
23227
23443
  };
23444
+ this.lastTime = performance.now();
23228
23445
  });
23229
- sc.on("pinchmove", (ev) => {
23230
- if (!initialScale) return;
23231
- const newScale = initialScale * ev.scale;
23232
- this.setZoom(newScale, false, center);
23446
+ sc.on("pinchmove", (e) => {
23447
+ const now = performance.now();
23448
+ const newScale = Math.max(this.config.zoomSteps[0], Math.min(this.config.zoomSteps[this.config.zoomSteps.length - 1], this.initialScale * e.scale));
23449
+ this.setZoom(newScale, false, this.center);
23450
+ const dt = now - this.lastTime;
23451
+ this.zoomVelocity = (newScale - 1) / (dt * 16.6);
23452
+ this.lastTime = now;
23453
+ });
23454
+ sc.on("pinchend", () => {
23455
+ this.zooming = true;
23456
+ this.zoomInertiaType = WEAVE_STAGE_ZOOM_TYPE.PINCH_ZOOM;
23457
+ requestAnimationFrame(this.zoomTick.bind(this));
23233
23458
  });
23234
23459
  const handleWheel = (e) => {
23235
23460
  e.evt.preventDefault();
23236
23461
  const stage$1 = this.instance.getStage();
23237
23462
  const performZoom = this.isCtrlOrMetaPressed || !this.isCtrlOrMetaPressed && e.evt.ctrlKey && e.evt.deltaMode === 0;
23238
23463
  if (!this.enabled || !stage$1.isFocused() || !performZoom) return;
23239
- const oldScale = stage$1.scaleX();
23240
- const pointer = stage$1.getPointerPosition();
23241
- if (!pointer) return;
23242
- const scaleBy = 1.025;
23243
- const direction = e.evt.deltaY > 0 ? 1 : -1;
23244
- const newScale = direction > 0 ? oldScale / scaleBy : oldScale * scaleBy;
23245
- this.setZoom(newScale, false, pointer);
23464
+ const delta = e.evt.deltaY > 0 ? 1 : -1;
23465
+ this.zoomVelocity += delta;
23466
+ this.isTrackpad = Math.abs(e.evt.deltaY) < 15 && e.evt.deltaMode === 0;
23467
+ if (!this.zooming) {
23468
+ this.zooming = true;
23469
+ this.zoomInertiaType = WEAVE_STAGE_ZOOM_TYPE.MOUSE_WHEEL;
23470
+ requestAnimationFrame(this.zoomTick.bind(this));
23471
+ }
23246
23472
  };
23247
23473
  stage.on("wheel", handleWheel);
23248
23474
  }
23475
+ getInertiaScale() {
23476
+ const stage = this.instance.getStage();
23477
+ let step = 1;
23478
+ if (this.zoomInertiaType === WEAVE_STAGE_ZOOM_TYPE.MOUSE_WHEEL && !this.isTrackpad) step = this.config.zoomInertia.mouseWheelStep;
23479
+ if (this.zoomInertiaType === WEAVE_STAGE_ZOOM_TYPE.MOUSE_WHEEL && this.isTrackpad) step = this.config.zoomInertia.trackpadStep;
23480
+ const oldScale = stage.scaleX();
23481
+ let newScale = oldScale * (1 - this.zoomVelocity * step);
23482
+ newScale = Math.max(this.config.zoomSteps[0], Math.min(this.config.zoomSteps[this.config.zoomSteps.length - 1], newScale));
23483
+ return newScale;
23484
+ }
23485
+ zoomTick() {
23486
+ if (Math.abs(this.zoomVelocity) < .001) {
23487
+ this.zooming = false;
23488
+ return;
23489
+ }
23490
+ let pointer = this.center;
23491
+ if (this.zoomInertiaType === WEAVE_STAGE_ZOOM_TYPE.MOUSE_WHEEL) {
23492
+ const stage = this.instance.getStage();
23493
+ pointer = stage.getPointerPosition();
23494
+ }
23495
+ if (!pointer) return;
23496
+ this.setZoom(this.getInertiaScale(), false, pointer);
23497
+ this.zoomVelocity *= this.config.zoomInertia.friction;
23498
+ requestAnimationFrame(this.zoomTick.bind(this));
23499
+ }
23249
23500
  };
23250
23501
 
23251
23502
  //#endregion
@@ -23570,7 +23821,10 @@ var WeaveEraserToolAction = class extends WeaveAction {
23570
23821
  stage.container().focus();
23571
23822
  this.cancelAction = cancelAction;
23572
23823
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
23573
- if (selectionPlugin) selectionPlugin.disable();
23824
+ if (selectionPlugin) {
23825
+ selectionPlugin.setSelectedNodes([]);
23826
+ selectionPlugin.disable();
23827
+ }
23574
23828
  this.setEraser();
23575
23829
  }
23576
23830
  cleanup() {
@@ -23638,19 +23892,23 @@ var WeaveRectangleToolAction = class extends WeaveAction {
23638
23892
  return;
23639
23893
  }
23640
23894
  });
23641
- stage.on("pointerdown", () => {
23895
+ stage.on("pointerdown", (e) => {
23896
+ this.setTapStart(e);
23642
23897
  if (this.state === RECTANGLE_TOOL_STATE.ADDING) {
23643
23898
  this.creating = true;
23644
23899
  this.handleAdding();
23645
23900
  }
23646
23901
  });
23647
- stage.on("pointermove", () => {
23902
+ stage.on("pointermove", (e) => {
23903
+ if (!this.isPressed(e)) return;
23648
23904
  if (this.state === RECTANGLE_TOOL_STATE.DEFINING_SIZE) {
23649
23905
  this.moved = true;
23650
23906
  this.handleMovement();
23651
23907
  }
23652
23908
  });
23653
- stage.on("pointerup", () => {
23909
+ stage.on("pointerup", (e) => {
23910
+ const isTap = this.isTap(e);
23911
+ if (isTap) this.moved = false;
23654
23912
  if (this.state === RECTANGLE_TOOL_STATE.DEFINING_SIZE) {
23655
23913
  this.creating = false;
23656
23914
  this.handleSettingSize();
@@ -23813,19 +24071,23 @@ var WeaveEllipseToolAction = class extends WeaveAction {
23813
24071
  return;
23814
24072
  }
23815
24073
  });
23816
- stage.on("pointerdown", () => {
24074
+ stage.on("pointerdown", (e) => {
24075
+ this.setTapStart(e);
23817
24076
  if (this.state === ELLIPSE_TOOL_STATE.ADDING) {
23818
24077
  this.creating = true;
23819
24078
  this.handleAdding();
23820
24079
  }
23821
24080
  });
23822
- stage.on("pointermove", () => {
24081
+ stage.on("pointermove", (e) => {
24082
+ if (!this.isPressed(e)) return;
23823
24083
  if (this.state === ELLIPSE_TOOL_STATE.DEFINING_SIZE) {
23824
24084
  this.moved = true;
23825
24085
  this.handleMovement();
23826
24086
  }
23827
24087
  });
23828
- stage.on("pointerup", () => {
24088
+ stage.on("pointerup", (e) => {
24089
+ const isTap = this.isTap(e);
24090
+ if (isTap) this.moved = false;
23829
24091
  if (this.state === ELLIPSE_TOOL_STATE.DEFINING_SIZE) {
23830
24092
  this.creating = false;
23831
24093
  this.handleSettingSize();
@@ -24195,11 +24457,13 @@ const BRUSH_TOOL_STATE = {
24195
24457
  //#region src/actions/brush-tool/brush-tool.ts
24196
24458
  var WeaveBrushToolAction = class extends WeaveAction {
24197
24459
  initialized = false;
24460
+ lineWidth = 0;
24198
24461
  onPropsChange = void 0;
24199
24462
  onInit = void 0;
24200
24463
  constructor() {
24201
24464
  super();
24202
24465
  this.initialized = false;
24466
+ this.lineWidth = 0;
24203
24467
  this.state = BRUSH_TOOL_STATE.INACTIVE;
24204
24468
  this.strokeId = null;
24205
24469
  this.clickPoint = null;
@@ -24217,6 +24481,11 @@ var WeaveBrushToolAction = class extends WeaveAction {
24217
24481
  opacity: 1
24218
24482
  };
24219
24483
  }
24484
+ getPointPressure(e) {
24485
+ let pressure = 1;
24486
+ if (e.evt instanceof PointerEvent && e.evt.pointerType === "pen") pressure = e.evt.pressure;
24487
+ return pressure;
24488
+ }
24220
24489
  setupEvents() {
24221
24490
  const stage = this.instance.getStage();
24222
24491
  stage.container().tabIndex = 1;
@@ -24231,75 +24500,132 @@ var WeaveBrushToolAction = class extends WeaveAction {
24231
24500
  return;
24232
24501
  }
24233
24502
  });
24234
- stage.on("pointerdown", (e) => {
24503
+ const handlePointerDown = (e) => {
24235
24504
  if (this.state !== BRUSH_TOOL_STATE.IDLE) return;
24505
+ const pointPressure = this.getPointPressure(e);
24506
+ this.lineWidth = Math.log(pointPressure + 1) * this.props.strokeWidth;
24236
24507
  this.handleStartStroke();
24237
24508
  e.evt.stopPropagation();
24238
- });
24239
- stage.on("pointermove", (e) => {
24509
+ };
24510
+ stage.on("pointerdown touchstart", handlePointerDown);
24511
+ const handlePointerMove = (e) => {
24240
24512
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
24513
+ const pointPressure = this.getPointPressure(e);
24514
+ this.lineWidth = Math.log(pointPressure + 1) * this.props.strokeWidth * .2 + this.lineWidth * .8;
24241
24515
  this.handleMovement();
24242
24516
  e.evt.stopPropagation();
24243
- });
24244
- stage.on("pointerup", (e) => {
24517
+ };
24518
+ stage.on("pointermove touchmove", handlePointerMove);
24519
+ const handlePointerUp = (e) => {
24245
24520
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
24246
24521
  this.handleEndStroke();
24247
24522
  e.evt.stopPropagation();
24248
- });
24523
+ };
24524
+ stage.on("pointerup touchend", handlePointerUp);
24249
24525
  this.initialized = true;
24250
24526
  }
24251
24527
  setState(state) {
24252
24528
  this.state = state;
24253
24529
  }
24530
+ getBoundingBox(strokeElements) {
24531
+ if (strokeElements.length === 0) return {
24532
+ x: 0,
24533
+ y: 0,
24534
+ width: 0,
24535
+ height: 0
24536
+ };
24537
+ let minX = strokeElements[0].x;
24538
+ let maxX = strokeElements[0].x;
24539
+ let minY = strokeElements[0].y;
24540
+ let maxY = strokeElements[0].y;
24541
+ strokeElements.forEach((point) => {
24542
+ minX = Math.min(minX, point.x);
24543
+ maxX = Math.max(maxX, point.x);
24544
+ minY = Math.min(minY, point.y);
24545
+ maxY = Math.max(maxY, point.y);
24546
+ });
24547
+ return {
24548
+ x: minX,
24549
+ y: minY,
24550
+ width: maxX - minX,
24551
+ height: maxY - minY
24552
+ };
24553
+ }
24254
24554
  handleStartStroke() {
24255
24555
  const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
24256
24556
  this.clickPoint = mousePoint;
24257
24557
  this.container = container;
24258
24558
  this.measureContainer = measureContainer;
24259
24559
  this.strokeId = v4_default();
24260
- const nodeHandler = this.instance.getNodeHandler("line");
24560
+ const nodeHandler = this.instance.getNodeHandler("stroke");
24261
24561
  if (nodeHandler) {
24262
24562
  const node = nodeHandler.create(this.strokeId, {
24263
24563
  ...this.props,
24264
24564
  strokeScaleEnabled: true,
24265
- x: this.clickPoint?.x ?? 0,
24266
- y: this.clickPoint?.y ?? 0,
24267
- points: [0, 0]
24565
+ x: 0,
24566
+ y: 0,
24567
+ width: 0,
24568
+ height: 0,
24569
+ strokeElements: []
24268
24570
  });
24269
- this.instance.addNode(node, this.container?.getAttrs().id);
24571
+ const nodeInstance = nodeHandler.onRender(node.props);
24572
+ this.container?.add(nodeInstance);
24270
24573
  }
24271
24574
  this.setState(BRUSH_TOOL_STATE.DEFINE_STROKE);
24272
24575
  }
24576
+ handleMovement() {
24577
+ if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
24578
+ const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
24579
+ if (this.measureContainer && tempStroke) {
24580
+ const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
24581
+ const newStrokeElements = [...tempStroke.getAttrs().strokeElements];
24582
+ newStrokeElements.push({
24583
+ x: mousePoint.x - tempStroke.x(),
24584
+ y: mousePoint.y - tempStroke.y(),
24585
+ lineWidth: this.lineWidth
24586
+ });
24587
+ const box = this.getBoundingBox(newStrokeElements);
24588
+ tempStroke.setAttrs({
24589
+ width: box.width,
24590
+ height: box.height,
24591
+ x: 0,
24592
+ y: 0,
24593
+ strokeElements: newStrokeElements
24594
+ });
24595
+ const nodeHandler = this.instance.getNodeHandler("stroke");
24596
+ if (nodeHandler) nodeHandler.onUpdate(tempStroke, tempStroke.getAttrs());
24597
+ }
24598
+ }
24273
24599
  handleEndStroke() {
24274
24600
  const stage = this.instance.getStage();
24275
24601
  const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
24276
24602
  if (tempStroke) {
24277
- const nodeHandler = this.instance.getNodeHandler("line");
24278
- tempStroke.setAttrs({
24279
- ...this.props,
24280
- hitStrokeWidth: 10
24281
- });
24282
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(tempStroke));
24603
+ const nodeHandler = this.instance.getNodeHandler("stroke");
24604
+ if (nodeHandler) {
24605
+ const box = this.getBoundingBox(tempStroke.getAttrs().strokeElements);
24606
+ let newStrokeElements = [...tempStroke.getAttrs().strokeElements];
24607
+ newStrokeElements = newStrokeElements.map((point) => ({
24608
+ ...point,
24609
+ x: point.x - box.x,
24610
+ y: point.y - box.y
24611
+ }));
24612
+ tempStroke.setAttrs({
24613
+ width: box.width,
24614
+ height: box.height,
24615
+ x: box.x,
24616
+ y: box.y,
24617
+ strokeElements: newStrokeElements
24618
+ });
24619
+ const realNode = this.instance.getStage().findOne(`#${tempStroke.getAttrs().id}`);
24620
+ if (realNode) realNode.destroy();
24621
+ this.instance.addNode(nodeHandler.serialize(tempStroke), this.container?.getAttrs().id);
24622
+ }
24283
24623
  this.clickPoint = null;
24284
24624
  stage.container().tabIndex = 1;
24285
24625
  stage.container().focus();
24286
24626
  this.setState(BRUSH_TOOL_STATE.IDLE);
24287
24627
  }
24288
24628
  }
24289
- handleMovement() {
24290
- if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
24291
- const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
24292
- if (this.measureContainer && tempStroke) {
24293
- const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
24294
- tempStroke.points([
24295
- ...tempStroke.points(),
24296
- mousePoint.x - tempStroke.x(),
24297
- mousePoint.y - tempStroke.y()
24298
- ]);
24299
- const nodeHandler = this.instance.getNodeHandler("line");
24300
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(tempStroke));
24301
- }
24302
- }
24303
24629
  trigger(cancel) {
24304
24630
  if (!this.instance) throw new Error("Instance not defined");
24305
24631
  if (!this.initialized) this.setupEvents();
@@ -24493,19 +24819,23 @@ var WeaveStarToolAction = class extends WeaveAction {
24493
24819
  return;
24494
24820
  }
24495
24821
  });
24496
- stage.on("pointerdown", () => {
24822
+ stage.on("pointerdown", (e) => {
24823
+ this.setTapStart(e);
24497
24824
  if (this.state === STAR_TOOL_STATE.ADDING) {
24498
24825
  this.creating = true;
24499
24826
  this.handleAdding();
24500
24827
  }
24501
24828
  });
24502
- stage.on("pointermove", () => {
24829
+ stage.on("pointermove", (e) => {
24830
+ if (!this.isPressed(e)) return;
24503
24831
  if (this.state === STAR_TOOL_STATE.DEFINING_SIZE) {
24504
24832
  this.moved = true;
24505
24833
  this.handleMovement();
24506
24834
  }
24507
24835
  });
24508
- stage.on("pointerup", () => {
24836
+ stage.on("pointerup", (e) => {
24837
+ const isTap = this.isTap(e);
24838
+ if (isTap) this.moved = false;
24509
24839
  if (this.state === STAR_TOOL_STATE.DEFINING_SIZE) {
24510
24840
  this.creating = false;
24511
24841
  this.handleSettingSize();
@@ -24931,19 +25261,23 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
24931
25261
  return;
24932
25262
  }
24933
25263
  });
24934
- stage.on("pointerdown", () => {
25264
+ stage.on("pointerdown", (e) => {
25265
+ this.setTapStart(e);
24935
25266
  if (this.state === REGULAR_POLYGON_TOOL_STATE.ADDING) {
24936
25267
  this.creating = true;
24937
25268
  this.handleAdding();
24938
25269
  }
24939
25270
  });
24940
- stage.on("pointermove", () => {
25271
+ stage.on("pointermove", (e) => {
25272
+ if (!this.isPressed(e)) return;
24941
25273
  if (this.state === REGULAR_POLYGON_TOOL_STATE.DEFINING_SIZE) {
24942
25274
  this.moved = true;
24943
25275
  this.handleMovement();
24944
25276
  }
24945
25277
  });
24946
- stage.on("pointerup", () => {
25278
+ stage.on("pointerup", (e) => {
25279
+ const isTap = this.isTap(e);
25280
+ if (isTap) this.moved = false;
24947
25281
  if (this.state === REGULAR_POLYGON_TOOL_STATE.DEFINING_SIZE) {
24948
25282
  this.creating = false;
24949
25283
  this.handleSettingSize();
@@ -26360,6 +26694,7 @@ var WeaveStageDropAreaPlugin = class extends WeavePlugin {
26360
26694
  initEvents() {
26361
26695
  const stage = this.instance.getStage();
26362
26696
  stage.container().addEventListener("dragover", (e) => {
26697
+ e.preventDefault();
26363
26698
  e.stopPropagation();
26364
26699
  });
26365
26700
  stage.container().addEventListener("drop", (e) => {
@@ -26808,6 +27143,7 @@ exports.WEAVE_REGULAR_POLYGON_NODE_TYPE = WEAVE_REGULAR_POLYGON_NODE_TYPE
26808
27143
  exports.WEAVE_STAGE_GRID_KEY = WEAVE_STAGE_GRID_KEY
26809
27144
  exports.WEAVE_STAGE_NODE_TYPE = WEAVE_STAGE_NODE_TYPE
26810
27145
  exports.WEAVE_STAR_NODE_TYPE = WEAVE_STAR_NODE_TYPE
27146
+ exports.WEAVE_STROKE_NODE_TYPE = WEAVE_STROKE_NODE_TYPE
26811
27147
  exports.WEAVE_TEXT_NODE_TYPE = WEAVE_TEXT_NODE_TYPE
26812
27148
  exports.WEAVE_USERS_POINTERS_KEY = WEAVE_USERS_POINTERS_KEY
26813
27149
  exports.WEAVE_USERS_SELECTION_KEY = WEAVE_USERS_SELECTION_KEY
@@ -26857,6 +27193,7 @@ exports.WeaveStageZoomPlugin = WeaveStageZoomPlugin
26857
27193
  exports.WeaveStarNode = WeaveStarNode
26858
27194
  exports.WeaveStarToolAction = WeaveStarToolAction
26859
27195
  exports.WeaveStore = WeaveStore
27196
+ exports.WeaveStrokeNode = WeaveStrokeNode
26860
27197
  exports.WeaveTextNode = WeaveTextNode
26861
27198
  exports.WeaveTextToolAction = WeaveTextToolAction
26862
27199
  exports.WeaveUsersPointersPlugin = WeaveUsersPointersPlugin