@inditextech/weave-sdk 0.36.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.36.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)";
@@ -20612,7 +20689,6 @@ var WeaveImageNode = class extends WeaveNode {
20612
20689
  const imageProps = params;
20613
20690
  const imagePlaceholder = image.findOne(`#${imageProps.id}-placeholder`);
20614
20691
  const internalImage = image.findOne(`#${imageProps.id}-image`);
20615
- console.log("crossOrigin", this.config.crossOrigin);
20616
20692
  const imageObj = new Image();
20617
20693
  imageObj.crossOrigin = this.config.crossOrigin;
20618
20694
  imageObj.onerror = (error) => {
@@ -21047,7 +21123,28 @@ var WeaveFrameNode = class extends WeaveNode {
21047
21123
  width: props.frameWidth,
21048
21124
  height: props.frameHeight,
21049
21125
  fill: "transparent",
21050
- 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
+ }
21051
21148
  });
21052
21149
  selectorArea.getTransformerProperties = () => {
21053
21150
  return this.config.transform;
@@ -21058,7 +21155,6 @@ var WeaveFrameNode = class extends WeaveNode {
21058
21155
  x: 0,
21059
21156
  y: 0
21060
21157
  });
21061
- this.instance.updateNode(this.serialize(selectorArea));
21062
21158
  };
21063
21159
  const updateFrame = (e) => {
21064
21160
  const selectorArea$1 = e.target;
@@ -21129,17 +21225,18 @@ var WeaveFrameNode = class extends WeaveNode {
21129
21225
  width: props.frameWidth - borderWidth * 2,
21130
21226
  height: props.frameHeight - borderWidth * 2,
21131
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
+ },
21132
21233
  draggable: false
21133
21234
  });
21134
- frameInternal.clipFunc((ctx) => {
21135
- const width = (frameInternal.width() + borderWidth) * frameInternal.scaleX();
21136
- const height = (frameInternal.height() + borderWidth) * frameInternal.scaleY();
21137
- ctx.rect(-(borderWidth / 2) * frameInternal.scaleX(), -(borderWidth / 2) * frameInternal.scaleY(), width, height);
21138
- });
21139
21235
  frameInternalGroup.add(frameInternal);
21140
21236
  this.setupDefaultNodeEvents(frame);
21141
- frame.on("dragmove", () => {});
21142
- frame.on("dragend", () => {});
21237
+ frame.off("dragstart");
21238
+ frame.off("dragmove");
21239
+ frame.off("dragend");
21143
21240
  frame.on(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, () => {
21144
21241
  background.setAttrs({
21145
21242
  stroke: onTargetLeaveBorderColor,
@@ -21247,10 +21344,125 @@ var WeaveFrameNode = class extends WeaveNode {
21247
21344
  }
21248
21345
  };
21249
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
+
21250
21453
  //#endregion
21251
21454
  //#region src/plugins/stage-zoom/constants.ts
21455
+ const WEAVE_STAGE_ZOOM_TYPE = {
21456
+ MOUSE_WHEEL: "mouseWheel",
21457
+ PINCH_ZOOM: "pinchZoom"
21458
+ };
21252
21459
  const WEAVE_STAGE_ZOOM_KEY = "stageZoom";
21253
21460
  const WEAVE_STAGE_ZOOM_DEFAULT_CONFIG = {
21461
+ zoomInertia: {
21462
+ friction: .9,
21463
+ mouseWheelStep: .01,
21464
+ trackpadStep: .005
21465
+ },
21254
21466
  zoomSteps: [
21255
21467
  .01,
21256
21468
  .05,
@@ -22954,15 +23166,23 @@ var import_hammer = __toESM(require_hammer(), 1);
22954
23166
  var WeaveStageZoomPlugin = class extends WeavePlugin {
22955
23167
  getLayerName = void 0;
22956
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
+ };
22957
23179
  defaultStep = 3;
22958
23180
  constructor(params) {
22959
23181
  super();
22960
23182
  const { config } = params ?? {};
22961
- this.config = {
22962
- ...WEAVE_STAGE_ZOOM_DEFAULT_CONFIG,
22963
- ...config
22964
- };
23183
+ this.config = (0, import_lodash.merge)(WEAVE_STAGE_ZOOM_DEFAULT_CONFIG, config);
22965
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;
22966
23186
  this.isCtrlOrMetaPressed = false;
22967
23187
  this.updatedMinimumZoom = false;
22968
23188
  this.actualStep = this.config.zoomSteps.findIndex((step) => step === this.config.defaultZoom);
@@ -23215,38 +23435,68 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23215
23435
  threshold: 0,
23216
23436
  pointers: 2
23217
23437
  }));
23218
- let initialScale = null;
23219
- let center = {
23220
- x: 0,
23221
- y: 0
23222
- };
23223
- sc.on("pinchstart", (ev) => {
23224
- initialScale = stage.scaleX();
23225
- center = {
23226
- x: ev.center.x,
23227
- 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
23228
23443
  };
23444
+ this.lastTime = performance.now();
23229
23445
  });
23230
- sc.on("pinchmove", (ev) => {
23231
- if (!initialScale) return;
23232
- const newScale = initialScale * ev.scale;
23233
- 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));
23234
23458
  });
23235
23459
  const handleWheel = (e) => {
23236
23460
  e.evt.preventDefault();
23237
23461
  const stage$1 = this.instance.getStage();
23238
23462
  const performZoom = this.isCtrlOrMetaPressed || !this.isCtrlOrMetaPressed && e.evt.ctrlKey && e.evt.deltaMode === 0;
23239
23463
  if (!this.enabled || !stage$1.isFocused() || !performZoom) return;
23240
- const oldScale = stage$1.scaleX();
23241
- const pointer = stage$1.getPointerPosition();
23242
- if (!pointer) return;
23243
- const scaleBy = 1.025;
23244
- const direction = e.evt.deltaY > 0 ? 1 : -1;
23245
- const newScale = direction > 0 ? oldScale / scaleBy : oldScale * scaleBy;
23246
- 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
+ }
23247
23472
  };
