@inditextech/weave-sdk 0.41.0 → 0.42.1

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
@@ -15879,6 +15879,7 @@ var WeaveContextMenuPlugin = class extends WeavePlugin {
15879
15879
  initEvents() {
15880
15880
  const stage = this.instance.getStage();
15881
15881
  stage.on("pointerdown", (e) => {
15882
+ e.evt.preventDefault();
15882
15883
  this.setTapStart(e);
15883
15884
  this.pointers[e.evt.pointerId] = e.evt;
15884
15885
  if (e.evt.buttons === 0) return;
@@ -16961,11 +16962,7 @@ var WeaveNode = class {
16961
16962
  const nodesSnappingPlugin = this.instance.getPlugin("nodesSnapping");
16962
16963
  if (nodesSelectionPlugin && this.isSelecting() && this.isNodeSelected(node$1)) nodesSelectionPlugin.getTransformer().forceUpdate();
16963
16964
  if (nodesSnappingPlugin && transforming && this.isSelecting() && this.isNodeSelected(node$1)) nodesSnappingPlugin.evaluateGuidelines(e);
16964
- if (this.isSelecting() && this.isNodeSelected(node$1)) {
16965
- this.scaleReset(node$1);
16966
- const nodeHandler = this.instance.getNodeHandler(node$1.getAttrs().nodeType);
16967
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(node$1));
16968
- }
16965
+ if (this.isSelecting() && this.isNodeSelected(node$1)) this.scaleReset(node$1);
16969
16966
  };
16970
16967
  node.on("transform", (0, import_lodash.throttle)(handleTransform, 100));
16971
16968
  node.on("transformend", (e) => {
@@ -17041,14 +17038,15 @@ var WeaveNode = class {
17041
17038
  node.on("pointerover", (e) => {
17042
17039
  e.cancelBubble = true;
17043
17040
  const stage = this.instance.getStage();
17041
+ const isNodeSelectionEnabled = this.getSelectionPlugin()?.isEnabled();
17044
17042
  const realNode = this.instance.getInstanceRecursive(node);
17045
17043
  const isTargetable = e.target.getAttrs().isTargetable !== false;
17046
17044
  const isLocked$1 = realNode.getAttrs().locked ?? false;
17047
- if (this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isLocked$1) {
17045
+ if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isLocked$1) {
17048
17046
  const stage$1 = this.instance.getStage();
17049
17047
  stage$1.container().style.cursor = "default";
17050
17048
  }
17051
- if (this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !isLocked$1 && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
17049
+ if (isNodeSelectionEnabled && this.isSelecting() && !this.isNodeSelected(realNode) && !this.isPasting() && isTargetable && !isLocked$1 && stage.mode() === WEAVE_STAGE_DEFAULT_MODE) {
17052
17050
  const stage$1 = this.instance.getStage();
17053
17051
  stage$1.container().style.cursor = "pointer";
17054
17052
  this.setHoverState(realNode);
@@ -18426,7 +18424,6 @@ var WeaveStateManager = class {
18426
18424
  }
18427
18425
  addNode(node, parentId = "mainLayer", index = void 0) {
18428
18426
  const state = this.instance.getStore().getState();
18429
- this.logger.info({ state: JSON.parse(JSON.stringify(state)) }, "State before addNode");
18430
18427
  if ((0, import_lodash.isEmpty)(state.weave)) {
18431
18428
  const msg = `State is empty, cannot add the node`;
18432
18429
  this.logger.warn({
@@ -18453,33 +18450,57 @@ var WeaveStateManager = class {
18453
18450
  }, msg);
18454
18451
  return;
18455
18452
  }
18456
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "addNode: parent before init");
18457
- const newChildren = JSON.parse(JSON.stringify(parent.props.children ?? []));
18458
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "addNode: parent before add");
18459
- if (index) {
18460
- newChildren?.splice(index, 0, node);
18461
- for (let i = 0; i < newChildren.length; i++) newChildren[i].props.zIndex = i;
18462
- }
18463
- if (!index) {
18464
- const childrenAmount = newChildren.length;
18465
- node.props.zIndex = childrenAmount;
18466
- const nodeToAdd = {
18467
- ...node,
18468
- props: {
18469
- ...node.props,
18470
- zIndex: childrenAmount
18471
- }
18472
- };
18473
- this.logger.info({ node: JSON.parse(JSON.stringify(nodeToAdd)) }, "addNode: node to add");
18474
- newChildren.push(nodeToAdd);
18453
+ const doc = (0, __syncedstore_core.getYjsDoc)(state);
18454
+ doc.transact(() => {
18455
+ if (!parent.props.children) parent.props.children = [];
18456
+ if (index) {
18457
+ parent.props.children.splice(index, 0, node);
18458
+ for (let i = 0; i < parent.props.children.length; i++) parent.props.children[i].props.zIndex = i;
18459
+ }
18460
+ if (!index) {
18461
+ const childrenAmount = parent.props.children.length;
18462
+ const nodeToAdd = {
18463
+ ...node,
18464
+ props: {
18465
+ ...node.props,
18466
+ zIndex: childrenAmount
18467
+ }
18468
+ };
18469
+ parent.props.children.push(nodeToAdd);
18470
+ }
18471
+ this.instance.emitEvent("onNodeAdded", node);
18472
+ });
18473
+ }
18474
+ deepSyncSyncedStore(target, source) {
18475
+ for (const key in target) if (!(key in source)) delete target[key];
18476
+ for (const key in source) {
18477
+ const srcVal = source[key];
18478
+ const tgtVal = target[key];
18479
+ const bothAreObjects = this.isObject(srcVal) && this.isObject(tgtVal);
18480
+ if (bothAreObjects && !Array.isArray(srcVal)) this.deepSyncSyncedStore(tgtVal, srcVal);
18481
+ else if (Array.isArray(srcVal)) this.syncArray(target, key, srcVal);
18482
+ else if (tgtVal !== srcVal) target[key] = srcVal;
18483
+ }
18484
+ }
18485
+ syncArray(target, key, sourceArr) {
18486
+ const tgtArr = target[key];
18487
+ if (!Array.isArray(tgtArr)) {
18488
+ target[key] = [...sourceArr];
18489
+ return;
18475
18490
  }
18476
- if (typeof newChildren !== "undefined") parent.props.children = newChildren;
18477
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "addNode: parent after add");
18478
- this.instance.emitEvent("onNodeAdded", node);
18491
+ while (tgtArr.length > sourceArr.length) tgtArr.pop();
18492
+ for (let i = 0; i < sourceArr.length; i++) {
18493
+ const srcItem = sourceArr[i];
18494
+ const tgtItem = tgtArr[i];
18495
+ if (this.isObject(srcItem) && this.isObject(tgtItem)) this.deepSyncSyncedStore(tgtItem, srcItem);
18496
+ else if (tgtItem !== srcItem) tgtArr[i] = srcItem;
18497
+ }
18498
+ }
18499
+ isObject(val) {
18500
+ return typeof val === "object" && val !== null;
18479
18501
  }
18480
18502
  updateNode(node) {
18481
18503
  const state = this.instance.getStore().getState();
18482
- this.logger.info({ state: JSON.parse(JSON.stringify(state)) }, "State before updateNode");
18483
18504
  if ((0, import_lodash.isEmpty)(state.weave)) {
18484
18505
  const msg = `State is empty, cannot update the node`;
18485
18506
  this.logger.warn({ node }, msg);
@@ -18491,19 +18512,14 @@ var WeaveStateManager = class {
18491
18512
  this.logger.warn({ node }, msg);
18492
18513
  return;
18493
18514
  }
18494
- this.logger.info({ node: JSON.parse(JSON.stringify(nodeState)) }, "updateNode: before update");
18495
- const newNode = JSON.parse(JSON.stringify(nodeState));
18496
- newNode.props = {
18497
- ...newNode.props,
18498
- ...node.props
18499
- };
18500
- if (typeof newNode.props !== "undefined") nodeState.props = newNode.props;
18501
- this.logger.info({ node: JSON.parse(JSON.stringify(nodeState)) }, "updateNode: after update");
18515
+ const doc = (0, __syncedstore_core.getYjsDoc)(state);
18516
+ doc.transact(() => {
18517
+ this.deepSyncSyncedStore(nodeState.props, node.props);
18518
+ });
18502
18519
  this.instance.emitEvent("onNodeUpdated", node);
18503
18520
  }
18504
18521
  removeNode(node) {
18505
18522
  const state = this.instance.getStore().getState();
18506
- this.logger.info({ stage: JSON.parse(JSON.stringify(state)) }, "State before removeNode");
18507
18523
  if ((0, import_lodash.isEmpty)(state.weave)) {
18508
18524
  const msg = `State is empty, cannot update the node`;
18509
18525
  this.logger.warn({ node }, msg);
@@ -18520,24 +18536,23 @@ var WeaveStateManager = class {
18520
18536
  this.logger.warn({ node }, msg);
18521
18537
  return;
18522
18538
  }
18523
- this.logger.info({ key: node.key }, "removeNode: node to remove");
18524
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "removeNode: parent before remove");
18525
- const newChildren = JSON.parse(JSON.stringify(parent.props.children ?? []));
18526
- for (let i = newChildren.length - 1; i >= 0; i--) if (newChildren[i].key === node.key) {
18527
- newChildren.splice(i, 1);
18528
- break;
18529
- }
18530
- for (let i = 0; i < newChildren.length; i++) newChildren[i].props.zIndex = i;
18531
- if (typeof newChildren !== "undefined") parent.props.children = newChildren;
18532
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "removeNode: parent after remove");
18533
- this.instance.emitEvent("onNodeRemoved", node);
18539
+ const doc = (0, __syncedstore_core.getYjsDoc)(state);
18540
+ doc.transact(() => {
18541
+ if (parent.props.children) {
18542
+ for (let i = parent.props.children.length - 1; i >= 0; i--) if (parent.props.children[i].key === node.key) {
18543
+ parent.props.children.splice(i, 1);
18544
+ break;
18545
+ }
18546
+ for (let i = 0; i < parent.props.children.length; i++) parent.props.children[i].props.zIndex = i;
18547
+ this.instance.emitEvent("onNodeRemoved", node);
18548
+ }
18549
+ });
18534
18550
  }
18535
18551
  removeNodes(nodes) {
18536
18552
  for (const node of nodes) this.removeNode(node);
18537
18553
  }
18538
18554
  moveNode(node, position) {
18539
18555
  const state = this.instance.getStore().getState();
18540
- this.logger.info({ stage: JSON.parse(JSON.stringify(state)) }, "State before moveNode");
18541
18556
  if ((0, import_lodash.isEmpty)(state.weave)) {
18542
18557
  const msg = `State is empty, cannot update the node`;
18543
18558
  this.logger.warn({ node }, msg);
@@ -18549,20 +18564,32 @@ var WeaveStateManager = class {
18549
18564
  this.logger.warn({ node }, msg);
18550
18565
  return;
18551
18566
  }
18552
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "moveNode: parent before move");
18553
- if (parent && parent.props.children) {
18567
+ if (!parent) {
18568
+ const msg = `Parent doesn't exists, cannot move it`;
18569
+ this.logger.warn({ node }, msg);
18570
+ return;
18571
+ }
18572
+ if (parent.props.children) {
18554
18573
  const childrenAmount = parent.props.children.length;
18555
18574
  const nodeIndex = parent.props.children.findIndex((child) => child.key === node.key);
18556
- const newChildren = JSON.parse(JSON.stringify(parent.props.children ?? []));
18557
- newChildren.splice(nodeIndex, 1);
18558
- if (position === __inditextech_weave_types.WEAVE_NODE_POSITION.UP) newChildren.splice(nodeIndex + 1, 0, { ...node });
18559
- if (position === __inditextech_weave_types.WEAVE_NODE_POSITION.DOWN) newChildren.splice(nodeIndex - 1, 0, { ...node });
18560
- if (position === __inditextech_weave_types.WEAVE_NODE_POSITION.FRONT) newChildren.splice(childrenAmount - 1, 0, { ...node });
18561
- if (position === __inditextech_weave_types.WEAVE_NODE_POSITION.BACK) newChildren.splice(0, 0, { ...node });
18562
- for (let i = 0; i < newChildren.length; i++) newChildren[i].props.zIndex = i;
18563
- if (typeof newChildren !== "undefined") parent.props.children = newChildren;
18575
+ if (nodeIndex === -1) {
18576
+ const msg = `Element doesn't exists on parent, cannot move it`;
18577
+ this.logger.warn({ node }, msg);
18578
+ return;
18579
+ }
18580
+ const doc = (0, __syncedstore_core.getYjsDoc)(state);
18581
+ doc.transact(() => {
18582
+ if (parent.props.children) {
18583
+ const item = JSON.parse(JSON.stringify(parent.props.children[nodeIndex]));
18584
+ parent.props.children.splice(nodeIndex, 1);
18585
+ if (item && position === __inditextech_weave_types.WEAVE_NODE_POSITION.UP) parent.props.children.splice(nodeIndex + 1, 0, item);
18586
+ if (item && position === __inditextech_weave_types.WEAVE_NODE_POSITION.DOWN) parent.props.children.splice(nodeIndex - 1, 0, item);
18587
+ if (item && position === __inditextech_weave_types.WEAVE_NODE_POSITION.FRONT) parent.props.children.splice(childrenAmount - 1, 0, item);
18588
+ if (item && position === __inditextech_weave_types.WEAVE_NODE_POSITION.BACK) parent.props.children.splice(0, 0, item);
18589
+ for (let i = 0; i < parent.props.children.length; i++) parent.props.children[i].props.zIndex = i;
18590
+ }
18591
+ });
18564
18592
  }
18565
- this.logger.info({ parent: JSON.parse(JSON.stringify(parent)) }, "moveNode: parent after move");
18566
18593
  }
18567
18594
  getElementsTree() {
18568
18595
  const state = this.instance.getStore().getState().weave;
@@ -18647,7 +18674,7 @@ var WeaveRegisterManager = class {
18647
18674
 
18648
18675
  //#endregion
18649
18676
  //#region package.json
18650
- var version = "0.41.0";
18677
+ var version = "0.42.1";
18651
18678
 
18652
18679
  //#endregion
18653
18680
  //#region src/managers/setup.ts
@@ -18747,7 +18774,6 @@ var WeaveStageManager = class {
18747
18774
  initialZIndex: void 0
18748
18775
  };
18749
18776
  const stage = new konva.default.Stage({ ...props });
18750
- stage.batchDraw();
18751
18777
  this.setStage(stage);
18752
18778
  }
18753
18779
  getContainerNodes() {
@@ -19382,6 +19408,10 @@ var WeaveStageNode = class extends WeaveNode {
19382
19408
  this.wheelMousePressed = false;
19383
19409
  stage.isFocused = () => this.stageFocused;
19384
19410
  stage.isMouseWheelPressed = () => this.wheelMousePressed;
19411
+ stage.position({
19412
+ x: 0,
19413
+ y: 0
19414
+ });
19385
19415
  const container = stage.container();
19386
19416
  container.setAttribute("tabindex", "0");
19387
19417
  stage.container().addEventListener("focus", () => {
@@ -19430,7 +19460,6 @@ var WeaveStageNode = class extends WeaveNode {
19430
19460
  stage.on("pointerup", (e) => {
19431
19461
  if (e.evt.button === 1) this.wheelMousePressed = false;
19432
19462
  });
19433
- stage.batchDraw();
19434
19463
  return stage;
19435
19464
  }
19436
19465
  onUpdate() {}
@@ -19791,7 +19820,6 @@ var WeaveTextNode = class extends WeaveNode {
19791
19820
  });
19792
19821
  resetScale(text);
19793
19822
  text.fontSize(text.fontSize() * text.scaleY());
19794
- this.instance.updateNode(this.serialize(text));
19795
19823
  e.cancelBubble = true;
19796
19824
  }
19797
19825
  });
@@ -19815,7 +19843,6 @@ var WeaveTextNode = class extends WeaveNode {
19815
19843
  width,
19816
19844
  height
19817
19845
  });
19818
- if (nextProps.width !== nodeInstance.getAttrs().width || nextProps.height !== nodeInstance.getAttrs().height) this.updateNode(nodeInstance);
19819
19846
  if (this.editing) this.updateTextAreaDOM(nodeInstance);
19820
19847
  const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
19821
19848
  if (nodesSelectionPlugin) {
@@ -20150,6 +20177,8 @@ const IMAGE_TOOL_ACTION_NAME = "imageTool";
20150
20177
  const IMAGE_TOOL_STATE = {
20151
20178
  ["IDLE"]: "idle",
20152
20179
  ["UPLOADING"]: "uploading",
20180
+ ["DEFINING_POSITION"]: "definingPosition",
20181
+ ["SELECTED_POSITION"]: "selectedPosition",
20153
20182
  ["ADDING"]: "adding",
20154
20183
  ["FINISHED"]: "finished"
20155
20184
  };
@@ -20159,14 +20188,17 @@ const IMAGE_TOOL_STATE = {
20159
20188
  var WeaveImageToolAction = class extends WeaveAction {
20160
20189
  initialized = false;
20161
20190
  initialCursor = null;
20191
+ cursorPadding = 5;
20162
20192
  onPropsChange = void 0;
20163
20193
  update = void 0;
20164
20194
  constructor() {
20165
20195
  super();
20196
+ this.pointers = new Map();
20166
20197
  this.initialized = false;
20167
20198
  this.state = IMAGE_TOOL_STATE.IDLE;
20168
20199
  this.imageId = null;
20169
20200
  this.tempImageId = null;
20201
+ this.tempImageNode = null;
20170
20202
  this.container = void 0;
20171
20203
  this.imageURL = null;
20172
20204
  this.preloadImgs = {};
@@ -20207,26 +20239,37 @@ var WeaveImageToolAction = class extends WeaveAction {
20207
20239
  return;
20208
20240
  }
20209
20241
  });
20210
- stage.on("pointerclick", () => {
20211
- if (this.state === IMAGE_TOOL_STATE.IDLE) return;
20212
- if (this.state === IMAGE_TOOL_STATE.UPLOADING) return;
20213
- if (this.state === IMAGE_TOOL_STATE.ADDING) {
20214
- this.handleAdding();
20242
+ stage.on("pointerdown", (e) => {
20243
+ this.setTapStart(e);
20244
+ this.pointers.set(e.evt.pointerId, {
20245
+ x: e.evt.clientX,
20246
+ y: e.evt.clientY
20247
+ });
20248
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
20249
+ this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
20215
20250
  return;
20216
20251
  }
20252
+ if (this.state === IMAGE_TOOL_STATE.DEFINING_POSITION) this.state = IMAGE_TOOL_STATE.SELECTED_POSITION;
20217
20253
  });
20218
- stage.on("pointermove", () => {
20219
- const tempImage = this.instance.getStage().findOne(`#${this.tempImageId}`);
20220
- if (this.state === IMAGE_TOOL_STATE.ADDING && tempImage) {
20254
+ stage.on("pointermove", (e) => {
20255
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME) {
20256
+ this.state = IMAGE_TOOL_STATE.DEFINING_POSITION;
20257
+ return;
20258
+ }
20259
+ if ([IMAGE_TOOL_STATE.DEFINING_POSITION, IMAGE_TOOL_STATE.SELECTED_POSITION].includes(this.state) && this.tempImageNode && this.instance.getActiveAction() === IMAGE_TOOL_ACTION_NAME && e.evt.pointerType === "mouse") {
20260
+ stage.container().style.cursor = "crosshair";
20261
+ stage.container().focus();
20221
20262
  const mousePos = stage.getRelativePointerPosition();
20222
- tempImage.setAttrs({
20223
- x: (mousePos?.x ?? 0) + 2,
20224
- y: (mousePos?.y ?? 0) + 2
20263
+ this.tempImageNode.setAttrs({
20264
+ x: (mousePos?.x ?? 0) + this.cursorPadding,
20265
+ y: (mousePos?.y ?? 0) + this.cursorPadding
20225
20266
  });
20226
- const nodeHandler = this.instance.getNodeHandler("rectangle");
20227
- if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(tempImage));
20228
20267
  }
20229
20268
  });
20269
+ stage.on("pointerup", (e) => {
20270
+ this.pointers.delete(e.evt.pointerId);
20271
+ if (this.state === IMAGE_TOOL_STATE.SELECTED_POSITION) this.handleAdding();
20272
+ });
20230
20273
  this.initialized = true;
20231
20274
  }
20232
20275
  setState(state) {
@@ -20261,47 +20304,50 @@ var WeaveImageToolAction = class extends WeaveAction {
20261
20304
  this.preloadImgs[this.imageId].src = imageURL;
20262
20305
  this.instance.emitEvent("onImageLoadStart");
20263
20306
  }
20307
+ isTouchDevice() {
20308
+ return window.matchMedia("(pointer: coarse)").matches;
20309
+ }
20264
20310
  addImageNode(position) {
20265
20311
  const stage = this.instance.getStage();
20266
20312
  stage.container().style.cursor = "crosshair";
20267
20313
  stage.container().focus();
20268
20314
  if (position) {
20269
- this.setState(IMAGE_TOOL_STATE.ADDING);
20315
+ this.setState(IMAGE_TOOL_STATE.SELECTED_POSITION);
20270
20316
  this.handleAdding(position);
20271
20317
  return;
20272
20318
  }
20273
20319
  if (this.imageId) {
20274
20320
  const mousePos = stage.getRelativePointerPosition();
20275
- const nodeHandler = this.instance.getNodeHandler("image");
20276
20321
  this.tempImageId = v4_default();
20277
20322
  const aspectRatio = this.preloadImgs[this.imageId].width / this.preloadImgs[this.imageId].height;
20278
- if (nodeHandler) {
20279
- const node = nodeHandler.create(this.tempImageId, {
20280
- x: (mousePos?.x ?? 0) + 5,
20281
- y: (mousePos?.y ?? 0) + 5,
20282
- width: 100 * aspectRatio,
20283
- height: 100,
20323
+ if (!this.tempImageNode && this.tempImageId && !this.isTouchDevice()) {
20324
+ this.tempImageNode = new konva.default.Image({
20325
+ id: this.tempImageId,
20326
+ x: (mousePos?.x ?? 0) + this.cursorPadding,
20327
+ y: (mousePos?.y ?? 0) + this.cursorPadding,
20328
+ width: 240 * aspectRatio * (1 / stage.scaleX()),
20329
+ height: 240 * (1 / stage.scaleY()),
20284
20330
  opacity: 1,
20285
20331
  adding: true,
20286
- imageURL: this.imageURL,
20332
+ image: this.preloadImgs[this.imageId],
20287
20333
  stroke: "#000000ff",
20288
20334
  strokeWidth: 0,
20289
20335
  strokeScaleEnabled: true,
20290
20336
  listening: false
20291
20337
  });
20292
- this.instance.addNode(node, this.container?.getAttrs().id);
20338
+ this.instance.getMainLayer()?.add(this.tempImageNode);
20293
20339
  }
20340
+ this.instance.emitEvent("onAddingImage", { imageURL: this.props.imageURL });
20294
20341
  }
20295
20342
  this.clickPoint = null;
20296
- this.setState(IMAGE_TOOL_STATE.ADDING);
20343
+ this.setState(IMAGE_TOOL_STATE.DEFINING_POSITION);
20297
20344
  }
20298
20345
  addImage(position) {
20299
20346
  if (position) this.clickPoint = position;
20300
20347
  this.setState(IMAGE_TOOL_STATE.UPLOADING);
20301
20348
  }
20302
20349
  handleAdding(position) {
20303
- const tempImage = this.instance.getStage().findOne(`#${this.tempImageId}`);
20304
- if (this.imageId && this.imageURL && this.preloadImgs[this.imageId] && (!position && tempImage || position)) {
20350
+ if (this.imageId && this.imageURL && this.preloadImgs[this.imageId]) {
20305
20351
  const { mousePoint, container } = this.instance.getMousePointer(position);
20306
20352
  this.clickPoint = mousePoint;
20307
20353
  this.container = container;
@@ -20325,10 +20371,7 @@ var WeaveImageToolAction = class extends WeaveAction {
20325
20371
  }
20326
20372
  });
20327
20373
  this.instance.addNode(node, this.container?.getAttrs().id);
20328
- }
20329
- if (!position) {
20330
- const imageNodeHandler = this.instance.getNodeHandler("image");
20331
- if (imageNodeHandler) this.instance.removeNode(imageNodeHandler.serialize(tempImage));
20374
+ this.instance.emitEvent("onAddedImage", { imageURL: this.props.imageURL });
20332
20375
  }
20333
20376
  this.setState(IMAGE_TOOL_STATE.FINISHED);
20334
20377
  }
@@ -20351,11 +20394,7 @@ var WeaveImageToolAction = class extends WeaveAction {
20351
20394
  cleanup() {
20352
20395
  const stage = this.instance.getStage();
20353
20396
  if (this.imageId) delete this.preloadImgs[this.imageId];
20354
- const tempImage = this.instance.getStage().findOne(`#${this.tempImageId}`);
20355
- if (tempImage) {
20356
- const nodeHandler = this.instance.getNodeHandler("rectangle");
20357
- if (nodeHandler) this.instance.removeNode(nodeHandler.serialize(tempImage));
20358
- }
20397
+ if (this.tempImageNode) this.tempImageNode.destroy();
20359
20398
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
20360
20399
  if (selectionPlugin) {
20361
20400
  const node = stage.findOne(`#${this.imageId}`);
@@ -20833,8 +20872,8 @@ var WeaveImageNode = class extends WeaveNode {
20833
20872
  scaleX: 1,
20834
20873
  scaleY: 1,
20835
20874
  rotation: 0,
20836
- width: imageProps.width ?? 0,
20837
- height: imageProps.height ?? 0,
20875
+ width: imageProps.width || 0,
20876
+ height: imageProps.height || 0,
20838
20877
  fill: "#ccccccff",
20839
20878
  strokeWidth: 0,
20840
20879
  draggable: false,
@@ -23360,6 +23399,7 @@ var import_hammer = __toESM(require_hammer(), 1);
23360
23399
  var WeaveStageZoomPlugin = class extends WeavePlugin {
23361
23400
  getLayerName = void 0;
23362
23401
  initLayer = void 0;
23402
+ pinching = false;
23363
23403
  zooming = false;
23364
23404
  isTrackpad = false;
23365
23405
  zoomVelocity = 0;
@@ -23376,6 +23416,8 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23376
23416
  const { config } = params ?? {};
23377
23417
  this.config = (0, import_lodash.merge)(WEAVE_STAGE_ZOOM_DEFAULT_CONFIG, config);
23378
23418
  if (!this.config.zoomSteps.includes(this.config.defaultZoom)) throw new Error(`Default zoom ${this.config.defaultZoom} is not in zoom steps`);
23419
+ this.threshold = .2;
23420
+ this.pinching = false;
23379
23421
  this.isTrackpad = false;
23380
23422
  this.isCtrlOrMetaPressed = false;
23381
23423
  this.updatedMinimumZoom = false;
@@ -23515,10 +23557,6 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23515
23557
  const scale = Math.min(scaleX, scaleY);
23516
23558
  return scale;
23517
23559
  }
23518
- getSelectionPlugin() {
23519
- const selectionPlugin = this.instance.getPlugin("nodesSelection");
23520
- return selectionPlugin;
23521
- }
23522
23560
  fitToScreen() {
23523
23561
  if (!this.enabled) return;
23524
23562
  const mainLayer = this.instance.getMainLayer();
@@ -23559,7 +23597,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23559
23597
  fitToSelection() {
23560
23598
  if (!this.enabled) return;
23561
23599
  const stage = this.instance.getStage();
23562
- const selectionPlugin = this.getSelectionPlugin();
23600
+ const selectionPlugin = this.getNodesSelectionPlugin();
23563
23601
  if (!selectionPlugin) return;
23564
23602
  const nodes = selectionPlugin.getTransformer().getNodes();
23565
23603
  if (nodes.length === 0) return;
@@ -23630,10 +23668,15 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23630
23668
  const stageContainer = this.instance.getStage().container();
23631
23669
  const sc = new import_hammer.default.Manager(stageContainer);
23632
23670
  sc.add(new import_hammer.default.Pinch({
23633
- threshold: 0,
23671
+ threshold: this.threshold,
23634
23672
  pointers: 2
23635
23673
  }));
23636
23674
  sc.on("pinchstart", (e) => {
23675
+ if (this.getPanPlugin()?.isPanning()) {
23676
+ this.pinching = false;
23677
+ return;
23678
+ }
23679
+ this.getNodesSelectionPlugin()?.disable();
23637
23680
  this.initialScale = this.instance.getStage().scaleX();
23638
23681
  this.center = {
23639
23682
  x: e.center.x,
@@ -23642,6 +23685,11 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23642
23685
  this.lastTime = performance.now();
23643
23686
  });
23644
23687
  sc.on("pinchmove", (e) => {
23688
+ if (this.getPanPlugin()?.isPanning()) {
23689
+ this.pinching = false;
23690
+ return;
23691
+ }
23692
+ this.pinching = true;
23645
23693
  const now = performance.now();
23646
23694
  this.getContextMenuPlugin()?.cancelLongPressTimer();
23647
23695
  const newScale = Math.max(this.config.zoomSteps[0], Math.min(this.config.zoomSteps[this.config.zoomSteps.length - 1], this.initialScale * e.scale));
@@ -23651,6 +23699,13 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23651
23699
  this.lastTime = now;
23652
23700
  });
23653
23701
  sc.on("pinchend", () => {
23702
+ if (this.getPanPlugin()?.isPanning()) {
23703
+ this.pinching = false;
23704
+ this.zooming = false;
23705
+ return;
23706
+ }
23707
+ this.getNodesSelectionPlugin()?.enable();
23708
+ this.pinching = false;
23654
23709
  this.zooming = true;
23655
23710
  this.zoomInertiaType = WEAVE_STAGE_ZOOM_TYPE.PINCH_ZOOM;
23656
23711
  requestAnimationFrame(this.zoomTick.bind(this));
@@ -23660,6 +23715,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23660
23715
  const stage$1 = this.instance.getStage();
23661
23716
  const performZoom = this.isCtrlOrMetaPressed || !this.isCtrlOrMetaPressed && e.evt.ctrlKey && e.evt.deltaMode === 0;
23662
23717
  if (!this.enabled || !stage$1.isFocused() || !performZoom) return;
23718
+ this.getNodesSelectionPlugin()?.disable();
23663
23719
  const delta = e.evt.deltaY > 0 ? 1 : -1;
23664
23720
  this.zoomVelocity += delta;
23665
23721
  this.isTrackpad = Math.abs(e.evt.deltaY) < 15 && e.evt.deltaMode === 0;
@@ -23692,10 +23748,27 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
23692
23748
  pointer = stage.getPointerPosition();
23693
23749
  }
23694
23750
  if (!pointer) return;
23751
+ this.getNodesSelectionPlugin()?.enable();
23695
23752
  this.setZoom(this.getInertiaScale(), false, pointer);
23696
23753
  this.zoomVelocity *= this.config.zoomInertia.friction;
23754
+ this.getStageGridPlugin()?.onRender();
23697
23755
  requestAnimationFrame(this.zoomTick.bind(this));
23698
23756
  }
23757
+ isPinching() {
23758
+ return this.pinching;
23759
+ }
23760
+ getStageGridPlugin() {
23761
+ const gridPlugin = this.instance.getPlugin("stageGrid");
23762
+ return gridPlugin;
23763
+ }
23764
+ getNodesSelectionPlugin() {
23765
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
23766
+ return selectionPlugin;
23767
+ }
23768
+ getPanPlugin() {
23769
+ const panPlugin = this.instance.getPlugin("stagePanning");
23770
+ return panPlugin;
23771
+ }
23699
23772
  getContextMenuPlugin() {
23700
23773
  const contextMenuPlugin = this.instance.getPlugin("contextMenu");
23701
23774
  return contextMenuPlugin;
@@ -24061,6 +24134,7 @@ var WeaveRectangleToolAction = class extends WeaveAction {
24061
24134
  onInit = void 0;
24062
24135
  constructor() {
24063
24136
  super();
24137
+ this.pointers = new Map();
24064
24138
  this.initialized = false;
24065
24139
  this.state = RECTANGLE_TOOL_STATE.IDLE;
24066
24140
  this.rectId = null;
@@ -24097,6 +24171,14 @@ var WeaveRectangleToolAction = class extends WeaveAction {
24097
24171
  });
24098
24172
  stage.on("pointerdown", (e) => {
24099
24173
  this.setTapStart(e);
24174
+ this.pointers.set(e.evt.pointerId, {
24175
+ x: e.evt.clientX,
24176
+ y: e.evt.clientY
24177
+ });
24178
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === RECTANGLE_TOOL_ACTION_NAME) {
24179
+ this.state = RECTANGLE_TOOL_STATE.ADDING;
24180
+ return;
24181
+ }
24100
24182
  if (this.state === RECTANGLE_TOOL_STATE.ADDING) {
24101
24183
  this.creating = true;
24102
24184
  this.handleAdding();
@@ -24104,12 +24186,18 @@ var WeaveRectangleToolAction = class extends WeaveAction {
24104
24186
  });
24105
24187
  stage.on("pointermove", (e) => {
24106
24188
  if (!this.isPressed(e)) return;
24189
+ if (!this.pointers.has(e.evt.pointerId)) return;
24190
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === RECTANGLE_TOOL_ACTION_NAME) {
24191
+ this.state = RECTANGLE_TOOL_STATE.ADDING;
24192
+ return;
24193
+ }
24107
24194
  if (this.state === RECTANGLE_TOOL_STATE.DEFINING_SIZE) {
24108
24195
  this.moved = true;
24109
24196
  this.handleMovement();
24110
24197
  }
24111
24198
  });
24112
24199
  stage.on("pointerup", (e) => {
24200
+ this.pointers.delete(e.evt.pointerId);
24113
24201
  const isTap = this.isTap(e);
24114
24202
  if (isTap) this.moved = false;
24115
24203
  if (this.state === RECTANGLE_TOOL_STATE.DEFINING_SIZE) {
@@ -24126,6 +24214,7 @@ var WeaveRectangleToolAction = class extends WeaveAction {
24126
24214
  const stage = this.instance.getStage();
24127
24215
  stage.container().style.cursor = "crosshair";
24128
24216
  stage.container().focus();
24217
+ this.instance.emitEvent("onAddingRectangle");
24129
24218
  this.clickPoint = null;
24130
24219
  this.setState(RECTANGLE_TOOL_STATE.ADDING);
24131
24220
  }
@@ -24173,6 +24262,7 @@ var WeaveRectangleToolAction = class extends WeaveAction {
24173
24262
  height: rectHeight
24174
24263
  });
24175
24264
  if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(rectangle));
24265
+ this.instance.emitEvent("onAddedRectangle");
24176
24266
  }
24177
24267
  this.cancelAction();
24178
24268
  }
@@ -24239,6 +24329,7 @@ var WeaveEllipseToolAction = class extends WeaveAction {
24239
24329
  onInit = void 0;
24240
24330
  constructor() {
24241
24331
  super();
24332
+ this.pointers = new Map();
24242
24333
  this.initialized = false;
24243
24334
  this.state = ELLIPSE_TOOL_STATE.IDLE;
24244
24335
  this.ellipseId = null;
@@ -24276,6 +24367,14 @@ var WeaveEllipseToolAction = class extends WeaveAction {
24276
24367
  });
24277
24368
  stage.on("pointerdown", (e) => {
24278
24369
  this.setTapStart(e);
24370
+ this.pointers.set(e.evt.pointerId, {
24371
+ x: e.evt.clientX,
24372
+ y: e.evt.clientY
24373
+ });
24374
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === ELLIPSE_TOOL_ACTION_NAME) {
24375
+ this.state = ELLIPSE_TOOL_STATE.ADDING;
24376
+ return;
24377
+ }
24279
24378
  if (this.state === ELLIPSE_TOOL_STATE.ADDING) {
24280
24379
  this.creating = true;
24281
24380
  this.handleAdding();
@@ -24283,12 +24382,18 @@ var WeaveEllipseToolAction = class extends WeaveAction {
24283
24382
  });
24284
24383
  stage.on("pointermove", (e) => {
24285
24384
  if (!this.isPressed(e)) return;
24385
+ if (!this.pointers.has(e.evt.pointerId)) return;
24386
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === ELLIPSE_TOOL_ACTION_NAME) {
24387
+ this.state = ELLIPSE_TOOL_STATE.ADDING;
24388
+ return;
24389
+ }
24286
24390
  if (this.state === ELLIPSE_TOOL_STATE.DEFINING_SIZE) {
24287
24391
  this.moved = true;
24288
24392
  this.handleMovement();
24289
24393
  }
24290
24394
  });
24291
24395
  stage.on("pointerup", (e) => {
24396
+ this.pointers.delete(e.evt.pointerId);
24292
24397
  const isTap = this.isTap(e);
24293
24398
  if (isTap) this.moved = false;
24294
24399
  if (this.state === ELLIPSE_TOOL_STATE.DEFINING_SIZE) {
@@ -24305,6 +24410,7 @@ var WeaveEllipseToolAction = class extends WeaveAction {
24305
24410
  const stage = this.instance.getStage();
24306
24411
  stage.container().style.cursor = "crosshair";
24307
24412
  stage.container().focus();
24413
+ this.instance.emitEvent("onAddingEllipse");
24308
24414
  this.clickPoint = null;
24309
24415
  this.setState(ELLIPSE_TOOL_STATE.ADDING);
24310
24416
  }
@@ -24352,6 +24458,7 @@ var WeaveEllipseToolAction = class extends WeaveAction {
24352
24458
  radiusY: ellipseRadiusY
24353
24459
  });
24354
24460
  if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(ellipse));
24461
+ this.instance.emitEvent("onAddedEllipse");
24355
24462
  }
24356
24463
  this.cancelAction();
24357
24464
  }
@@ -24429,6 +24536,7 @@ var WeavePenToolAction = class extends WeaveAction {
24429
24536
  onInit = void 0;
24430
24537
  constructor() {
24431
24538
  super();
24539
+ this.pointers = new Map();
24432
24540
  this.initialized = false;
24433
24541
  this.state = PEN_TOOL_STATE.IDLE;
24434
24542
  this.lineId = null;
@@ -24462,19 +24570,30 @@ var WeavePenToolAction = class extends WeaveAction {
24462
24570
  return;
24463
24571
  }
24464
24572
  });
24465
- stage.on("pointerclick", () => {
24466
- if (this.state === PEN_TOOL_STATE.IDLE) return;
24467
- if (this.state === PEN_TOOL_STATE.ADDING) {
24468
- this.handleAdding();
24573
+ stage.on("pointerdown", (e) => {
24574
+ this.setTapStart(e);
24575
+ this.pointers.set(e.evt.pointerId, {
24576
+ x: e.evt.clientX,
24577
+ y: e.evt.clientY
24578
+ });
24579
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === PEN_TOOL_ACTION_NAME) {
24580
+ this.state = PEN_TOOL_STATE.ADDING;
24469
24581
  return;
24470
24582
  }
24471
- if (this.state === PEN_TOOL_STATE.DEFINING_SIZE) {
24472
- this.handleSettingSize();
24583
+ if (this.state === PEN_TOOL_STATE.ADDING) this.handleAdding();
24584
+ });
24585
+ stage.on("pointermove", (e) => {
24586
+ if (!this.isPressed(e)) return;
24587
+ if (!this.pointers.has(e.evt.pointerId)) return;
24588
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === PEN_TOOL_ACTION_NAME) {
24589
+ this.state = PEN_TOOL_STATE.ADDING;
24473
24590
  return;
24474
24591
  }
24592
+ if (this.state === PEN_TOOL_STATE.DEFINING_SIZE) this.handleMovement();
24475
24593
  });
24476
- stage.on("pointermove", () => {
24477
- this.handleMovement();
24594
+ stage.on("pointerup", (e) => {
24595
+ this.pointers.delete(e.evt.pointerId);
24596
+ if (this.state === PEN_TOOL_STATE.DEFINING_SIZE) this.handleSettingSize();
24478
24597
  });
24479
24598
  this.initialized = true;
24480
24599
  }
@@ -24986,6 +25105,7 @@ var WeaveStarToolAction = class extends WeaveAction {
24986
25105
  onInit = void 0;
24987
25106
  constructor() {
24988
25107
  super();
25108
+ this.pointers = new Map();
24989
25109
  this.initialized = false;
24990
25110
  this.state = STAR_TOOL_STATE.IDLE;
24991
25111
  this.starId = null;
@@ -25024,6 +25144,14 @@ var WeaveStarToolAction = class extends WeaveAction {
25024
25144
  });
25025
25145
  stage.on("pointerdown", (e) => {
25026
25146
  this.setTapStart(e);
25147
+ this.pointers.set(e.evt.pointerId, {
25148
+ x: e.evt.clientX,
25149
+ y: e.evt.clientY
25150
+ });
25151
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === STAR_TOOL_ACTION_NAME) {
25152
+ this.state = STAR_TOOL_STATE.ADDING;
25153
+ return;
25154
+ }
25027
25155
  if (this.state === STAR_TOOL_STATE.ADDING) {
25028
25156
  this.creating = true;
25029
25157
  this.handleAdding();
@@ -25031,12 +25159,18 @@ var WeaveStarToolAction = class extends WeaveAction {
25031
25159
  });
25032
25160
  stage.on("pointermove", (e) => {
25033
25161
  if (!this.isPressed(e)) return;
25162
+ if (!this.pointers.has(e.evt.pointerId)) return;
25163
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === STAR_TOOL_ACTION_NAME) {
25164
+ this.state = STAR_TOOL_STATE.ADDING;
25165
+ return;
25166
+ }
25034
25167
  if (this.state === STAR_TOOL_STATE.DEFINING_SIZE) {
25035
25168
  this.moved = true;
25036
25169
  this.handleMovement();
25037
25170
  }
25038
25171
  });
25039
25172
  stage.on("pointerup", (e) => {
25173
+ this.pointers.delete(e.evt.pointerId);
25040
25174
  const isTap = this.isTap(e);
25041
25175
  if (isTap) this.moved = false;
25042
25176
  if (this.state === STAR_TOOL_STATE.DEFINING_SIZE) {
@@ -25053,6 +25187,7 @@ var WeaveStarToolAction = class extends WeaveAction {
25053
25187
  const stage = this.instance.getStage();
25054
25188
  stage.container().style.cursor = "crosshair";
25055
25189
  stage.container().focus();
25190
+ this.instance.emitEvent("onAddingStar");
25056
25191
  this.clickPoint = null;
25057
25192
  this.setState(STAR_TOOL_STATE.ADDING);
25058
25193
  }
@@ -25101,6 +25236,7 @@ var WeaveStarToolAction = class extends WeaveAction {
25101
25236
  innerRadius: starInnerRadius
25102
25237
  });
25103
25238
  if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(star));
25239
+ this.instance.emitEvent("onAddedStar");
25104
25240
  }
25105
25241
  this.cancelAction();
25106
25242
  }
@@ -25430,6 +25566,7 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
25430
25566
  onInit = void 0;
25431
25567
  constructor() {
25432
25568
  super();
25569
+ this.pointers = new Map();
25433
25570
  this.initialized = false;
25434
25571
  this.state = REGULAR_POLYGON_TOOL_STATE.IDLE;
25435
25572
  this.regularPolygonId = null;
@@ -25466,6 +25603,14 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
25466
25603
  });
25467
25604
  stage.on("pointerdown", (e) => {
25468
25605
  this.setTapStart(e);
25606
+ this.pointers.set(e.evt.pointerId, {
25607
+ x: e.evt.clientX,
25608
+ y: e.evt.clientY
25609
+ });
25610
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === REGULAR_POLYGON_TOOL_ACTION_NAME) {
25611
+ this.state = REGULAR_POLYGON_TOOL_STATE.ADDING;
25612
+ return;
25613
+ }
25469
25614
  if (this.state === REGULAR_POLYGON_TOOL_STATE.ADDING) {
25470
25615
  this.creating = true;
25471
25616
  this.handleAdding();
@@ -25473,12 +25618,18 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
25473
25618
  });
25474
25619
  stage.on("pointermove", (e) => {
25475
25620
  if (!this.isPressed(e)) return;
25621
+ if (!this.pointers.has(e.evt.pointerId)) return;
25622
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === REGULAR_POLYGON_TOOL_ACTION_NAME) {
25623
+ this.state = REGULAR_POLYGON_TOOL_STATE.ADDING;
25624
+ return;
25625
+ }
25476
25626
  if (this.state === REGULAR_POLYGON_TOOL_STATE.DEFINING_SIZE) {
25477
25627
  this.moved = true;
25478
25628
  this.handleMovement();
25479
25629
  }
25480
25630
  });
25481
25631
  stage.on("pointerup", (e) => {
25632
+ this.pointers.delete(e.evt.pointerId);
25482
25633
  const isTap = this.isTap(e);
25483
25634
  if (isTap) this.moved = false;
25484
25635
  if (this.state === REGULAR_POLYGON_TOOL_STATE.DEFINING_SIZE) {
@@ -25495,6 +25646,7 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
25495
25646
  const stage = this.instance.getStage();
25496
25647
  stage.container().style.cursor = "crosshair";
25497
25648
  stage.container().focus();
25649
+ this.instance.emitEvent("onAddingRegularPolygon");
25498
25650
  this.clickPoint = null;
25499
25651
  this.setState(REGULAR_POLYGON_TOOL_STATE.ADDING);
25500
25652
  }
@@ -25538,6 +25690,7 @@ var WeaveRegularPolygonToolAction = class extends WeaveAction {
25538
25690
  radius: newRadius
25539
25691
  });
25540
25692
  if (nodeHandler) this.instance.updateNode(nodeHandler.serialize(regularPolygon));
25693
+ this.instance.emitEvent("onAddedRegularPolygon");
25541
25694
  }
25542
25695
  this.cancelAction();
25543
25696
  }
@@ -26114,6 +26267,9 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
26114
26267
  window.addEventListener("keyup", (e) => {
26115
26268
  if (e.code === "Space") this.isSpaceKeyPressed = false;
26116
26269
  });
26270
+ this.instance.addEventListener("onStageMove", () => {
26271
+ this.onRender();
26272
+ });
26117
26273
  stage.on("pointerdown", (e) => {
26118
26274
  const activeAction = this.instance.getActiveAction();
26119
26275
  if (e && e.evt.button === 0 && activeAction === "moveTool") this.moveToolActive = true;
@@ -26306,7 +26462,9 @@ var WeaveStageGridPlugin = class extends WeavePlugin {
26306
26462
  }
26307
26463
  }
26308
26464
  onRender() {
26309
- this.renderGrid();
26465
+ requestAnimationFrame(() => {
26466
+ this.renderGrid();
26467
+ });
26310
26468
  }
26311
26469
  enable() {
26312
26470
  this.enabled = true;
@@ -26334,11 +26492,18 @@ const WEAVE_STAGE_PANNING_KEY = "stagePanning";
26334
26492
  //#endregion
26335
26493
  //#region src/plugins/stage-panning/stage-panning.ts
26336
26494
  var WeaveStagePanningPlugin = class extends WeavePlugin {
26495
+ pinching = false;
26496
+ panning = false;
26337
26497
  getLayerName = void 0;
26338
26498
  initLayer = void 0;
26339
26499
  constructor() {
26340
26500
  super();
26341
- this.activePointers = new Set();
26501
+ this.pointers = new Map();
26502
+ this.lastCenter = null;
26503
+ this.pinching = false;
26504
+ this.panning = false;
26505
+ this.threshold = 5;
26506
+ this.pointersDistanceDiffThreshold = 10;
26342
26507
  this.enabled = true;
26343
26508
  this.moveToolActive = false;
26344
26509
  this.isMouseMiddleButtonPressed = false;
@@ -26382,6 +26547,8 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
26382
26547
  this.disableMove();
26383
26548
  }
26384
26549
  });
26550
+ let startPointersDistance = null;
26551
+ let startCenter = null;
26385
26552
  let lastPos = null;
26386
26553
  let isDragging = false;
26387
26554
  let velocity = {
@@ -26390,7 +26557,10 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
26390
26557
  };
26391
26558
  let lastTime = 0;
26392
26559
  stage.on("pointerdown", (e) => {
26393
- this.activePointers.add(e.evt.pointerId);
26560
+ this.pointers.set(e.evt.pointerId, {
26561
+ x: e.evt.clientX,
26562
+ y: e.evt.clientY
26563
+ });
26394
26564
  const activeAction = this.instance.getActiveAction();
26395
26565
  let enableMove = false;
26396
26566
  if (e && (e.evt.pointerType !== "mouse" || e.evt.pointerType === "mouse" && e.evt.buttons === 1) && activeAction === "moveTool") {
@@ -26401,6 +26571,27 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
26401
26571
  this.isMouseMiddleButtonPressed = true;
26402
26572
  enableMove = true;
26403
26573
  }
26574
+ if (e.evt.pointerType !== "mouse" && this.pointers.size === 2 && !this.pinching && !this.panning) {
26575
+ const center = this.getTouchCenter();
26576
+ const [p1, p2] = Array.from(this.pointers.values());
26577
+ const pointersDistance = this.getDistance(p1, p2);
26578
+ if (!startCenter) {
26579
+ startPointersDistance = pointersDistance;
26580
+ startCenter = center;
26581
+ this.lastCenter = center;
26582
+ this.pinching = false;
26583
+ this.panning = false;
26584
+ velocity = {
26585
+ x: 0,
26586
+ y: 0
26587
+ };
26588
+ }
26589
+ isDragging = true;
26590
+ lastPos = stage.getPointerPosition();
26591
+ lastTime = performance.now();
26592
+ this.enableMove();
26593
+ return;
26594
+ }
26404
26595
  if (enableMove) {
26405
26596
  isDragging = true;
26406
26597
  lastPos = stage.getPointerPosition();
@@ -26412,28 +26603,65 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
26412
26603
  this.enableMove();
26413
26604
  }
26414
26605
  });
26415
- stage.on("pointercancel", () => {
26606
+ stage.on("pointercancel", (e) => {
26607
+ this.pointers.delete(e.evt.pointerId);
26416
26608
  lastPos = null;
26609
+ this.lastCenter = null;
26417
26610
  });
26418
- stage.on("pointerup", (e) => {
26419
- this.activePointers.delete(e.evt.pointerId);
26420
- isDragging = false;
26421
- const decay = .95;
26422
- function animateInertia() {
26423
- velocity.x *= decay;
26424
- velocity.y *= decay;
26425
- if (Math.abs(velocity.x) < .01 && Math.abs(velocity.y) < .01) return;
26426
- stage.x(stage.x() + velocity.x * 16);
26427
- stage.y(stage.y() + velocity.y * 16);
26428
- stage.batchDraw();
26429
- requestAnimationFrame(animateInertia);
26430
- }
26431
- requestAnimationFrame(animateInertia);
26432
- });
26433
- const handleMouseMove = () => {
26434
- if (this.activePointers.size !== 1) return;
26611
+ const handleMouseMove = (e) => {
26612
+ this.pointers.set(e.evt.pointerId, {
26613
+ x: e.evt.clientX,
26614
+ y: e.evt.clientY
26615
+ });
26435
26616
  if (!isDragging) return;
26617
+ const center = this.getTouchCenter();
26618
+ if (e.evt.pointerType !== "mouse" && this.pointers.size !== 2) {
26619
+ startCenter = null;
26620
+ startPointersDistance = null;
26621
+ this.pinching = false;
26622
+ this.panning = false;
26623
+ }
26624
+ if (e.evt.pointerType !== "mouse" && this.pointers.size === 2) {
26625
+ this.getContextMenuPlugin()?.cancelLongPressTimer();
26626
+ const [p1, p2] = Array.from(this.pointers.values());
26627
+ const pointersDistance = this.getDistance(p1, p2);
26628
+ if (!startCenter) {
26629
+ startPointersDistance = pointersDistance;
26630
+ startCenter = center;
26631
+ this.lastCenter = center;
26632
+ this.pinching = false;
26633
+ this.panning = false;
26634
+ }
26635
+ if (center && startCenter && startPointersDistance && this.lastCenter) {
26636
+ const now$1 = performance.now();
26637
+ const dt$1 = now$1 - lastTime;
26638
+ const dx = center.x - startCenter.x;
26639
+ const dy = center.y - startCenter.y;
26640
+ const distanceCenters = Math.hypot(dx, dy);
26641
+ const distanceChange = Math.abs(pointersDistance - startPointersDistance);
26642
+ if (!this.pinching && distanceCenters > this.threshold && distanceChange <= this.pointersDistanceDiffThreshold) this.panning = true;
26643
+ if (!this.panning && distanceCenters <= this.threshold && distanceChange > this.pointersDistanceDiffThreshold) this.pinching = true;
26644
+ if (this.panning) {
26645
+ this.getNodesSelectionPlugin()?.disable();
26646
+ const dx$1 = center.x - this.lastCenter.x;
26647
+ const dy$1 = center.y - this.lastCenter.y;
26648
+ velocity = {
26649
+ x: dx$1 / dt$1,
26650
+ y: dy$1 / dt$1
26651
+ };
26652
+ stage.x(stage.x() + dx$1);
26653
+ stage.y(stage.y() + dy$1);
26654
+ this.instance.emitEvent("onStageMove");
26655
+ }
26656
+ this.lastCenter = center;
26657
+ lastTime = now$1;
26658
+ return;
26659
+ }
26660
+ }
26661
+ this.lastCenter = center;
26436
26662
  if (!this.enabled || !(this.isSpaceKeyPressed || this.isMouseMiddleButtonPressed || this.moveToolActive)) return;
26663
+ this.getContextMenuPlugin()?.cancelLongPressTimer();
26664
+ this.getNodesSelectionPlugin()?.disable();
26437
26665
  const pos = stage.getPointerPosition();
26438
26666
  const now = performance.now();
26439
26667
  const dt = now - lastTime;
@@ -26446,20 +26674,50 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
26446
26674
  };
26447
26675
  stage.x(stage.x() + dx);
26448
26676
  stage.y(stage.y() + dy);
26449
- stage.batchDraw();
26450
26677
  }
26451
26678
  lastPos = pos;
26452
26679
  lastTime = now;
26453
26680
  this.instance.emitEvent("onStageMove");
26454
26681
  };
26455
26682
  stage.on("pointermove", handleMouseMove);
26683
+ const decay = .95;
26684
+ const animateInertia = () => {
26685
+ velocity.x *= decay;
26686
+ velocity.y *= decay;
26687
+ if (Math.abs(velocity.x) < .01 && Math.abs(velocity.y) < .01) return;
26688
+ stage.x(stage.x() + velocity.x);
26689
+ stage.y(stage.y() + velocity.y);
26690
+ this.instance.emitEvent("onStageMove");
26691
+ requestAnimationFrame(animateInertia);
26692
+ };
26693
+ stage.on("pointerup", (e) => {
26694
+ this.pointers.delete(e.evt.pointerId);
26695
+ if (e.evt.pointerType !== "mouse" && this.pointers.size < 2) {
26696
+ this.getNodesSelectionPlugin()?.enable();
26697
+ isDragging = false;
26698
+ startCenter = null;
26699
+ startPointersDistance = null;
26700
+ this.lastCenter = null;
26701
+ this.pinching = false;
26702
+ this.panning = false;
26703
+ requestAnimationFrame(animateInertia);
26704
+ return;
26705
+ }
26706
+ isDragging = false;
26707
+ this.pinching = false;
26708
+ this.panning = false;
26709
+ requestAnimationFrame(animateInertia);
26710
+ });
26456
26711
  const handleWheel = (e) => {
26457
26712
  e.evt.preventDefault();
26458
26713
  const stage$1 = this.instance.getStage();
26459
26714
  const performPanning = !this.isCtrlOrMetaPressed && !e.evt.ctrlKey;
26460
26715
  if (!this.enabled || !stage$1.isFocused() || this.isCtrlOrMetaPressed || e.evt.buttons === 4 || !performPanning) return;
26716
+ this.getContextMenuPlugin()?.cancelLongPressTimer();
26717
+ this.getNodesSelectionPlugin()?.disable();
26461
26718
  stage$1.x(stage$1.x() - e.evt.deltaX);
26462
26719
  stage$1.y(stage$1.y() - e.evt.deltaY);
26720
+ this.getNodesSelectionPlugin()?.enable();
26463
26721
  this.instance.emitEvent("onStageMove");
26464
26722
  };
26465
26723
  stage.on("wheel", handleWheel);
@@ -26470,6 +26728,35 @@ var WeaveStagePanningPlugin = class extends WeavePlugin {
26470
26728
  e.preventDefault();
26471
26729
  }, { passive: false });
26472
26730
  }
26731
+ isPanning() {
26732
+ return this.panning;
26733
+ }
26734
+ getDistance(p1, p2) {
26735
+ const dx = p2.x - p1.x;
26736
+ const dy = p2.y - p1.y;
26737
+ return Math.hypot(dx, dy);
26738
+ }
26739
+ getTouchCenter() {
26740
+ const points = Array.from(this.pointers.values());
26741
+ if (points.length !== 2) return null;
26742
+ const [p1, p2] = points;
26743
+ return {
26744
+ x: (p1.x + p2.x) / 2,
26745
+ y: (p1.y + p2.y) / 2
26746
+ };
26747
+ }
26748
+ getNodesSelectionPlugin() {
26749
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
26750
+ return selectionPlugin;
26751
+ }
26752
+ getZoomPlugin() {
26753
+ const zoomPlugin = this.instance.getPlugin("stageZoom");
26754
+ return zoomPlugin;
26755
+ }
26756
+ getContextMenuPlugin() {
26757
+ const contextMenuPlugin = this.instance.getPlugin("contextMenu");
26758
+ return contextMenuPlugin;
26759
+ }
26473
26760
  enable() {
26474
26761
  this.enabled = true;
26475
26762
  }