23248
23473
  stage.on("wheel", handleWheel);
23249
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
+ }
23250
23500
  };
23251
23501
 
23252
23502
  //#endregion
@@ -23571,7 +23821,10 @@ var WeaveEraserToolAction = class extends WeaveAction {
23571
23821
  stage.container().focus();
23572
23822
  this.cancelAction = cancelAction;
23573
23823
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
23574
- if (selectionPlugin) selectionPlugin.disable();
23824
+ if (selectionPlugin) {
23825
+ selectionPlugin.setSelectedNodes([]);
23826
+ selectionPlugin.disable();
23827
+ }
23575
23828
  this.setEraser();
23576
23829
  }
23577
23830
  cleanup() {
@@ -23639,19 +23892,23 @@ var WeaveRectangleToolAction = class extends WeaveAction {
23639
23892
  return;
23640
23893
  }
23641
23894
  });
23642
- stage.on("pointerdown", () => {
23895
+ stage.on("pointerdown", (e) => {
23896
+ this.setTapStart(e);
23643
23897
  if (this.state === RECTANGLE_TOOL_STATE.ADDING) {
23644
23898
  this.creating = true;
23645
23899
  this.handleAdding();
23646
23900
  }
23647
23901
  });
23648
- stage.on("pointermove", () => {
23902
+ stage.on("pointermove", (e) => {
23903
+ if (!this.isPressed(e)) return;
23649
23904
  if (this.state === RECTANGLE_TOOL_STATE.DEFINING_SIZE) {
23650
23905
  this.moved = true;
23651
23906
  this.handleMovement();
23652
23907
  }
23653
23908
  });
23654
- stage.on("pointerup", () => {
23909
+ stage.on("pointerup", (e) => {
23910
+ const isTap = this.isTap(e);
23911
+ if (isTap) this.moved = false;
23655
23912
  if (this.state === RECTANGLE_TOOL_STATE.DEFINING_SIZE) {
23656
23913
  this.creating = false;
23657
23914
  this.handleSettingSize();
@@ -23814,19 +24071,23 @@ var WeaveEllipseToolAction = class extends WeaveAction {
23814
24071
  return;
23815
24072
  }
23816
24073
  });
23817
- stage.on("pointerdown", () => {
24074
+ stage.on("pointerdown", (e) => {
24075
+ this.setTapStart(e);
23818
24076
  if (this.state === ELLIPSE_TOOL_STATE.ADDING) {
23819
24077
  this.creating = true;
23820
24078
  this.handleAdding();
23821
24079
  }
23822
24080
  });
23823
- stage.on("pointermove", () => {
24081
+ stage.on("pointermove", (e) => {
24082
+ if (!this.isPressed(e)) return;
23824
24083
  if (this.state === ELLIPSE_TOOL_STATE.DEFINING_SIZE) {
23825
24084
  this.moved = true;
23826
24085
  this.handleMovement();
23827
24086
  }
23828
24087
  });
23829
- stage.on("pointerup", () => {
24088
+ stage.on("pointerup", (e) => {
24089
+ const isTap = this.isTap(e);
24090
+ if (isTap) this.moved = false;
23830
24091
  if (this.state === ELLIPSE_TOOL_STATE.DEFINING_SIZE) {
23831
24092
  this.creating = false;
23832
24093
  this.handleSettingSize();
@@ -24196,11 +24457,13 @@ const BRUSH_TOOL_STATE = {
24196
24457
  //#region src/actions/brush-tool/brush-tool.ts
24197
24458
  var WeaveBrushToolAction = class extends WeaveAction {
24198
24459
  initialized = false;
24460
+ lineWidth = 0;
24199
24461
  onPropsChange = void 0;
24200
24462
  onInit = void 0;
24201
24463
  constructor() {
24202
24464
  super();
24203
24465
  this.initialized = false;
24466
+ this.lineWidth = 0;
24204
24467
  this.state = BRUSH_TOOL_STATE.INACTIVE;
24205
24468
  this.strokeId = null;
24206
24469
  this.clickPoint = null;
@@ -24218,6 +24481,11 @@ var WeaveBrushToolAction = class extends WeaveAction {
24218
24481
  opacity: 1
24219
24482
  };
24220
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
+ }
24221
24489
  setupEvents() {
24222
24490
  const stage = this.instance.getStage();
24223
24491
  stage.container().tabIndex = 1;
@@ -24232,75 +24500,132 @@ var WeaveBrushToolAction = class extends WeaveAction {
24232
24500
  return;
24233
24501
  }
24234
24502
  });
24235
- stage.on("pointerdown", (e) => {
24503
+ const handlePointerDown = (e) => {
24236
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;
24237
24507
  this.handleStartStroke();
24238
24508
  e.evt.stopPropagation();
24239
- });
24240
- stage.on("pointermove", (e) => {
24509
+ };
24510
+ stage.on("pointerdown touchstart", handlePointerDown);
24511
+ const handlePointerMove = (e) => {
24241
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;
24242
24515
  this.handleMovement();
24243
24516
  e.evt.stopPropagation();
24244
- });
24245
- stage.on("pointerup", (e) => {
24517
+ };
24518
+ stage.on("pointermove touchmove", handlePointerMove);
24519
+ const handlePointerUp = (e) => {
24246
24520
  if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
24247
24521
  this.handleEndStroke();
24248
24522
  e.evt.stopPropagation();
24249
- });
24523
+ };
24524
+ stage.on("pointerup touchend", handlePointerUp);
24250
24525
  this.initialized = true;
24251
24526
  }
24252
24527
  setState(state) {
24253
24528
  this.state = state;
24254
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
+ }
24255
24554
  handleStartStroke() {
24256
24555
  const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
24257
24556
  this.clickPoint = mousePoint;
24258
24557
  this.container = container;
24259
24558
  this.measureContainer = measureContainer;
24260
24559
  this.strokeId = v4_default();
24261
- const nodeHandler = this.instance.getNodeHandler("line");
24560
+ const nodeHandler = this.instance.getNodeHandler("stroke");
24262
24561
  if (nodeHandler) {
24263
24562
  const node = nodeHandler.create(this.strokeId, {
24264
24563
  ...this.props,
24265
24564
  strokeScaleEnabled: true,
24266
- x: this.clickPoint?.x ?? 0,
24267
- y: this.clickPoint?.y ?? 0,
24268
- points: [0, 0]
24565
+ x: 0,
24566
+ y: 0,
24567
+ width: 0,
24568
+ height: 0,
24569
+ strokeElements: []
24269
24570
  });
24270
- this.instance.addNode(node, this.container?.getAttrs().id);
24571
+ const nodeInstance = nodeHandler.onRender(node.props);
24572
+ this.container?.add(nodeInstance);
24271
24573
  }
24272
24574
  this.setState(BRUSH_TOOL_STATE.DEFINE_STROKE);
24273
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
+ }
24274
24599
  handleEndStroke() {
24275
24600
  const stage = this.instance.getStage();
24276
24601
  const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
24277
24602
  if (tempStroke) {
24278
- const nodeHandler = this.instance.getNodeHandler("line");
24279
- tempStroke.setAttrs({
24280
- ...this.props,
24281
- hitStrokeWidth: 10
24282
- });
24283
- 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
+ }
24284
24623
  this.clickPoint = null;
24285
24624
  stage.container().tabIndex = 1;
24286
24625
  stage.container().focus();
24287
24626
  this.setState(BRUSH_TOOL_STATE.IDLE);
24288
24627
  }
24289
24628
  }
24290
- handleMovement() {
24291
- if (this.state !== BRUSH_TOOL_STATE.DEFINE_STROKE) return;
24292
- const tempStroke = this.instance.getStage().findOne(`#${this.strokeId}`);
24293
- if (this.measureContainer && tempStroke) {
24294
- const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
24295
- tempStroke.points([
24296
- ...tempStroke.points(),
24297
- mousePoint.x - tempStroke.x(),
24298
- mousePoint.y - tempStroke.y()
24299
- ]);
24300
- const nodeHandler = this.instance.getNodeHandler("line");
24301
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(tempStroke));
24302
- }
24303
- }
24304
24629
  trigger(cancel) {
24305
24630
  if (!this.instance) throw new Error("Instance not defined");
24306
24631
  if (!this.initialized) this.setupEvents();
@@ -24494,19 +24819,23 @@ var WeaveStarToolAction = class extends WeaveAction {
24494
24819
  return;
24495
24820
  }
24496
24821
  });
24497
- stage.on("pointerdown", () => {
24822
+ stage.on("pointerdown", (e) => {
24823
+ this.setTapStart(e);
24498
24824
  if (this.state === STAR_TOOL_STATE.ADDING) {
24499
24825
  this.creating = true;
24500
24826
  this.handleAdding();
24501
24827
  }
24502
24828
  });
24503
- stage.on("pointermove", () => {
24829
+ stage.on("pointermove", (e) => {
24830
+ if (!this.isPressed(e)) return;
24504
24831
  if (this.state === STAR_TOOL_STATE.DEFINING_SIZE) {
24505
24832
  this.moved = true;
24506
24833
  this.handleMovement();
24507
24834
  }
24508
24835
  });
24509
- stage.on("pointerup", () => {
24836
+ stage.on("pointerup", (e) => {
24837
+ const isTap = this.isTap(e);
24838
+ if (isTap) this.moved = false;
24510
24839
  if (this.state === STAR_TOOL_STATE.DEFINING_SIZE) {
24511
24840
  this.creating = false;
24512
24841
  this.handleSettingSize();
@@ -24932,19 +25261,23 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
24932
25261
  return;
24933
25262
  }
24934
25263
  });
24935
- stage.on("pointerdown", () => {
25264
+ stage.on("pointerdown", (e) => {
25265
+ this.setTapStart(e);
24936
25266
  if (this.state === REGULAR_POLYGON_TOOL_STATE.ADDING) {
24937
25267
  this.creating = true;
24938
25268
  this.handleAdding();
24939
25269
  }
24940
25270
  });
24941
- stage.on("pointermove", () => {
25271
+ stage.on("pointermove", (e) => {
25272
+ if (!this.isPressed(e)) return;
24942
25273
  if (this.state === REGULAR_POLYGON_TOOL_STATE.DEFINING_SIZE) {
24943
25274
  this.moved = true;
24944
25275
  this.handleMovement();
24945
25276
  }
24946
25277
  });
24947
- stage.on("pointerup", () => {
25278
+ stage.on("pointerup", (e) => {
25279
+ const isTap = this.isTap(e);
25280
+ if (isTap) this.moved = false;
24948
25281
  if (this.state === REGULAR_POLYGON_TOOL_STATE.DEFINING_SIZE) {
24949
25282
  this.creating = false;
24950
25283
  this.handleSettingSize();
@@ -26361,6 +26694,7 @@ var WeaveStageDropAreaPlugin = class extends WeavePlugin {
26361
26694
  initEvents() {
26362
26695
  const stage = this.instance.getStage();
26363
26696
  stage.container().addEventListener("dragover", (e) => {
26697
+ e.preventDefault();
26364
26698
  e.stopPropagation();
26365
26699
  });
26366
26700
  stage.container().addEventListener("drop", (e) => {
@@ -26809,6 +27143,7 @@ exports.WEAVE_REGULAR_POLYGON_NODE_TYPE = WEAVE_REGULAR_POLYGON_NODE_TYPE
26809
27143
  exports.WEAVE_STAGE_GRID_KEY = WEAVE_STAGE_GRID_KEY
26810
27144
  exports.WEAVE_STAGE_NODE_TYPE = WEAVE_STAGE_NODE_TYPE
26811
27145
  exports.WEAVE_STAR_NODE_TYPE = WEAVE_STAR_NODE_TYPE
27146
+ exports.WEAVE_STROKE_NODE_TYPE = WEAVE_STROKE_NODE_TYPE
26812
27147
  exports.WEAVE_TEXT_NODE_TYPE = WEAVE_TEXT_NODE_TYPE
26813
27148
  exports.WEAVE_USERS_POINTERS_KEY = WEAVE_USERS_POINTERS_KEY
26814
27149
  exports.WEAVE_USERS_SELECTION_KEY = WEAVE_USERS_SELECTION_KEY
@@ -26858,6 +27193,7 @@ exports.WeaveStageZoomPlugin = WeaveStageZoomPlugin
26858
27193
  exports.WeaveStarNode = WeaveStarNode
26859
27194
  exports.WeaveStarToolAction = WeaveStarToolAction
26860
27195
  exports.WeaveStore = WeaveStore
27196
+ exports.WeaveStrokeNode = WeaveStrokeNode
26861
27197
  exports.WeaveTextNode = WeaveTextNode
26862
27198
  exports.WeaveTextToolAction = WeaveTextToolAction
26863
27199
  exports.WeaveUsersPointersPlugin = WeaveUsersPointersPlugin