@inditextech/weave-sdk 2.20.2 → 2.21.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.js CHANGED
@@ -17765,7 +17765,10 @@ function hasFrames(node) {
17765
17765
  else return true;
17766
17766
  }
17767
17767
  function intersectArrays(arrays) {
17768
- return arrays.reduce((acc, arr) => acc.filter((val) => arr.includes(val)), arrays[0]);
17768
+ if (arrays.length === 0) return [];
17769
+ if (arrays.some((arr) => arr.length === 0)) return [];
17770
+ const sorted = [...arrays].sort((a, b) => a.length - b.length);
17771
+ return sorted[0].filter((item) => sorted.every((arr) => arr.includes(item)));
17769
17772
  }
17770
17773
  function isNodeInSelection(node, nodes) {
17771
17774
  return nodes.some((selectedNode) => selectedNode.id() === node.id());
@@ -18606,6 +18609,7 @@ const DEFAULT_ADD_NODE_OPTIONS = { emitUserChangeEvent: true };
18606
18609
  const DEFAULT_UPDATE_NODE_OPTIONS = { emitUserChangeEvent: true };
18607
18610
  const DEFAULT_REMOVE_NODE_OPTIONS = { emitUserChangeEvent: true };
18608
18611
  const DEFAULT_MOVE_NODE_OPTIONS = { emitUserChangeEvent: true };
18612
+ const WEAVE_DEFAULT_CONFIG = { behaviors: { axisLockThreshold: 5 } };
18609
18613
 
18610
18614
  //#endregion
18611
18615
  //#region src/plugins/users-presence/constants.ts
@@ -18642,6 +18646,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18642
18646
  "bottom-right"
18643
18647
  ];
18644
18648
  this.taps = 0;
18649
+ this.isCtrlMetaPressed = false;
18645
18650
  this.isSpaceKeyPressed = false;
18646
18651
  this.isDoubleTap = false;
18647
18652
  this.tapStart = {
@@ -18664,6 +18669,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18664
18669
  getLayerName() {
18665
18670
  return WEAVE_NODES_SELECTION_LAYER_ID;
18666
18671
  }
18672
+ getConfiguration() {
18673
+ return this.config;
18674
+ }
18667
18675
  initLayer() {
18668
18676
  const stage = this.instance.getStage();
18669
18677
  const layer = new Konva.Layer({ id: this.getLayerName() });
@@ -18760,18 +18768,18 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18760
18768
  const targetNode = this.instance.getInstanceRecursive(shape);
18761
18769
  if (targetNode && targetNode !== nodeHovered) {
18762
18770
  this.instance.getStage().handleMouseover();
18763
- nodeHovered?.handleMouseout();
18764
- targetNode?.handleMouseover();
18771
+ nodeHovered?.handleMouseout?.();
18772
+ targetNode?.handleMouseover?.();
18765
18773
  nodeHovered = targetNode;
18766
18774
  }
18767
- targetNode?.handleMouseover();
18768
- } else nodeHovered?.handleMouseout();
18775
+ targetNode?.handleMouseover?.();
18776
+ } else nodeHovered?.handleMouseout?.();
18769
18777
  });
18770
18778
  tr.on("mouseover", () => {
18771
18779
  stage.container().style.cursor = "grab";
18772
18780
  });
18773
18781
  tr.on("mouseout", () => {
18774
- this.instance.getStage().handleMouseover();
18782
+ this.instance.getStage().handleMouseover?.();
18775
18783
  nodeHovered = void 0;
18776
18784
  });
18777
18785
  window.addEventListener("mouseout", () => {
@@ -18779,7 +18787,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
18779
18787
  nodeHovered.handleMouseout();
18780
18788
  nodeHovered = void 0;
18781
18789
  }
18782
- this.instance.getStage().handleMouseover();
18790
+ this.instance.getStage().handleMouseover?.();
18783
18791
  });
18784
18792
  const handleTransform = (e) => {
18785
18793
  const moved = this.checkMoved(e);
@@ -19184,6 +19192,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19184
19192
  this.selecting = false;
19185
19193
  const stage = this.instance.getStage();
19186
19194
  stage.container().addEventListener("keydown", (e) => {
19195
+ if (e.ctrlKey || e.metaKey) this.isCtrlMetaPressed = true;
19187
19196
  if (e.code === "Space") this.isSpaceKeyPressed = true;
19188
19197
  if ((e.code === "Backspace" || e.code === "Delete") && Object.keys(window.weaveTextEditing).length === 0) {
19189
19198
  Promise.resolve().then(() => {
@@ -19193,6 +19202,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19193
19202
  }
19194
19203
  });
19195
19204
  stage.container().addEventListener("keyup", (e) => {
19205
+ if (e.ctrlKey || e.metaKey) this.isCtrlMetaPressed = false;
19196
19206
  if (e.code === "Space") this.isSpaceKeyPressed = false;
19197
19207
  });
19198
19208
  stage.on("pointerdown", (e) => {
@@ -19244,6 +19254,10 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19244
19254
  this.selectionRectangle.width(0);
19245
19255
  this.selectionRectangle.height(0);
19246
19256
  this.selecting = true;
19257
+ if (this.isCtrlMetaPressed) {
19258
+ const nodesSelected = this.tr.nodes();
19259
+ for (const node of nodesSelected) node.fire("onSelectionCleared", { bubbles: true });
19260
+ }
19247
19261
  this.tr.nodes([]);
19248
19262
  this.instance.emitEvent("onSelectionState", true);
19249
19263
  this.panLoopId = requestAnimationFrame(() => this.panLoop());
@@ -19386,6 +19400,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19386
19400
  if (this.tr.nodes().length > 1 && this.config.behaviors?.onMultipleSelection) {
19387
19401
  const selectionBehavior = this.config.behaviors?.onMultipleSelection?.(this.tr.nodes());
19388
19402
  this.tr.setAttrs(selectionBehavior);
19403
+ this.tr.forceUpdate();
19389
19404
  }
19390
19405
  }
19391
19406
  syncSelection() {
@@ -19458,6 +19473,7 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19458
19473
  nodeTargeted.dblClick();
19459
19474
  return;
19460
19475
  }
19476
+ if (stage.isCmdCtrlPressed()) return;
19461
19477
  if (!metaPressed) {
19462
19478
  this.tr.nodes([nodeTargeted]);
19463
19479
  this.tr.show();
@@ -19509,7 +19525,9 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
19509
19525
  if (nodesSelected > 1) {
19510
19526
  const anchorsArrays = [];
19511
19527
  for (const node of nodes) anchorsArrays.push(node.allowedAnchors());
19512
- transformerAttrs.enabledAnchors = intersectArrays(anchorsArrays);
19528
+ const enabledAnchors = intersectArrays(anchorsArrays);
19529
+ transformerAttrs.enabledAnchors = enabledAnchors;
19530
+ this.tr.enabledAnchors(transformerAttrs.enabledAnchors);
19513
19531
  }
19514
19532
  if (this.tr && this.tr.nodes().length > 0) {
19515
19533
  this.tr.setAttrs(transformerAttrs);
@@ -20247,7 +20265,7 @@ var WeaveNode = class {
20247
20265
  this.hideHoverState();
20248
20266
  return;
20249
20267
  }
20250
- if (node.canBeHovered()) selectionPlugin.getHoverTransformer().nodes([node]);
20268
+ if (node?.canBeHovered?.()) selectionPlugin.getHoverTransformer().nodes([node]);
20251
20269
  else selectionPlugin.getHoverTransformer().nodes([]);
20252
20270
  selectionPlugin.getHoverTransformer().moveToTop();
20253
20271
  }
@@ -20257,25 +20275,27 @@ var WeaveNode = class {
20257
20275
  selectionPlugin.getHoverTransformer().nodes([]);
20258
20276
  }
20259
20277
  setupDefaultNodeEvents(node) {
20260
- this.instance.addEventListener("onNodesChange", () => {
20278
+ const handleNodesChange = () => {
20261
20279
  if (!this.isLocked(node) && this.isSelecting() && this.isNodeSelected(node)) {
20262
20280
  node.draggable(true);
20263
20281
  return;
20264
20282
  }
20265
20283
  node.draggable(false);
20266
- });
20284
+ };
20267
20285
  const isLocked = node.getAttrs().locked ?? false;
20268
20286
  if (isLocked) {
20287
+ this.instance.removeEventListener("onNodesChange", handleNodesChange);
20269
20288
  node.off("transformstart");
20270
20289
  node.off("transform");
20271
20290
  node.off("transformend");
20272
20291
  node.off("dragstart");
20273
20292
  node.off("dragmove");
20274
20293
  node.off("dragend");
20275
- node.off("pointerenter");
20294
+ node.off("pointerover");
20276
20295
  node.off("pointerleave");
20277
20296
  } else {
20278
20297
  let transforming = false;
20298
+ this.instance.addEventListener("onNodesChange", handleNodesChange);
20279
20299
  node.on("transformstart", (e) => {
20280
20300
  transforming = true;
20281
20301
  if (e.target.getAttrs().strokeScaleEnabled !== false) {
@@ -20341,6 +20361,9 @@ var WeaveNode = class {
20341
20361
  });
20342
20362
  let originalNode = void 0;
20343
20363
  let originalContainer = void 0;
20364
+ let startPosition = null;
20365
+ let lockedAxis = null;
20366
+ let isShiftPressed = false;
20344
20367
  node.on("dragstart", (e) => {
20345
20368
  const nodeTarget = e.target;
20346
20369
  this.getNodesSelectionFeedbackPlugin()?.hideSelectionHalo(nodeTarget);
@@ -20366,6 +20389,14 @@ var WeaveNode = class {
20366
20389
  }
20367
20390
  const realNodeTarget = this.getRealSelectedNode(nodeTarget);
20368
20391
  if (realNodeTarget.getAttrs().isCloned) return;
20392
+ lockedAxis = null;
20393
+ if (e.evt.shiftKey && !startPosition) startPosition = realNodeTarget.absolutePosition();
20394
+ if (e.evt.shiftKey) isShiftPressed = true;
20395
+ else {
20396
+ lockedAxis = null;
20397
+ startPosition = null;
20398
+ isShiftPressed = false;
20399
+ }
20369
20400
  if (this.getNodesSelectionPlugin()?.getSelectedNodes().length === 1 && realNodeTarget.getAttr("dragStartOpacity") === void 0) {
20370
20401
  realNodeTarget.setAttr("dragStartOpacity", realNodeTarget.opacity());
20371
20402
  realNodeTarget.opacity(this.getNodesSelectionPlugin()?.getDragOpacity());
@@ -20422,6 +20453,13 @@ var WeaveNode = class {
20422
20453
  return;
20423
20454
  }
20424
20455
  const realNodeTarget = this.getRealSelectedNode(nodeTarget);
20456
+ if (e.evt.shiftKey && !startPosition) startPosition = realNodeTarget.absolutePosition();
20457
+ if (e.evt.shiftKey) isShiftPressed = true;
20458
+ else {
20459
+ lockedAxis = null;
20460
+ startPosition = null;
20461
+ isShiftPressed = false;
20462
+ }
20425
20463
  if (this.isSelecting() && this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20426
20464
  clearContainerTargets(this.instance);
20427
20465
  this.getUsersPresencePlugin()?.setPresence(realNodeTarget.id(), {
@@ -20433,8 +20471,30 @@ var WeaveNode = class {
20433
20471
  }
20434
20472
  };
20435
20473
  node.on("dragmove", (0, import_lodash.throttle)(handleDragMove, DEFAULT_THROTTLE_MS));
20474
+ node.dragBoundFunc((pos) => {
20475
+ if (!startPosition) return pos;
20476
+ if (!isShiftPressed) return pos;
20477
+ const dx = pos.x - startPosition.x;
20478
+ const dy = pos.y - startPosition.y;
20479
+ if (!lockedAxis) {
20480
+ const axisLockThreshold = this.instance.getConfiguration().behaviors.axisLockThreshold;
20481
+ if (Math.abs(dx) < axisLockThreshold && Math.abs(dy) < axisLockThreshold) return pos;
20482
+ lockedAxis = Math.abs(dx) > Math.abs(dy) ? "x" : "y";
20483
+ }
20484
+ if (lockedAxis === "x") return {
20485
+ x: pos.x,
20486
+ y: startPosition.y
20487
+ };
20488
+ else return {
20489
+ x: startPosition.x,
20490
+ y: pos.y
20491
+ };
20492
+ });
20436
20493
  node.on("dragend", (e) => {
20437
20494
  const nodeTarget = e.target;
20495
+ startPosition = null;
20496
+ lockedAxis = null;
20497
+ isShiftPressed = false;
20438
20498
  if (this.getSelectionPlugin()?.getSelectedNodes().length === 1) {
20439
20499
  this.instance.releaseMutexLock();
20440
20500
  this.getNodesSelectionFeedbackPlugin()?.showSelectionHalo(nodeTarget);
@@ -20498,12 +20558,14 @@ var WeaveNode = class {
20498
20558
  realNodeTarget.setAttrs({ isCloneOrigin: void 0 });
20499
20559
  originalPosition = realNodeTarget.getAbsolutePosition();
20500
20560
  });
20501
- node.handleMouseover = () => {
20502
- this.handleMouseOver(node);
20503
- };
20504
- node.handleMouseout = () => {
20505
- this.handleMouseout(node);
20506
- };
20561
+ if (!node.getAttrs().overridesMouseControl) {
20562
+ node.handleMouseover = () => {
20563
+ this.handleMouseOver(node);
20564
+ };
20565
+ node.handleMouseout = () => {
20566
+ this.handleMouseout(node);
20567
+ };
20568
+ }
20507
20569
  node.handleSelectNode = () => {
20508
20570
  this.getNodesSelectionFeedbackPlugin()?.createSelectionHalo(node);
20509
20571
  };
@@ -20525,6 +20587,7 @@ var WeaveNode = class {
20525
20587
  }
20526
20588
  handleMouseOver(node) {
20527
20589
  const stage = this.instance.getStage();
20590
+ if (stage?.isCmdCtrlPressed?.()) return false;
20528
20591
  const user = this.instance.getStore().getUser();
20529
20592
  const activeAction = this.instance.getActiveAction();
20530
20593
  const isNodeSelectionEnabled = this.getSelectionPlugin()?.isEnabled();
@@ -20559,6 +20622,8 @@ var WeaveNode = class {
20559
20622
  return cancelBubble;
20560
20623
  }
20561
20624
  handleMouseout(node) {
20625
+ const stage = this.instance.getStage();
20626
+ if (stage?.isCmdCtrlPressed?.()) return;
20562
20627
  const realNode = this.instance.getInstanceRecursive(node);
20563
20628
  if (realNode) this.hideHoverState();
20564
20629
  }
@@ -20583,9 +20648,12 @@ var WeaveNode = class {
20583
20648
  serialize(instance) {
20584
20649
  const attrs = instance.getAttrs();
20585
20650
  const cleanedAttrs = { ...attrs };
20651
+ delete cleanedAttrs.isSelected;
20586
20652
  delete cleanedAttrs.mutexLocked;
20587
20653
  delete cleanedAttrs.mutexUserId;
20588
20654
  delete cleanedAttrs.draggable;
20655
+ delete cleanedAttrs.overridesMouseControl;
20656
+ delete cleanedAttrs.dragBoundFunc;
20589
20657
  return {
20590
20658
  key: attrs.id ?? "",
20591
20659
  type: attrs.nodeType,
@@ -20736,6 +20804,12 @@ var WeaveAction = class {
20736
20804
  getName() {
20737
20805
  return this.name;
20738
20806
  }
20807
+ hasAliases() {
20808
+ return false;
20809
+ }
20810
+ getAliases() {
20811
+ return [];
20812
+ }
20739
20813
  getLogger() {
20740
20814
  return this.logger;
20741
20815
  }
@@ -22081,12 +22155,23 @@ var WeaveRegisterManager = class {
22081
22155
  }
22082
22156
  action.register(this.instance);
22083
22157
  this.actionsHandlers[actionName] = action;
22158
+ if (action.hasAliases()) {
22159
+ const aliases = action.getAliases();
22160
+ for (const alias of aliases) {
22161
+ if (this.actionsHandlers[alias]) {
22162
+ const msg = `Action handler with name [${alias}] already exists`;
22163
+ this.logger.error(msg);
22164
+ throw new Error(msg);
22165
+ }
22166
+ this.actionsHandlers[alias] = action;
22167
+ }
22168
+ }
22084
22169
  }
22085
22170
  };
22086
22171
 
22087
22172
  //#endregion
22088
22173
  //#region package.json
22089
- var version = "2.20.2";
22174
+ var version = "2.21.1";
22090
22175
 
22091
22176
  //#endregion
22092
22177
  //#region src/managers/setup.ts
@@ -22944,7 +23029,7 @@ var Weave = class {
22944
23029
  Konva.showWarnings = false;
22945
23030
  this.id = v4_default();
22946
23031
  this.initialized = false;
22947
- this.config = mergeExceptArrays({}, weaveConfig);
23032
+ this.config = mergeExceptArrays(WEAVE_DEFAULT_CONFIG, weaveConfig);
22948
23033
  this.logger = new WeaveLogger(this, this.config?.logger ?? {
22949
23034
  disabled: false,
22950
23035
  level: "error"
@@ -23682,6 +23767,8 @@ var WeaveStageNode = class extends WeaveNode {
23682
23767
  nodeType = WEAVE_STAGE_NODE_TYPE;
23683
23768
  stageFocused = false;
23684
23769
  wheelMousePressed = false;
23770
+ isCmdCtrlPressed = false;
23771
+ globalEventsInitialized = false;
23685
23772
  onRender(props) {
23686
23773
  const stage = new Konva.Stage({ ...props });
23687
23774
  setupUpscaleStage(this.instance, stage);
@@ -23752,9 +23839,38 @@ var WeaveStageNode = class extends WeaveNode {
23752
23839
  this.hideHoverState();
23753
23840
  if (!this.instance.isServerSide()) stage.container().style.cursor = "default";
23754
23841
  });
23842
+ stage.isCmdCtrlPressed = () => this.isCmdCtrlPressed;
23843
+ this.setupEvents();
23755
23844
  return stage;
23756
23845
  }
23757
23846
  onUpdate() {}
23847
+ setupEvents() {
23848
+ if (this.globalEventsInitialized) return;
23849
+ if (this.instance.isServerSide()) return;
23850
+ window.addEventListener("keydown", (e) => {
23851
+ if (e.ctrlKey || e.metaKey) {
23852
+ this.isCmdCtrlPressed = true;
23853
+ this.instance.getStage().container().style.cursor = "default";
23854
+ const transformer = this.getSelectionPlugin()?.getTransformer();
23855
+ if (!transformer) return;
23856
+ if (transformer.nodes().length === 0 || transformer.nodes().length > 1) return;
23857
+ const selectedNode = transformer.nodes()[0];
23858
+ selectedNode.fire("onCmdCtrlPressed");
23859
+ }
23860
+ });
23861
+ window.addEventListener("keyup", (e) => {
23862
+ if (!e.ctrlKey && !e.metaKey) {
23863
+ this.isCmdCtrlPressed = false;
23864
+ this.instance.getStage().container().style.cursor = "default";
23865
+ const transformer = this.getSelectionPlugin()?.getTransformer();
23866
+ if (!transformer) return;
23867
+ if (transformer.nodes().length === 0 || transformer.nodes().length > 1) return;
23868
+ const selectedNode = transformer.nodes()[0];
23869
+ selectedNode.fire("onCmdCtrlReleased");
23870
+ }
23871
+ });
23872
+ this.globalEventsInitialized = true;
23873
+ }
23758
23874
  };
23759
23875
 
23760
23876
  //#endregion
@@ -23788,6 +23904,8 @@ var WeaveLayerNode = class extends WeaveNode {
23788
23904
  delete cleanedAttrs.mutexLocked;
23789
23905
  delete cleanedAttrs.mutexUserId;
23790
23906
  delete cleanedAttrs.draggable;
23907
+ delete cleanedAttrs.overridesMouseControl;
23908
+ delete cleanedAttrs.dragBoundFunc;
23791
23909
  return {
23792
23910
  key: attrs.id ?? "",
23793
23911
  type: attrs.nodeType,
@@ -23869,6 +23987,8 @@ var WeaveGroupNode = class extends WeaveNode {
23869
23987
  delete cleanedAttrs.mutexLocked;
23870
23988
  delete cleanedAttrs.mutexUserId;
23871
23989
  delete cleanedAttrs.draggable;
23990
+ delete cleanedAttrs.overridesMouseControl;
23991
+ delete cleanedAttrs.dragBoundFunc;
23872
23992
  return {
23873
23993
  key: attrs.id ?? "",
23874
23994
  type: attrs.nodeType,
@@ -24124,17 +24244,12 @@ var WeaveLineNode = class extends WeaveNode {
24124
24244
  originalEndHandleVisibility = null;
24125
24245
  });
24126
24246
  line.allowedAnchors = function() {
24127
- if (this.points().length !== 4) return [
24247
+ return [
24128
24248
  "top-left",
24129
- "top-center",
24130
24249
  "top-right",
24131
- "middle-right",
24132
- "middle-left",
24133
24250
  "bottom-left",
24134
- "bottom-center",
24135
24251
  "bottom-right"
24136
24252
  ];
24137
- return [];
24138
24253
  };
24139
24254
  this.setupDefaultNodeEvents(line);
24140
24255
  if (!this.handleZoomChanges) {
@@ -24564,6 +24679,8 @@ var WeaveTextNode = class extends WeaveNode {
24564
24679
  delete cleanedAttrs.triggerEditMode;
24565
24680
  delete cleanedAttrs.cancelEditMode;
24566
24681
  delete cleanedAttrs.measureMultilineText;
24682
+ delete cleanedAttrs.overridesMouseControl;
24683
+ delete cleanedAttrs.dragBoundFunc;
24567
24684
  return {
24568
24685
  key: attrs.id ?? "",
24569
24686
  type: attrs.nodeType,
@@ -24922,8 +25039,59 @@ var WeaveTextNode = class extends WeaveNode {
24922
25039
  }
24923
25040
  };
24924
25041
 
25042
+ //#endregion
25043
+ //#region src/nodes/image/constants.ts
25044
+ const WEAVE_IMAGE_NODE_TYPE = "image";
25045
+ const WEAVE_IMAGE_CROP_END_TYPE = {
25046
+ ["ACCEPT"]: "accept",
25047
+ ["CANCEL"]: "cancel"
25048
+ };
25049
+ const WEAVE_IMAGE_CROP_ANCHOR_POSITION = {
25050
+ ["TOP_LEFT"]: "top-left",
25051
+ ["TOP_RIGHT"]: "top-right",
25052
+ ["BOTTOM_LEFT"]: "bottom-left",
25053
+ ["BOTTOM_RIGHT"]: "bottom-right",
25054
+ ["TOP_CENTER"]: "top-center",
25055
+ ["MIDDLE_LEFT"]: "middle-left",
25056
+ ["MIDDLE_RIGHT"]: "middle-right",
25057
+ ["BOTTOM_CENTER"]: "bottom-center"
25058
+ };
25059
+ const WEAVE_IMAGE_DEFAULT_CONFIG = {
25060
+ performance: { cache: { enabled: false } },
25061
+ crossOrigin: "anonymous",
25062
+ cropMode: {
25063
+ gridLines: { enabled: true },
25064
+ overlay: { fill: "rgba(0,0,0,0.2)" },
25065
+ selection: {
25066
+ enabledAnchors: [
25067
+ "top-left",
25068
+ "top-center",
25069
+ "top-right",
25070
+ "middle-right",
25071
+ "middle-left",
25072
+ "bottom-left",
25073
+ "bottom-center",
25074
+ "bottom-right"
25075
+ ],
25076
+ borderStroke: "#1a1aff",
25077
+ borderStrokeWidth: 2,
25078
+ anchorStyleFunc: (anchor) => {
25079
+ anchor.width(12);
25080
+ anchor.height(12);
25081
+ anchor.offsetX(6);
25082
+ anchor.offsetY(6);
25083
+ anchor.fill("white");
25084
+ anchor.stroke("black");
25085
+ anchor.strokeWidth(1);
25086
+ anchor.cornerRadius(0);
25087
+ }
25088
+ }
25089
+ }
25090
+ };
25091
+
24925
25092
  //#endregion
24926
25093
  //#region src/nodes/image/crop.ts
25094
+ const SNAP = 8;
24927
25095
  var WeaveImageCrop = class WeaveImageCrop {
24928
25096
  constructor(instance, node, image, internalImage, clipGroup) {
24929
25097
  this.instance = instance;
@@ -24931,13 +25099,11 @@ var WeaveImageCrop = class WeaveImageCrop {
24931
25099
  this.image = image;
24932
25100
  this.internalImage = internalImage;
24933
25101
  this.cropGroup = clipGroup;
24934
- this.cropping = false;
24935
25102
  this.onClose = () => {};
24936
25103
  this.handleHide = this.hide.bind(this);
24937
25104
  }
24938
- show(onClose) {
25105
+ show(onClose, options) {
24939
25106
  this.onClose = onClose;
24940
- this.cropping = true;
24941
25107
  const nodeEdgeSnappingPlugin = this.getNodesEdgeSnappingPlugin();
24942
25108
  if (nodeEdgeSnappingPlugin) nodeEdgeSnappingPlugin.disable();
24943
25109
  const nodeDistanceSnappingPlugin = this.getNodesDistanceSnappingPlugin();
@@ -24946,6 +25112,7 @@ var WeaveImageCrop = class WeaveImageCrop {
24946
25112
  if (nodesSelectionPlugin) nodesSelectionPlugin.disable();
24947
25113
  this.node.clearCache(this.image);
24948
25114
  this.image.setAttrs({ cropping: true });
25115
+ this.image.listening(false);
24949
25116
  const imageAttrs = this.image.getAttrs();
24950
25117
  this.internalImage.hide();
24951
25118
  this.cropGroup.destroyChildren();
@@ -24967,16 +25134,17 @@ var WeaveImageCrop = class WeaveImageCrop {
24967
25134
  });
24968
25135
  this.imageOffsetX = imageAttrs.cropInfo ? imageAttrs.cropInfo.x * realScale : 0;
24969
25136
  this.imageOffsetY = imageAttrs.cropInfo ? imageAttrs.cropInfo.y * realScale : 0;
25137
+ const cropModeConfiguration = this.node.getConfiguration().cropMode;
24970
25138
  this.cropRect = new Konva.Rect({
24971
25139
  x: 0,
24972
25140
  y: 0,
24973
25141
  width: imageAttrs.cropInfo ? imageAttrs.cropInfo.width * realScale : imageAttrs.uncroppedImage.width,
24974
25142
  height: imageAttrs.cropInfo ? imageAttrs.cropInfo.height * realScale : imageAttrs.uncroppedImage.height,
24975
- fill: "rgba(0,0,0,0.2)",
24976
- stroke: "#ff0000ff",
25143
+ fill: cropModeConfiguration.overlay.fill,
25144
+ stroke: "transparent",
24977
25145
  strokeWidth: 0,
24978
- strokeScaleEnabled: true,
24979
- draggable: true,
25146
+ strokeScaleEnabled: false,
25147
+ draggable: !(options?.cmdCtrl?.triggered ?? false),
24980
25148
  rotation: 0
24981
25149
  });
24982
25150
  this.transformer = new Konva.Transformer({
@@ -24987,6 +25155,14 @@ var WeaveImageCrop = class WeaveImageCrop {
24987
25155
  keepRatio: false,
24988
25156
  ignoreStroke: false,
24989
25157
  rotateEnabled: false,
25158
+ borderStroke: cropModeConfiguration.selection.borderStroke,
25159
+ borderStrokeWidth: cropModeConfiguration.selection.borderStrokeWidth,
25160
+ anchorStyleFunc: (anchor) => {
25161
+ const tokens = anchor.name().split(" ");
25162
+ const position = tokens[0];
25163
+ cropModeConfiguration.selection.anchorStyleFunc(anchor, position);
25164
+ },
25165
+ anchorStroke: "black",
24990
25166
  enabledAnchors: [
24991
25167
  "top-left",
24992
25168
  "top-center",
@@ -25050,39 +25226,40 @@ var WeaveImageCrop = class WeaveImageCrop {
25050
25226
  },
25051
25227
  rotation: 0
25052
25228
  });
25053
- this.grid = new Konva.Group();
25229
+ this.grid = new Konva.Group({
25230
+ listening: false,
25231
+ draggable: false
25232
+ });
25054
25233
  const cropRect = this.cropRect.getClientRect({
25055
25234
  relativeTo: this.cropGroup,
25056
25235
  skipStroke: true
25057
25236
  });
25058
- this.drawGridLines(0, 0, cropRect.width, cropRect.height);
25059
- const handleGridLines = () => {
25237
+ this.drawGrid(0, 0, cropRect.width, cropRect.height);
25238
+ const handleGrid = () => {
25060
25239
  const cropRect$1 = this.cropRect.getClientRect({
25061
25240
  relativeTo: this.cropGroup,
25062
25241
  skipStroke: true
25063
25242
  });
25064
- this.drawGridLines(cropRect$1.x, cropRect$1.y, cropRect$1.width, cropRect$1.height);
25243
+ this.drawGrid(cropRect$1.x, cropRect$1.y, cropRect$1.width, cropRect$1.height);
25065
25244
  };
25066
- this.instance.getStage().on("pointerdown", (e) => {
25067
- if (!this.cropping) return;
25068
- const isStage = e.target instanceof Konva.Stage;
25069
- const isContainerEmptyArea = typeof e.target.getAttrs().isContainerPrincipal !== "undefined" && !e.target.getAttrs().isContainerPrincipal;
25070
- if (isStage || isContainerEmptyArea) this.cancel();
25071
- });
25072
25245
  this.instance.addEventListener("onActiveActionChange", (activeAction) => {
25073
25246
  if (typeof activeAction !== "undefined") this.cancel();
25074
25247
  });
25075
25248
  this.cropRect.on("dragstart", (e) => {
25076
25249
  this.instance.emitEvent("onDrag", e.target);
25077
25250
  });
25078
- this.cropRect.on("dragmove", handleGridLines);
25251
+ this.cropRect.on("dragmove", () => {
25252
+ handleGrid();
25253
+ });
25079
25254
  this.cropRect.on("dragend", () => {
25080
25255
  this.instance.emitEvent("onDrag", null);
25081
25256
  });
25082
25257
  this.cropRect.on("transformstart", (e) => {
25083
25258
  this.instance.emitEvent("onTransform", e.target);
25084
25259
  });
25085
- this.cropRect.on("transform", handleGridLines);
25260
+ this.cropRect.on("transform", () => {
25261
+ handleGrid();
25262
+ });
25086
25263
  this.cropRect.on("transformend", () => {
25087
25264
  this.instance.emitEvent("onTransform", null);
25088
25265
  });
@@ -25092,9 +25269,156 @@ var WeaveImageCrop = class WeaveImageCrop {
25092
25269
  this.cropGroup.add(this.grid);
25093
25270
  const utilityLayer = this.instance.getUtilityLayer();
25094
25271
  utilityLayer?.add(this.transformer);
25095
- this.transformer.forceUpdate();
25272
+ this.transformer?.forceUpdate();
25096
25273
  this.cropGroup.show();
25097
- this.instance.getStage().container().addEventListener("keydown", this.handleHide);
25274
+ window.addEventListener("keydown", this.handleHide);
25275
+ if (options.cmdCtrl.triggered) {
25276
+ utilityLayer?.hide();
25277
+ const stage = this.instance.getStage();
25278
+ let resizing = false;
25279
+ let fixedCorner = {
25280
+ x: 0,
25281
+ y: 0
25282
+ };
25283
+ const limits = {
25284
+ top: this.cropImage.y(),
25285
+ right: this.cropImage.x() + this.cropImage.width(),
25286
+ bottom: this.cropImage.y() + this.cropImage.height(),
25287
+ left: this.cropImage.x()
25288
+ };
25289
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT) fixedCorner = {
25290
+ x: this.cropRect.x() + this.cropRect.width(),
25291
+ y: this.cropRect.y() + this.cropRect.height()
25292
+ };
25293
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) fixedCorner = {
25294
+ x: this.cropRect.x(),
25295
+ y: this.cropRect.y() + this.cropRect.height()
25296
+ };
25297
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT) fixedCorner = {
25298
+ x: this.cropRect.x() + this.cropRect.width(),
25299
+ y: this.cropRect.y()
25300
+ };
25301
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) fixedCorner = {
25302
+ x: this.cropRect.x(),
25303
+ y: this.cropRect.y()
25304
+ };
25305
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER) fixedCorner = {
25306
+ x: this.cropRect.x() + this.cropRect.width(),
25307
+ y: this.cropRect.y() + this.cropRect.height()
25308
+ };
25309
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT) fixedCorner = {
25310
+ x: this.cropRect.x(),
25311
+ y: this.cropRect.y() + this.cropRect.height() / 2
25312
+ };
25313
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) fixedCorner = {
25314
+ x: this.cropRect.x(),
25315
+ y: this.cropRect.y()
25316
+ };
25317
+ if (options.cmdCtrl.corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) fixedCorner = {
25318
+ x: this.cropRect.x() + this.cropRect.width(),
25319
+ y: this.cropRect.y() + this.cropRect.height() / 2
25320
+ };
25321
+ this.drawSquarePointer(options.cmdCtrl.corner, fixedCorner, limits);
25322
+ resizing = true;
25323
+ stage.on("pointermove", () => {
25324
+ if (!resizing) return;
25325
+ if (options.cmdCtrl.triggered) {
25326
+ this.drawSquarePointer(options.cmdCtrl.corner, fixedCorner, limits);
25327
+ handleGrid();
25328
+ }
25329
+ });
25330
+ stage.on("pointerup", () => {
25331
+ if (!resizing) return;
25332
+ resizing = false;
25333
+ this.hide({ code: "Enter" });
25334
+ });
25335
+ } else utilityLayer?.show();
25336
+ }
25337
+ createSoftSnap(snapTo, snapDistance = 8) {
25338
+ let snapped = false;
25339
+ return function(value) {
25340
+ const dist = Math.abs(value - snapTo);
25341
+ if (!snapped && dist < snapDistance) {
25342
+ snapped = true;
25343
+ return snapTo;
25344
+ }
25345
+ if (snapped && dist > snapDistance * 1.5) snapped = false;
25346
+ return snapped ? snapTo : value;
25347
+ };
25348
+ }
25349
+ drawSquarePointer(corner, fixedCorner, limits) {
25350
+ const stage = this.instance.getStage();
25351
+ const pointer = stage.getPointerPosition();
25352
+ if (!pointer) return;
25353
+ const local = this.cropGroup.getAbsoluteTransform().copy().invert().point(pointer);
25354
+ const newPos = {
25355
+ x: local.x,
25356
+ y: local.y
25357
+ };
25358
+ let newWidth = this.cropRect.width();
25359
+ let newHeight = this.cropRect.height();
25360
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT) {
25361
+ newWidth = fixedCorner.x - local.x;
25362
+ newHeight = fixedCorner.y - local.y;
25363
+ newPos.x = local.x;
25364
+ newPos.y = local.y;
25365
+ }
25366
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) {
25367
+ newWidth = local.x - fixedCorner.x;
25368
+ newHeight = fixedCorner.y - local.y;
25369
+ newPos.x = fixedCorner.x;
25370
+ newPos.y = local.y;
25371
+ }
25372
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT) {
25373
+ newWidth = fixedCorner.x - local.x;
25374
+ newHeight = local.y - fixedCorner.y;
25375
+ newPos.x = local.x;
25376
+ newPos.y = fixedCorner.y;
25377
+ }
25378
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) {
25379
+ newWidth = local.x - fixedCorner.x;
25380
+ newHeight = local.y - fixedCorner.y;
25381
+ newPos.x = fixedCorner.x;
25382
+ newPos.y = fixedCorner.y;
25383
+ }
25384
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER) {
25385
+ newWidth = this.cropRect.width();
25386
+ newHeight = fixedCorner.y - local.y;
25387
+ newPos.x = this.cropRect.x();
25388
+ newPos.y = local.y;
25389
+ }
25390
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT) {
25391
+ newWidth = local.x - fixedCorner.x;
25392
+ newHeight = this.cropRect.height();
25393
+ newPos.x = this.cropRect.x();
25394
+ newPos.y = this.cropRect.y();
25395
+ }
25396
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) {
25397
+ newWidth = this.cropRect.width();
25398
+ newHeight = local.y - fixedCorner.y;
25399
+ newPos.x = this.cropRect.x();
25400
+ newPos.y = this.cropRect.y();
25401
+ }
25402
+ if (corner === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) {
25403
+ newWidth = fixedCorner.x - local.x;
25404
+ newHeight = this.cropRect.height();
25405
+ newPos.x = local.x;
25406
+ newPos.y = this.cropRect.y();
25407
+ }
25408
+ newPos.x = this.createSoftSnap(limits.left, SNAP)(newPos.x);
25409
+ newPos.x = this.createSoftSnap(limits.right, SNAP)(newPos.x);
25410
+ newPos.y = this.createSoftSnap(limits.top, SNAP)(newPos.y);
25411
+ newPos.y = this.createSoftSnap(limits.bottom, SNAP)(newPos.y);
25412
+ newWidth = this.createSoftSnap(limits.left, SNAP)(newWidth);
25413
+ newWidth = this.createSoftSnap(limits.right, SNAP)(newWidth);
25414
+ newHeight = this.createSoftSnap(limits.top, SNAP)(newHeight);
25415
+ newHeight = this.createSoftSnap(limits.bottom, SNAP)(newHeight);
25416
+ this.cropRect.setAttrs({
25417
+ x: newPos.x,
25418
+ y: newPos.y,
25419
+ width: newWidth,
25420
+ height: newHeight
25421
+ });
25098
25422
  }
25099
25423
  accept() {
25100
25424
  this.hide({ code: "Enter" });
@@ -25104,14 +25428,18 @@ var WeaveImageCrop = class WeaveImageCrop {
25104
25428
  }
25105
25429
  hide(e) {
25106
25430
  if (!["Enter", "Escape"].includes(e.code)) return;
25107
- this.cropping = false;
25108
25431
  this.image.setAttrs({ cropping: false });
25432
+ this.image.listening(true);
25109
25433
  if (e.code === "Enter") this.handleClipEnd();
25110
25434
  const stage = this.instance.getStage();
25111
25435
  this.onClose();
25112
25436
  const utilityLayer = this.instance.getUtilityLayer();
25113
25437
  utilityLayer?.destroyChildren();
25114
- this.instance.getStage().container().removeEventListener("keydown", this.handleHide);
25438
+ if (stage.isCmdCtrlPressed() && utilityLayer) {
25439
+ this.node.renderCropMode(utilityLayer, this.image);
25440
+ utilityLayer.show();
25441
+ }
25442
+ window.removeEventListener("keydown", this.handleHide);
25115
25443
  this.cropGroup.destroyChildren();
25116
25444
  this.cropGroup.hide();
25117
25445
  const nodesEdgeSnappingPlugin = this.getNodesEdgeSnappingPlugin();
@@ -25126,36 +25454,56 @@ var WeaveImageCrop = class WeaveImageCrop {
25126
25454
  this.node.cacheNode(this.image);
25127
25455
  this.instance.emitEvent("onImageCropEnd", { instance: this.image });
25128
25456
  }
25129
- drawGridLines(x, y, width, height) {
25457
+ drawGrid(x, y, width, height) {
25130
25458
  if (!this.image.getAttrs().cropping) return;
25131
25459
  this.grid.destroyChildren();
25132
- const stepX = width / 3;
25133
- const stepY = height / 3;
25134
- for (let i = 1; i <= 2; i++) {
25135
- const vLine = new Konva.Line({
25136
- points: [
25137
- x + stepX * i,
25138
- y,
25139
- x + stepX * i,
25140
- y + height
25141
- ],
25142
- stroke: "#0074ffcc",
25143
- strokeWidth: 1,
25144
- strokeScaleEnabled: false
25145
- });
25146
- const hLine = new Konva.Line({
25147
- points: [
25148
- x,
25149
- y + stepY * i,
25150
- x + width,
25151
- y + stepY * i
25152
- ],
25153
- stroke: "#0074ffcc",
25154
- strokeWidth: 1,
25155
- strokeScaleEnabled: false
25156
- });
25157
- this.grid.add(vLine, hLine);
25460
+ const cropModeConfiguration = this.node.getConfiguration().cropMode;
25461
+ if (cropModeConfiguration.gridLines.enabled) {
25462
+ const stepX = width / 3;
25463
+ const stepY = height / 3;
25464
+ for (let i = 1; i <= 2; i++) {
25465
+ const vLine = new Konva.Line({
25466
+ points: [
25467
+ x + stepX * i,
25468
+ y,
25469
+ x + stepX * i,
25470
+ y + height
25471
+ ],
25472
+ stroke: "#1a1aff",
25473
+ strokeWidth: 1,
25474
+ strokeScaleEnabled: false,
25475
+ listening: false,
25476
+ draggable: false
25477
+ });
25478
+ const hLine = new Konva.Line({
25479
+ points: [
25480
+ x,
25481
+ y + stepY * i,
25482
+ x + width,
25483
+ y + stepY * i
25484
+ ],
25485
+ stroke: "#1a1aff",
25486
+ strokeWidth: 1,
25487
+ strokeScaleEnabled: false,
25488
+ listening: false,
25489
+ draggable: false
25490
+ });
25491
+ this.grid.add(vLine, hLine);
25492
+ }
25158
25493
  }
25494
+ const border = new Konva.Rect({
25495
+ x,
25496
+ y,
25497
+ width,
25498
+ height,
25499
+ stroke: cropModeConfiguration.selection.borderStroke,
25500
+ strokeWidth: cropModeConfiguration.selection.borderStrokeWidth,
25501
+ strokeScaleEnabled: false,
25502
+ listening: false,
25503
+ draggable: false
25504
+ });
25505
+ this.grid.add(border);
25506
+ this.transformer?.forceUpdate();
25159
25507
  }
25160
25508
  unCrop() {
25161
25509
  const imageAttrs = this.image.getAttrs();
@@ -25275,18 +25623,6 @@ var WeaveImageCrop = class WeaveImageCrop {
25275
25623
  }
25276
25624
  };
25277
25625
 
25278
- //#endregion
25279
- //#region src/nodes/image/constants.ts
25280
- const WEAVE_IMAGE_NODE_TYPE = "image";
25281
- const WEAVE_IMAGE_CROP_END_TYPE = {
25282
- ["ACCEPT"]: "accept",
25283
- ["CANCEL"]: "cancel"
25284
- };
25285
- const WEAVE_IMAGE_DEFAULT_CONFIG = {
25286
- performance: { cache: { enabled: false } },
25287
- crossOrigin: "anonymous"
25288
- };
25289
-
25290
25626
  //#endregion
25291
25627
  //#region src/nodes/image/image.ts
25292
25628
  var WeaveImageNode = class extends WeaveNode {
@@ -25306,13 +25642,16 @@ var WeaveImageNode = class extends WeaveNode {
25306
25642
  this.config = mergeExceptArrays(WEAVE_IMAGE_DEFAULT_CONFIG, config);
25307
25643
  this.imageCrop = null;
25308
25644
  }
25645
+ getConfiguration() {
25646
+ return this.config;
25647
+ }
25309
25648
  onRegister() {
25310
25649
  this.logger.info(`image caching enabled: ${this.config.performance.cache.enabled}`);
25311
25650
  }
25312
- triggerCrop(imageNode) {
25651
+ triggerCrop(imageNode, options) {
25313
25652
  const stage = this.instance.getStage();
25314
25653
  if (imageNode.getAttrs().cropping ?? false) return;
25315
- if (!(this.isSelecting() && this.isNodeSelected(imageNode))) return;
25654
+ if (!(this.isSelecting() && this.isNodeSelected(imageNode)) && !options.cmdCtrl.triggered) return;
25316
25655
  const lockAcquired = this.instance.setMutexLock({
25317
25656
  nodeIds: [imageNode.id()],
25318
25657
  operation: "image-crop"
@@ -25328,8 +25667,11 @@ var WeaveImageNode = class extends WeaveNode {
25328
25667
  stage.mode(WEAVE_STAGE_DEFAULT_MODE);
25329
25668
  this.instance.emitEvent("onImageCropEnd", { instance: image });
25330
25669
  this.imageCrop = null;
25670
+ }, options);
25671
+ this.instance.emitEvent("onImageCropStart", {
25672
+ instance: image,
25673
+ cmdCtrlTriggered: options.cmdCtrl.triggered
25331
25674
  });
25332
- this.instance.emitEvent("onImageCropStart", { instance: image });
25333
25675
  }
25334
25676
  closeCrop = (imageNode, type) => {
25335
25677
  if (!this.imageCrop) return;
@@ -25375,7 +25717,8 @@ var WeaveImageNode = class extends WeaveNode {
25375
25717
  id,
25376
25718
  name: "node",
25377
25719
  loadedImage: false,
25378
- loadedImageError: false
25720
+ loadedImageError: false,
25721
+ cropping: false
25379
25722
  });
25380
25723
  this.setupDefaultNodeAugmentation(image);
25381
25724
  image.movedToContainer = () => {
@@ -25384,7 +25727,7 @@ var WeaveImageNode = class extends WeaveNode {
25384
25727
  if (!image$1) return;
25385
25728
  };
25386
25729
  image.triggerCrop = () => {
25387
- this.triggerCrop(image);
25730
+ this.triggerCrop(image, { cmdCtrl: { triggered: false } });
25388
25731
  };
25389
25732
  image.closeCrop = (type) => {
25390
25733
  this.closeCrop(image, type);
@@ -25493,6 +25836,32 @@ var WeaveImageNode = class extends WeaveNode {
25493
25836
  if (this.imageCrop) this.closeCrop(image, WEAVE_IMAGE_CROP_END_TYPE.CANCEL);
25494
25837
  }
25495
25838
  });
25839
+ image.on("onCmdCtrlPressed", () => {
25840
+ const transformer = this.getSelectionPlugin()?.getTransformer();
25841
+ if (!transformer) return;
25842
+ transformer.hide();
25843
+ const utilityLayer = this.instance.getUtilityLayer();
25844
+ if (!utilityLayer) return;
25845
+ utilityLayer?.destroyChildren();
25846
+ this.renderCropMode(utilityLayer, image);
25847
+ utilityLayer?.show();
25848
+ });
25849
+ image.on("onCmdCtrlReleased", () => {
25850
+ const transformer = this.getSelectionPlugin()?.getTransformer();
25851
+ if (!transformer) return;
25852
+ transformer.show();
25853
+ const utilityLayer = this.instance.getUtilityLayer();
25854
+ if (!utilityLayer) return;
25855
+ utilityLayer?.destroyChildren();
25856
+ });
25857
+ image.on("onSelectionCleared", () => {
25858
+ const transformer = this.getSelectionPlugin()?.getTransformer();
25859
+ if (!transformer) return;
25860
+ transformer.show();
25861
+ const utilityLayer = this.instance.getUtilityLayer();
25862
+ if (!utilityLayer) return;
25863
+ utilityLayer?.destroyChildren();
25864
+ });
25496
25865
  return image;
25497
25866
  }
25498
25867
  clearCache(nodeInstance) {
@@ -25504,6 +25873,164 @@ var WeaveImageNode = class extends WeaveNode {
25504
25873
  nodeInstance.cache({ pixelRatio: this.config.performance.cache.pixelRatio });
25505
25874
  }
25506
25875
  }
25876
+ renderCropBorder(layer, node) {
25877
+ const stage = this.instance.getStage();
25878
+ const stageScale = stage.scaleX();
25879
+ const transform = node.getAbsoluteTransform().copy();
25880
+ const w = node.width();
25881
+ const h = node.height();
25882
+ const offsetX = node.offsetX();
25883
+ const offsetY = node.offsetY();
25884
+ const localCorners = [
25885
+ {
25886
+ x: 0,
25887
+ y: 0
25888
+ },
25889
+ {
25890
+ x: w,
25891
+ y: 0
25892
+ },
25893
+ {
25894
+ x: w,
25895
+ y: h
25896
+ },
25897
+ {
25898
+ x: 0,
25899
+ y: h
25900
+ }
25901
+ ];
25902
+ const absoluteCorners = localCorners.map((p) => transform.point({
25903
+ x: p.x - offsetX,
25904
+ y: p.y - offsetY
25905
+ }));
25906
+ const rect = new Konva.Rect({
25907
+ width: absoluteCorners[1].x - absoluteCorners[0].x,
25908
+ height: absoluteCorners[2].y - absoluteCorners[0].y,
25909
+ fill: "transparent",
25910
+ strokeWidth: 2,
25911
+ stroke: "#1a1aff",
25912
+ draggable: false,
25913
+ listening: false,
25914
+ rotation: node.rotation()
25915
+ });
25916
+ layer.add(rect);
25917
+ rect.setAbsolutePosition(absoluteCorners[0]);
25918
+ rect.scale({
25919
+ x: 1 / stageScale,
25920
+ y: 1 / stageScale
25921
+ });
25922
+ stage.on("scaleXChange scaleYChange", () => {
25923
+ const scale = stage.scaleX();
25924
+ rect.scale({
25925
+ x: 1 / scale,
25926
+ y: 1 / scale
25927
+ });
25928
+ });
25929
+ }
25930
+ renderCropAnchor(position, node, layer, onClick) {
25931
+ const transform = node.getAbsoluteTransform().copy();
25932
+ const stage = this.instance.getStage();
25933
+ const stageScale = stage.scaleX();
25934
+ const w = node.width();
25935
+ const h = node.height();
25936
+ const offsetX = node.offsetX();
25937
+ const offsetY = node.offsetY();
25938
+ const localCorners = [
25939
+ {
25940
+ x: 0,
25941
+ y: 0
25942
+ },
25943
+ {
25944
+ x: w,
25945
+ y: 0
25946
+ },
25947
+ {
25948
+ x: w,
25949
+ y: h
25950
+ },
25951
+ {
25952
+ x: 0,
25953
+ y: h
25954
+ },
25955
+ {
25956
+ x: w / 2,
25957
+ y: 0
25958
+ },
25959
+ {
25960
+ x: w,
25961
+ y: h / 2
25962
+ },
25963
+ {
25964
+ x: 0,
25965
+ y: h / 2
25966
+ },
25967
+ {
25968
+ x: w / 2,
25969
+ y: h
25970
+ }
25971
+ ];
25972
+ const absoluteCorners = localCorners.map((p) => transform.point({
25973
+ x: p.x - offsetX,
25974
+ y: p.y - offsetY
25975
+ }));
25976
+ const anchor = new Konva.Rect({
25977
+ draggable: false,
25978
+ rotation: node.rotation()
25979
+ });
25980
+ this.config.cropMode.selection.anchorStyleFunc(anchor, position);
25981
+ layer.add(anchor);
25982
+ anchor.scale({
25983
+ x: 1 / stageScale,
25984
+ y: 1 / stageScale
25985
+ });
25986
+ stage.on("scaleXChange scaleYChange", () => {
25987
+ const scale = stage.scaleX();
25988
+ anchor.scale({
25989
+ x: 1 / scale,
25990
+ y: 1 / scale
25991
+ });
25992
+ });
25993
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT) anchor.setAbsolutePosition(absoluteCorners[0]);
25994
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) anchor.setAbsolutePosition(absoluteCorners[1]);
25995
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) anchor.setAbsolutePosition(absoluteCorners[2]);
25996
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT) anchor.setAbsolutePosition(absoluteCorners[3]);
25997
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER) anchor.setAbsolutePosition(absoluteCorners[4]);
25998
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT) anchor.setAbsolutePosition(absoluteCorners[5]);
25999
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) anchor.setAbsolutePosition(absoluteCorners[6]);
26000
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) anchor.setAbsolutePosition(absoluteCorners[7]);
26001
+ anchor.on("pointerover", () => {
26002
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT) this.instance.getStage().container().style.cursor = "nesw-resize";
26003
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT) this.instance.getStage().container().style.cursor = "nwse-resize";
26004
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT) this.instance.getStage().container().style.cursor = "ew-resize";
26005
+ if (position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER || position === WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER) this.instance.getStage().container().style.cursor = "ns-resize";
26006
+ });
26007
+ anchor.on("pointerdown", () => {
26008
+ onClick();
26009
+ });
26010
+ return anchor;
26011
+ }
26012
+ renderCropAnchors(layer, node) {
26013
+ const anchors = [
26014
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_LEFT,
26015
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_RIGHT,
26016
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_RIGHT,
26017
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_LEFT,
26018
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.TOP_CENTER,
26019
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_RIGHT,
26020
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.BOTTOM_CENTER,
26021
+ WEAVE_IMAGE_CROP_ANCHOR_POSITION.MIDDLE_LEFT
26022
+ ];
26023
+ for (const anchor of anchors) if (this.config.cropMode.selection.enabledAnchors.includes(anchor)) this.renderCropAnchor(anchor, node, layer, () => {
26024
+ this.triggerCrop(node, { cmdCtrl: {
26025
+ triggered: true,
26026
+ corner: anchor
26027
+ } });
26028
+ });
26029
+ }
26030
+ renderCropMode(layer, node) {
26031
+ this.renderCropBorder(layer, node);
26032
+ this.renderCropAnchors(layer, node);
26033
+ }
25507
26034
  onUpdate(nodeInstance, nextProps) {
25508
26035
  const id = nodeInstance.getAttrs().id;
25509
26036
  const node = nodeInstance;
@@ -25605,8 +26132,8 @@ var WeaveImageNode = class extends WeaveNode {
25605
26132
  }
25606
26133
  this.cacheNode(nodeInstance);
25607
26134
  }
25608
- preloadImage(imageId, imageURL, { onLoad, onError }) {
25609
- const realImageURL = this.config.urlTransformer?.(imageURL ?? "") ?? imageURL;
26135
+ preloadImage(imageId, imageURL, { node, onLoad, onError }) {
26136
+ const realImageURL = this.config.urlTransformer?.(imageURL ?? "", node) ?? imageURL;
25610
26137
  this.imageSource[imageId] = Konva.Util.createImageElement();
25611
26138
  this.imageSource[imageId].crossOrigin = this.config.crossOrigin;
25612
26139
  this.imageSource[imageId].onerror = (error) => {
@@ -25640,9 +26167,10 @@ var WeaveImageNode = class extends WeaveNode {
25640
26167
  const { id } = imageProps;
25641
26168
  const imagePlaceholder = image.findOne(`#${id}-placeholder`);
25642
26169
  const internalImage = image.findOne(`#${id}-image`);
25643
- const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "") ?? imageProps.imageURL;
26170
+ const realImageURL = this.config.urlTransformer?.(imageProps.imageURL ?? "", image) ?? imageProps.imageURL;
25644
26171
  this.loadAsyncElement(id);
25645
26172
  this.preloadImage(id, realImageURL ?? "", {
26173
+ node: image,
25646
26174
  onLoad: () => {
25647
26175
  if (image && imagePlaceholder && internalImage) {
25648
26176
  image.setAttrs({
@@ -26325,6 +26853,8 @@ var WeaveFrameNode = class extends WeaveNode {
26325
26853
  delete cleanedAttrs.mutexUserId;
26326
26854
  delete cleanedAttrs.draggable;
26327
26855
  delete cleanedAttrs.onTargetEnter;
26856
+ delete cleanedAttrs.overridesMouseControl;
26857
+ delete cleanedAttrs.dragBoundFunc;
26328
26858
  return {
26329
26859
  key: realAttrs?.id ?? "",
26330
26860
  type: realAttrs?.nodeType,
@@ -26560,6 +27090,8 @@ var WeaveStrokeNode = class extends WeaveNode {
26560
27090
  delete cleanedAttrs.draggable;
26561
27091
  delete cleanedAttrs.sceneFunc;
26562
27092
  delete cleanedAttrs.hitFunc;
27093
+ delete cleanedAttrs.overridesMouseControl;
27094
+ delete cleanedAttrs.dragBoundFunc;
26563
27095
  return {
26564
27096
  key: attrs.id ?? "",
26565
27097
  type: attrs.nodeType,
@@ -26576,23 +27108,793 @@ var WeaveStrokeNode = class extends WeaveNode {
26576
27108
  };
26577
27109
 
26578
27110
  //#endregion
26579
- //#region src/nodes/comment/constants.ts
26580
- const WEAVE_COMMENT_STATUS = {
26581
- PENDING: "pending",
26582
- RESOLVED: "resolved"
27111
+ //#region src/nodes/stroke-single/constants.ts
27112
+ const WEAVE_STROKE_SINGLE_NODE_TYPE = "stroke-single";
27113
+ const WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG = { snapAngles: {
27114
+ angles: [
27115
+ 0,
27116
+ 45,
27117
+ 90,
27118
+ 135,
27119
+ 180,
27120
+ 225,
27121
+ 270,
27122
+ 315
27123
+ ],
27124
+ activateThreshold: 5,
27125
+ releaseThreshold: 10
27126
+ } };
27127
+ const WEAVE_STROKE_SINGLE_NODE_TIP_TYPE = {
27128
+ NONE: "none",
27129
+ ARROW: "arrow",
27130
+ CIRCLE: "circle",
27131
+ SQUARE: "square"
26583
27132
  };
26584
- const WEAVE_COMMENT_CREATE_ACTION = {
26585
- CREATE: "create",
26586
- CLOSE: "close"
27133
+ const WEAVE_STROKE_SINGLE_NODE_TIP_SIDE = {
27134
+ START: "start",
27135
+ END: "end"
26587
27136
  };
26588
- const WEAVE_COMMENT_VIEW_ACTION = {
26589
- REPLY: "reply",
26590
- MARK_RESOLVED: "markResolved",
26591
- EDIT: "edit",
26592
- DELETE: "delete",
26593
- CLOSE: "close"
27137
+
27138
+ //#endregion
27139
+ //#region src/nodes/stroke-single/base.line-tip-manager.ts
27140
+ var WeaveBaseLineTipManager = class {
27141
+ constructor() {}
27142
+ capitalizeFirst(str) {
27143
+ if (typeof str !== "string" || str.length === 0) return str;
27144
+ return str[0].toUpperCase() + str.slice(1);
27145
+ }
27146
+ destroy(instance, point) {}
27147
+ render(instance, point) {}
27148
+ update(instance, point) {}
27149
+ getTip(instance, point) {
27150
+ const actualTip = instance.findOne(`#${instance.getAttrs().id}-tip-${point}`);
27151
+ if (!actualTip) return;
27152
+ return actualTip;
27153
+ }
27154
+ getInternalLine(instance) {
27155
+ const actualLine = instance.findOne(`#${instance.getAttrs().id}-line`);
27156
+ if (!actualLine) return;
27157
+ return actualLine;
27158
+ }
27159
+ getLinePoints(instance) {
27160
+ const points = instance.getAttrs().linePoints;
27161
+ const lineStartPoint = {
27162
+ x: points[0],
27163
+ y: points[1]
27164
+ };
27165
+ const lineEndPoint = {
27166
+ x: points[2],
27167
+ y: points[3]
27168
+ };
27169
+ return {
27170
+ lineStartPoint,
27171
+ lineEndPoint
27172
+ };
27173
+ }
26594
27174
  };
26595
- const WEAVE_COMMENT_NODE_ACTION = {
27175
+
27176
+ //#endregion
27177
+ //#region src/nodes/stroke-single/utils.ts
27178
+ const movePointParallelToLine$1 = (fromPoint, toPoint, point, distance) => {
27179
+ const dx = toPoint.x - fromPoint.x;
27180
+ const dy = toPoint.y - fromPoint.y;
27181
+ const len = Math.hypot(dx, dy);
27182
+ if (len === 0) throw new Error("Defined line length is zero");
27183
+ const ux = dx / len;
27184
+ const uy = dy / len;
27185
+ return {
27186
+ x: point.x + ux * distance,
27187
+ y: point.y + uy * distance
27188
+ };
27189
+ };
27190
+
27191
+ //#endregion
27192
+ //#region src/nodes/stroke-single/line-tip-managers/arrow.line-tip-manager.ts
27193
+ var WeaveArrowLineTipManager = class extends WeaveBaseLineTipManager {
27194
+ constructor() {
27195
+ super();
27196
+ }
27197
+ destroy(instance, point) {
27198
+ const actualTip = this.getTip(instance, point);
27199
+ if (!actualTip) return;
27200
+ actualTip.destroy();
27201
+ }
27202
+ updateTip(instance, point, internalLine, tip, base, height) {
27203
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27204
+ const trianglePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? height / 2 : -height / 2);
27205
+ tip.setAttrs({
27206
+ points: [
27207
+ -base / 2,
27208
+ height / 2,
27209
+ base / 2,
27210
+ height / 2,
27211
+ 0,
27212
+ -height / 2
27213
+ ],
27214
+ x: trianglePoint.x,
27215
+ y: trianglePoint.y
27216
+ });
27217
+ const angleRad = Math.atan2(lineEndPoint.y - lineStartPoint.y, lineEndPoint.x - lineStartPoint.x);
27218
+ const angleDeg = angleRad * (180 / Math.PI);
27219
+ tip.rotation(angleDeg + (point === "start" ? -90 : 90));
27220
+ if (point === "start") {
27221
+ const internalPoints = internalLine.points();
27222
+ internalLine.points([
27223
+ trianglePoint.x,
27224
+ trianglePoint.y,
27225
+ internalPoints[2],
27226
+ internalPoints[3]
27227
+ ]);
27228
+ } else {
27229
+ const internalPoints = internalLine.points();
27230
+ internalLine.points([
27231
+ internalPoints[0],
27232
+ internalPoints[1],
27233
+ trianglePoint.x,
27234
+ trianglePoint.y
27235
+ ]);
27236
+ }
27237
+ }
27238
+ render(instance, point) {
27239
+ this.destroy(instance, point);
27240
+ const internalLine = this.getInternalLine(instance);
27241
+ if (!internalLine) return;
27242
+ const stroke = instance.getAttrs().stroke ?? "black";
27243
+ const base = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Base`] ?? 3;
27244
+ const height = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Height`] ?? Math.sqrt(3) / 2 * 3;
27245
+ const triangle = new Konva.Line({
27246
+ id: `${instance.getAttrs().id}-tip-${point}`,
27247
+ name: "lineTip",
27248
+ nodeId: instance.getAttrs().id,
27249
+ closed: true,
27250
+ stroke,
27251
+ strokeWidth: 0,
27252
+ strokeScaleEnabled: false,
27253
+ fill: stroke
27254
+ });
27255
+ instance.add(triangle);
27256
+ this.updateTip(instance, point, internalLine, triangle, base, height);
27257
+ }
27258
+ update(instance, point) {
27259
+ const actualTip = this.getTip(instance, point);
27260
+ if (!actualTip) return;
27261
+ const internalLine = this.getInternalLine(instance);
27262
+ if (!internalLine) return;
27263
+ const stroke = instance.getAttrs().stroke ?? "black";
27264
+ const base = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Base`] ?? 3;
27265
+ const height = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Height`] ?? Math.sqrt(3) / 2 * 3;
27266
+ actualTip.setAttrs({ fill: stroke });
27267
+ this.updateTip(instance, point, internalLine, actualTip, base, height);
27268
+ }
27269
+ };
27270
+
27271
+ //#endregion
27272
+ //#region src/nodes/stroke-single/line-tip-managers/circle.line-tip-manager.ts
27273
+ var WeaveCircleLineTipManager = class extends WeaveBaseLineTipManager {
27274
+ constructor() {
27275
+ super();
27276
+ }
27277
+ moveTipAlongLine(instance, point, internalLine, tip, distance) {
27278
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27279
+ const circlePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? distance : -distance);
27280
+ if (point === "start") {
27281
+ const internalPoints = internalLine.points();
27282
+ internalLine.points([
27283
+ circlePoint.x,
27284
+ circlePoint.y,
27285
+ internalPoints[2],
27286
+ internalPoints[3]
27287
+ ]);
27288
+ } else {
27289
+ const internalPoints = internalLine.points();
27290
+ internalLine.points([
27291
+ internalPoints[0],
27292
+ internalPoints[1],
27293
+ circlePoint.x,
27294
+ circlePoint.y
27295
+ ]);
27296
+ }
27297
+ tip.x(circlePoint.x);
27298
+ tip.y(circlePoint.y);
27299
+ }
27300
+ destroy(instance, point) {
27301
+ const actualTip = this.getTip(instance, point);
27302
+ if (!actualTip) return;
27303
+ actualTip.destroy();
27304
+ }
27305
+ render(instance, point) {
27306
+ this.destroy(instance, point);
27307
+ const actualLine = this.getInternalLine(instance);
27308
+ if (!actualLine) return;
27309
+ const stroke = instance.getAttrs().stroke ?? "black";
27310
+ const radius = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Radius`] ?? 1.5;
27311
+ const circle = new Konva.Circle({
27312
+ id: `${instance.getAttrs().id}-tip-${point}`,
27313
+ name: "lineTip",
27314
+ nodeId: instance.getAttrs().id,
27315
+ radius,
27316
+ stroke: "black",
27317
+ strokeWidth: 0,
27318
+ strokeScaleEnabled: false,
27319
+ fill: stroke
27320
+ });
27321
+ instance.add(circle);
27322
+ this.moveTipAlongLine(instance, point, actualLine, circle, radius);
27323
+ }
27324
+ update(instance, point) {
27325
+ const actualTip = this.getTip(instance, point);
27326
+ if (!actualTip) return;
27327
+ const actualLine = this.getInternalLine(instance);
27328
+ if (!actualLine) return;
27329
+ const stroke = instance.getAttrs().stroke ?? "black";
27330
+ const radius = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Radius`] ?? 1.5;
27331
+ actualTip.setAttrs({
27332
+ fill: stroke,
27333
+ radius
27334
+ });
27335
+ this.moveTipAlongLine(instance, point, actualLine, actualTip, radius);
27336
+ }
27337
+ };
27338
+
27339
+ //#endregion
27340
+ //#region src/nodes/stroke-single/line-tip-managers/none.line-tip-manager.ts
27341
+ var WeaveNoneLineTipManager = class extends WeaveBaseLineTipManager {
27342
+ constructor() {
27343
+ super();
27344
+ }
27345
+ destroy(instance, point) {
27346
+ const actualTip = this.getTip(instance, point);
27347
+ if (!actualTip) return;
27348
+ actualTip.destroy();
27349
+ }
27350
+ render(instance, point) {
27351
+ this.destroy(instance, point);
27352
+ this.update(instance, point);
27353
+ }
27354
+ update(instance, point) {
27355
+ const internalLine = this.getInternalLine(instance);
27356
+ if (!internalLine) return;
27357
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27358
+ const distance = instance.getAttrs().strokeWidth ?? 1;
27359
+ const linePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? distance / 2 : -(distance / 2));
27360
+ if (point === "start") {
27361
+ const internalPoints = internalLine.points();
27362
+ internalLine.points([
27363
+ linePoint.x,
27364
+ linePoint.y,
27365
+ internalPoints[2],
27366
+ internalPoints[3]
27367
+ ]);
27368
+ } else {
27369
+ const internalPoints = internalLine.points();
27370
+ internalLine.points([
27371
+ internalPoints[0],
27372
+ internalPoints[1],
27373
+ linePoint.x,
27374
+ linePoint.y
27375
+ ]);
27376
+ }
27377
+ }
27378
+ };
27379
+
27380
+ //#endregion
27381
+ //#region src/nodes/stroke-single/line-tip-managers/square.line-tip-manager.ts
27382
+ var WeaveSquareLineTipManager = class extends WeaveBaseLineTipManager {
27383
+ constructor() {
27384
+ super();
27385
+ }
27386
+ moveTipAlongLine(instance, point, internalLine, tip, distance) {
27387
+ const { lineStartPoint, lineEndPoint } = this.getLinePoints(instance);
27388
+ const points = instance.getAttrs().linePoints;
27389
+ const circlePoint = movePointParallelToLine$1(lineStartPoint, lineEndPoint, point === "start" ? lineStartPoint : lineEndPoint, point === "start" ? distance : -distance);
27390
+ if (point === "start") {
27391
+ const internalPoints = internalLine.points();
27392
+ internalLine.points([
27393
+ circlePoint.x,
27394
+ circlePoint.y,
27395
+ internalPoints[2],
27396
+ internalPoints[3]
27397
+ ]);
27398
+ } else {
27399
+ const internalPoints = internalLine.points();
27400
+ internalLine.points([
27401
+ internalPoints[0],
27402
+ internalPoints[1],
27403
+ circlePoint.x,
27404
+ circlePoint.y
27405
+ ]);
27406
+ }
27407
+ tip.x(circlePoint.x);
27408
+ tip.y(circlePoint.y);
27409
+ const angle = Math.atan2(points[3] - points[1], points[2] - points[0]);
27410
+ const deg = angle * 180 / Math.PI;
27411
+ tip.rotation(deg);
27412
+ }
27413
+ destroy(instance, point) {
27414
+ const actualTip = this.getTip(instance, point);
27415
+ if (!actualTip) return;
27416
+ actualTip.destroy();
27417
+ }
27418
+ render(instance, point) {
27419
+ this.destroy(instance, point);
27420
+ const actualLine = this.getInternalLine(instance);
27421
+ if (!actualLine) return;
27422
+ const points = instance.getAttrs().linePoints;
27423
+ const stroke = instance.getAttrs().stroke ?? "black";
27424
+ const width = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Width`] ?? 3;
27425
+ const square = new Konva.Rect({
27426
+ id: `${instance.getAttrs().id}-tip-${point}`,
27427
+ name: "lineTip",
27428
+ nodeId: instance.getAttrs().id,
27429
+ width,
27430
+ height: width,
27431
+ stroke: "black",
27432
+ strokeWidth: 0,
27433
+ strokeScaleEnabled: false,
27434
+ fill: stroke,
27435
+ offsetX: width / 2,
27436
+ offsetY: width / 2
27437
+ });
27438
+ const angle = Math.atan2(points[3] - points[1], points[2] - points[0]);
27439
+ const deg = angle * 180 / Math.PI;
27440
+ square.rotation(deg);
27441
+ instance.add(square);
27442
+ this.moveTipAlongLine(instance, point, actualLine, square, width / 2);
27443
+ }
27444
+ update(instance, point) {
27445
+ const actualTip = this.getTip(instance, point);
27446
+ if (!actualTip) return;
27447
+ const actualLine = this.getInternalLine(instance);
27448
+ if (!actualLine) return;
27449
+ const stroke = instance.getAttrs().stroke ?? "black";
27450
+ const radius = instance.getAttrs()[`tip${this.capitalizeFirst(point)}Radius`] ?? 1.5;
27451
+ actualTip.setAttrs({
27452
+ fill: stroke,
27453
+ radius
27454
+ });
27455
+ this.moveTipAlongLine(instance, point, actualLine, actualTip, radius);
27456
+ }
27457
+ };
27458
+
27459
+ //#endregion
27460
+ //#region src/nodes/stroke-single/stroke-single.ts
27461
+ var WeaveStrokeSingleNode = class extends WeaveNode {
27462
+ startHandle = null;
27463
+ endHandle = null;
27464
+ nodeType = WEAVE_STROKE_SINGLE_NODE_TYPE;
27465
+ tipManagers = {
27466
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.ARROW]: new WeaveArrowLineTipManager(),
27467
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.CIRCLE]: new WeaveCircleLineTipManager(),
27468
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.SQUARE]: new WeaveSquareLineTipManager(),
27469
+ [WEAVE_STROKE_SINGLE_NODE_TIP_TYPE.NONE]: new WeaveNoneLineTipManager()
27470
+ };
27471
+ constructor(params) {
27472
+ super();
27473
+ this.config = mergeExceptArrays(WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, params?.config ?? {});
27474
+ this.handleNodeChanges = null;
27475
+ this.handleZoomChanges = null;
27476
+ this.snapper = new GreedySnapper({
27477
+ snapAngles: this.config.snapAngles.angles,
27478
+ activateThreshold: this.config.snapAngles.activateThreshold,
27479
+ releaseThreshold: this.config.snapAngles.releaseThreshold
27480
+ });
27481
+ }
27482
+ onRender(props) {
27483
+ const stroke = new Konva.Group({
27484
+ ...props,
27485
+ name: `node ${WEAVE_STROKE_SINGLE_NODE_TYPE}`,
27486
+ linePoints: props.linePoints,
27487
+ strokeScaleEnabled: true,
27488
+ overridesMouseControl: true
27489
+ });
27490
+ const internalLine = new Konva.Line({
27491
+ ...props,
27492
+ id: `${stroke.getAttrs().id}-line`,
27493
+ nodeId: stroke.getAttrs().id,
27494
+ name: void 0,
27495
+ x: 0,
27496
+ y: 0,
27497
+ strokeScaleEnabled: true,
27498
+ lineJoin: "miter",
27499
+ lineCap: "round"
27500
+ });
27501
+ stroke.add(internalLine);
27502
+ this.setupDefaultNodeAugmentation(stroke);
27503
+ const defaultTransformerProperties = this.defaultGetTransformerProperties(this.config.transform);
27504
+ stroke.getTransformerProperties = function() {
27505
+ const points = this.getAttrs().linePoints;
27506
+ return {
27507
+ ...defaultTransformerProperties,
27508
+ ignoreStroke: true,
27509
+ rotateEnabled: points.length !== 4,
27510
+ keepRatio: points.length !== 4,
27511
+ flipEnabled: points.length === 4,
27512
+ shiftBehavior: points.length === 4 ? "none" : "default",
27513
+ shouldOverdrawWholeArea: points.length !== 4
27514
+ };
27515
+ };
27516
+ let originalStartHandleVisibility = null;
27517
+ let originalEndHandleVisibility = null;
27518
+ stroke.on("dragstart", () => {
27519
+ originalStartHandleVisibility = this.startHandle?.visible() ?? false;
27520
+ originalEndHandleVisibility = this.endHandle?.visible() ?? false;
27521
+ this.startHandle?.visible(false);
27522
+ this.endHandle?.visible(false);
27523
+ });
27524
+ stroke.on("dragend", () => {
27525
+ this.startHandle?.visible(originalStartHandleVisibility);
27526
+ this.endHandle?.visible(originalEndHandleVisibility);
27527
+ originalStartHandleVisibility = null;
27528
+ originalEndHandleVisibility = null;
27529
+ });
27530
+ this.setupDefaultNodeEvents(stroke);
27531
+ if (!this.handleZoomChanges) {
27532
+ this.handleZoomChanges = () => {
27533
+ if (this.startHandle) this.startHandle.scale({
27534
+ x: 1 / this.instance.getStage().scaleX(),
27535
+ y: 1 / this.instance.getStage().scaleY()
27536
+ });
27537
+ if (this.endHandle) this.endHandle.scale({
27538
+ x: 1 / this.instance.getStage().scaleX(),
27539
+ y: 1 / this.instance.getStage().scaleY()
27540
+ });
27541
+ };
27542
+ this.instance.addEventListener("onZoomChange", this.handleZoomChanges);
27543
+ }
27544
+ if (!this.handleNodeChanges) {
27545
+ this.handleNodeChanges = (nodes) => {
27546
+ this.teardownSelection();
27547
+ if (nodes.length === 1 && nodes[0].instance.getAttrs().nodeType === WEAVE_STROKE_SINGLE_NODE_TYPE) {
27548
+ const strokeSelected = this.instance.getStage().findOne(`#${nodes[0].instance.getAttrs().id}`);
27549
+ if (!strokeSelected) return;
27550
+ this.setupHandles();
27551
+ this.showHandles(strokeSelected);
27552
+ this.setupSelection(strokeSelected, true);
27553
+ } else {
27554
+ this.startHandle?.setAttr("strokeId", void 0);
27555
+ this.startHandle?.visible(false);
27556
+ this.endHandle?.setAttr("strokeId", void 0);
27557
+ this.endHandle?.visible(false);
27558
+ }
27559
+ };
27560
+ this.instance.addEventListener("onNodesChange", this.handleNodeChanges);
27561
+ }
27562
+ const tipStartStyle = stroke.getAttrs().tipStartStyle ?? "none";
27563
+ const tipEndStyle = stroke.getAttrs().tipEndStyle ?? "none";
27564
+ this.tipManagers[tipStartStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27565
+ this.tipManagers[tipEndStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27566
+ stroke.handleMouseover = () => {
27567
+ this.setupSelection(stroke);
27568
+ };
27569
+ stroke.handleMouseout = () => {
27570
+ const attrs = stroke.getAttrs();
27571
+ if (attrs.isSelected) return;
27572
+ const nodes = stroke.find(".hoverClone");
27573
+ nodes.forEach((node) => node.destroy());
27574
+ };
27575
+ stroke.getTransformerProperties = () => {
27576
+ return this.defaultGetTransformerProperties({
27577
+ ...this.config.transform,
27578
+ rotateEnabled: false,
27579
+ shouldOverdrawWholeArea: false,
27580
+ borderStroke: "transparent"
27581
+ });
27582
+ };
27583
+ stroke.allowedAnchors = function() {
27584
+ return [];
27585
+ };
27586
+ stroke.canBeHovered = function() {
27587
+ return false;
27588
+ };
27589
+ stroke.getNodeAnchors = function() {
27590
+ return [];
27591
+ };
27592
+ return stroke;
27593
+ }
27594
+ setupHandles() {
27595
+ if (!this.startHandle) {
27596
+ const startHandle = new Konva.Circle({
27597
+ id: "line-start-handle",
27598
+ radius: 5,
27599
+ fill: "#ffffff",
27600
+ stroke: "#000000",
27601
+ strokeWidth: 1,
27602
+ edgeDistanceDisableOnDrag: true,
27603
+ scaleX: 1 / this.instance.getStage().scaleX(),
27604
+ scaleY: 1 / this.instance.getStage().scaleY(),
27605
+ draggable: true
27606
+ });
27607
+ startHandle.on("pointerover", () => {
27608
+ this.instance.getStage().container().style.cursor = "move";
27609
+ });
27610
+ startHandle.on("pointerout", () => {
27611
+ this.instance.getStage().container().style.cursor = "default";
27612
+ });
27613
+ startHandle.on("dragstart", (e) => {
27614
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27615
+ if (tr) tr.hide();
27616
+ const strokeId = e.target.getAttr("strokeId");
27617
+ const stroke = this.instance.getStage().findOne(`#${strokeId}`);
27618
+ if (!stroke) return;
27619
+ const points = stroke.getAttrs().linePoints;
27620
+ if (points.length === 4) stroke.setAttr("eventTarget", true);
27621
+ this.instance.emitEvent("onDrag", e.target);
27622
+ });
27623
+ startHandle.on("dragmove", (e) => {
27624
+ const draggedTarget = e.target;
27625
+ const strokeId = draggedTarget.getAttr("strokeId");
27626
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27627
+ if (!draggedStroke) return;
27628
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27629
+ if (!internalLine) return;
27630
+ const points = draggedStroke.getAttrs().linePoints;
27631
+ if (points.length !== 4) return;
27632
+ this.teardownSelection();
27633
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27634
+ draggedStroke.setAttrs({ linePoints: [
27635
+ newLinePoint.x,
27636
+ newLinePoint.y,
27637
+ points[2],
27638
+ points[3]
27639
+ ] });
27640
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27641
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27642
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27643
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27644
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27645
+ this.setupSelection(draggedStroke);
27646
+ });
27647
+ startHandle.on("dragend", (e) => {
27648
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27649
+ if (tr) tr.show();
27650
+ const draggedTarget = e.target;
27651
+ const strokeId = draggedTarget.getAttr("strokeId");
27652
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27653
+ if (!draggedStroke) return;
27654
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27655
+ if (!internalLine) return;
27656
+ const points = draggedStroke.getAttrs().linePoints;
27657
+ if (points.length !== 4) return;
27658
+ this.teardownSelection();
27659
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27660
+ draggedStroke.setAttrs({ linePoints: [
27661
+ newLinePoint.x,
27662
+ newLinePoint.y,
27663
+ points[2],
27664
+ points[3]
27665
+ ] });
27666
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27667
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27668
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27669
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27670
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27671
+ this.setupSelection(draggedStroke);
27672
+ this.instance.updateNode(this.serialize(draggedStroke));
27673
+ this.instance.emitEvent("onDrag", null);
27674
+ });
27675
+ this.startHandle = startHandle;
27676
+ this.startHandle.visible(false);
27677
+ this.instance.getSelectionLayer()?.add(this.startHandle);
27678
+ }
27679
+ if (!this.endHandle) {
27680
+ const endHandle = new Konva.Circle({
27681
+ id: "line-end-handle",
27682
+ radius: 5,
27683
+ fill: "#ffffff",
27684
+ stroke: "#000000",
27685
+ strokeWidth: 1,
27686
+ edgeDistanceDisableOnDrag: true,
27687
+ scaleX: 1 / this.instance.getStage().scaleX(),
27688
+ scaleY: 1 / this.instance.getStage().scaleY(),
27689
+ draggable: true
27690
+ });
27691
+ endHandle.on("pointerover", () => {
27692
+ this.instance.getStage().container().style.cursor = "move";
27693
+ });
27694
+ endHandle.on("pointerout", () => {
27695
+ this.instance.getStage().container().style.cursor = "default";
27696
+ });
27697
+ endHandle.on("dragstart", (e) => {
27698
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27699
+ if (tr) tr.hide();
27700
+ const strokeId = e.target.getAttr("strokeId");
27701
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27702
+ if (!draggedStroke) return;
27703
+ const points = draggedStroke.getAttrs().linePoints;
27704
+ if (points.length !== 4) return;
27705
+ if (points.length === 4) draggedStroke.setAttr("eventTarget", true);
27706
+ this.instance.emitEvent("onDrag", e.target);
27707
+ });
27708
+ endHandle.on("dragmove", (e) => {
27709
+ const draggedTarget = e.target;
27710
+ const strokeId = draggedTarget.getAttr("strokeId");
27711
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27712
+ if (!draggedStroke) return;
27713
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27714
+ if (!internalLine) return;
27715
+ const points = draggedStroke.getAttrs().linePoints;
27716
+ if (points.length !== 4) return;
27717
+ this.teardownSelection();
27718
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27719
+ draggedStroke.setAttrs({ linePoints: [
27720
+ points[0],
27721
+ points[1],
27722
+ newLinePoint.x,
27723
+ newLinePoint.y
27724
+ ] });
27725
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27726
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27727
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27728
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27729
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27730
+ this.setupSelection(draggedStroke);
27731
+ });
27732
+ endHandle.on("dragend", (e) => {
27733
+ const tr = this.instance.getPlugin("nodesSelection")?.getTransformer();
27734
+ if (tr) tr.show();
27735
+ const draggedTarget = e.target;
27736
+ const strokeId = draggedTarget.getAttr("strokeId");
27737
+ const draggedStroke = this.instance.getStage().findOne(`#${strokeId}`);
27738
+ if (!draggedStroke) return;
27739
+ const internalLine = draggedStroke.findOne(`#${draggedStroke.getAttrs().id}-line`);
27740
+ if (!internalLine) return;
27741
+ const points = draggedStroke.getAttrs().linePoints;
27742
+ if (points.length !== 4) return;
27743
+ this.teardownSelection();
27744
+ const newLinePoint = this.getLinePointFromHandle(draggedStroke, e);
27745
+ draggedStroke.setAttrs({ linePoints: [
27746
+ points[0],
27747
+ points[1],
27748
+ newLinePoint.x,
27749
+ newLinePoint.y
27750
+ ] });
27751
+ this.positionHandle(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27752
+ const tipStartStyle = draggedStroke.getAttrs().tipStartStyle ?? "none";
27753
+ this.tipManagers[tipStartStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27754
+ const tipEndStyle = draggedStroke.getAttrs().tipEndStyle ?? "none";
27755
+ this.tipManagers[tipEndStyle]?.update(draggedStroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27756
+ this.setupSelection(draggedStroke);
27757
+ this.instance.updateNode(this.serialize(draggedStroke));
27758
+ this.instance.emitEvent("onDrag", null);
27759
+ });
27760
+ this.endHandle = endHandle;
27761
+ this.endHandle.visible(false);
27762
+ this.instance.getSelectionLayer()?.add(this.endHandle);
27763
+ }
27764
+ }
27765
+ showHandles(stroke) {
27766
+ if (this.startHandle === null || this.endHandle === null) return;
27767
+ this.startHandle.setAttr("strokeId", stroke.getAttrs().id);
27768
+ this.startHandle.setAttr("targetNode", stroke.getAttrs().id);
27769
+ this.startHandle.visible(true);
27770
+ this.startHandle.moveToTop();
27771
+ this.positionHandle(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27772
+ this.endHandle.setAttr("strokeId", stroke.getAttrs().id);
27773
+ this.endHandle.setAttr("targetNode", stroke.getAttrs().id);
27774
+ this.endHandle.visible(true);
27775
+ this.endHandle.moveToTop();
27776
+ this.positionHandle(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27777
+ }
27778
+ onUpdate(nodeInstance, nextProps) {
27779
+ nodeInstance.setAttrs({ ...nextProps });
27780
+ const stroke = nodeInstance;
27781
+ const tipStartStyle = nextProps.tipStartStyle ?? "none";
27782
+ const tipEndStyle = nextProps.tipEndStyle ?? "none";
27783
+ this.tipManagers[tipStartStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27784
+ this.tipManagers[tipEndStyle]?.render(stroke, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27785
+ const internalLine = stroke.findOne(`#${stroke.getAttrs().id}-line`);
27786
+ if (internalLine) internalLine.setAttrs({
27787
+ name: void 0,
27788
+ dash: nextProps.dash,
27789
+ fill: nextProps.fill,
27790
+ stroke: nextProps.stroke,
27791
+ strokeWidth: nextProps.strokeWidth,
27792
+ lineJoin: "miter",
27793
+ lineCap: "round"
27794
+ });
27795
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
27796
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
27797
+ }
27798
+ scaleReset(node) {
27799
+ const scale = node.scale();
27800
+ const oldPoints = node.getAttrs().linePoints;
27801
+ const newPoints = [];
27802
+ for (let i = 0; i < oldPoints.length; i += 2) {
27803
+ const x = oldPoints[i] * scale.x;
27804
+ const y = oldPoints[i + 1] * scale.y;
27805
+ newPoints.push(x, y);
27806
+ }
27807
+ node.setAttrs({ linePoints: newPoints });
27808
+ node.scale({
27809
+ x: 1,
27810
+ y: 1
27811
+ });
27812
+ }
27813
+ positionHandle(instance, point) {
27814
+ const stage = this.instance.getStage();
27815
+ const points = instance.getAttrs().linePoints;
27816
+ const internalLine = instance.findOne(`#${instance.getAttrs().id}-line`);
27817
+ if (!internalLine) return;
27818
+ if (point === "start" && this.startHandle) {
27819
+ const stagePoint = internalLine.getAbsoluteTransform().point({
27820
+ x: points[0],
27821
+ y: points[1]
27822
+ });
27823
+ const localPoint = stage.getAbsoluteTransform().copy().invert().point(stagePoint);
27824
+ this.startHandle.x(localPoint.x);
27825
+ this.startHandle.y(localPoint.y);
27826
+ }
27827
+ if (point === "end" && this.endHandle) {
27828
+ const stagePoint = internalLine.getAbsoluteTransform().point({
27829
+ x: points[2],
27830
+ y: points[3]
27831
+ });
27832
+ const localPoint = stage.getAbsoluteTransform().copy().invert().point(stagePoint);
27833
+ this.endHandle.x(localPoint.x);
27834
+ this.endHandle.y(localPoint.y);
27835
+ }
27836
+ }
27837
+ getLinePointFromHandle(instance, e) {
27838
+ const stage = this.instance.getStage();
27839
+ const stagePoint = stage.getAbsoluteTransform().point(e.target.position());
27840
+ const localPoint = instance.getAbsoluteTransform().copy().invert().point(stagePoint);
27841
+ return localPoint;
27842
+ }
27843
+ setupSelection(instance, markSelected = false) {
27844
+ if (markSelected) instance.setAttrs({ isSelected: true });
27845
+ const hoverClone = instance.findOne(".hoverClone");
27846
+ if (hoverClone) return;
27847
+ const internalLine = instance.findOne(`#${instance.getAttrs().id}-line`);
27848
+ if (!internalLine) return;
27849
+ const internalLineHover = internalLine.clone();
27850
+ internalLineHover.setAttrs({
27851
+ name: "hoverClone",
27852
+ stroke: "#1a1aff",
27853
+ listening: false,
27854
+ draggable: false,
27855
+ strokeWidth: 1,
27856
+ points: instance.getAttrs().linePoints,
27857
+ strokeScaleEnabled: false
27858
+ });
27859
+ instance.add(internalLineHover);
27860
+ internalLineHover.moveToTop();
27861
+ }
27862
+ teardownSelection() {
27863
+ const stage = this.instance.getStage();
27864
+ const arrows = stage.find(`.${WEAVE_STROKE_SINGLE_NODE_TYPE}`);
27865
+ for (let i = 0; i < arrows.length; i++) {
27866
+ const arrow = arrows[i];
27867
+ arrow.setAttrs({ isSelected: false });
27868
+ const nodes = arrow.find(".hoverClone");
27869
+ if (nodes.length > 0) nodes.forEach((node) => node.destroy());
27870
+ }
27871
+ }
27872
+ updateLine(instance) {
27873
+ const tipStartStyle = instance.getAttrs().tipStartStyle ?? "none";
27874
+ this.tipManagers[tipStartStyle]?.update(instance, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.START);
27875
+ const tipEndStyle = instance.getAttrs().tipEndStyle ?? "none";
27876
+ this.tipManagers[tipEndStyle]?.update(instance, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE.END);
27877
+ }
27878
+ };
27879
+
27880
+ //#endregion
27881
+ //#region src/nodes/comment/constants.ts
27882
+ const WEAVE_COMMENT_STATUS = {
27883
+ PENDING: "pending",
27884
+ RESOLVED: "resolved"
27885
+ };
27886
+ const WEAVE_COMMENT_CREATE_ACTION = {
27887
+ CREATE: "create",
27888
+ CLOSE: "close"
27889
+ };
27890
+ const WEAVE_COMMENT_VIEW_ACTION = {
27891
+ REPLY: "reply",
27892
+ MARK_RESOLVED: "markResolved",
27893
+ EDIT: "edit",
27894
+ DELETE: "delete",
27895
+ CLOSE: "close"
27896
+ };
27897
+ const WEAVE_COMMENT_NODE_ACTION = {
26596
27898
  IDLE: "idle",
26597
27899
  CREATING: "creating",
26598
27900
  VIEWING: "viewing"
@@ -27365,7 +28667,7 @@ var WeaveVideoNode = class extends WeaveNode {
27365
28667
  const videoPlaceholder = video.findOne(`#${id}-video-placeholder`);
27366
28668
  const videoIconGroup = video.findOne(`#${id}-video-icon-group`);
27367
28669
  if (!videoPlaceholder || !videoIconGroup) return;
27368
- const realVideoPlaceholderURL = this.config.urlTransformer?.(videoProps.videoPlaceholderURL ?? "") ?? videoProps.videoPlaceholderURL;
28670
+ const realVideoPlaceholderURL = this.config.urlTransformer?.(videoProps.videoPlaceholderURL ?? "", video) ?? videoProps.videoPlaceholderURL;
27369
28671
  this.videoPlaceholder[id] = Konva.Util.createImageElement();
27370
28672
  this.videoPlaceholder[id].crossOrigin = this.config.crossOrigin;
27371
28673
  this.videoPlaceholder[id].src = realVideoPlaceholderURL;
@@ -27398,7 +28700,7 @@ var WeaveVideoNode = class extends WeaveNode {
27398
28700
  const videoPlaceholder = video.findOne(`#${id}-video-placeholder`);
27399
28701
  const videoPlayer = video.findOne(`#${id}-video`);
27400
28702
  if (!bg || !videoIconGroup || !videoProgress || !videoPlayer || !videoPlaceholder) return;
27401
- const realVideoURL = this.config.urlTransformer?.(videoProps.videoURL ?? "") ?? videoProps.videoURL;
28703
+ const realVideoURL = this.config.urlTransformer?.(videoProps.videoURL ?? "", video) ?? videoProps.videoURL;
27402
28704
  if (realVideoURL) videoSource.src = realVideoURL;
27403
28705
  videoSource.addEventListener("loadeddata", () => {
27404
28706
  videoSource.currentTime = 0;
@@ -27681,7 +28983,7 @@ var WeaveVideoNode = class extends WeaveNode {
27681
28983
  playing: true,
27682
28984
  paused: false
27683
28985
  };
27684
- this.videoSource[videoId].play();
28986
+ this.videoSource[videoId]?.play?.();
27685
28987
  this.anim.start();
27686
28988
  this.instance.emitEvent("onVideoPlay", { nodeId: videoId });
27687
28989
  }
@@ -29258,7 +30560,8 @@ var WeaveConnectorNode = class extends WeaveNode {
29258
30560
  name: "node",
29259
30561
  startInfoLoaded: false,
29260
30562
  endInfoLoaded: false,
29261
- draggable: false
30563
+ draggable: false,
30564
+ overridesMouseControl: true
29262
30565
  });
29263
30566
  if (!connector.getAttrs().lineType) connector.setAttrs({
29264
30567
  lineType: WEAVE_CONNECTOR_NODE_LINE_TYPE.STRAIGHT,
@@ -29749,6 +31052,8 @@ var WeaveConnectorNode = class extends WeaveNode {
29749
31052
  delete cleanedAttrs.initialized;
29750
31053
  delete cleanedAttrs.startInfoLoaded;
29751
31054
  delete cleanedAttrs.endInfoLoaded;
31055
+ delete cleanedAttrs.overridesMouseControl;
31056
+ delete cleanedAttrs.dragBoundFunc;
29752
31057
  return {
29753
31058
  key: attrs.id ?? "",
29754
31059
  type: attrs.nodeType,
@@ -29980,6 +31285,7 @@ var WeaveStageZoomPlugin = class extends WeavePlugin {
29980
31285
  canZoomIn: this.canZoomIn(),
29981
31286
  canZoomOut: this.canZoomOut()
29982
31287
  };
31288
+ stage.fire("onZoomChange", {}, true);
29983
31289
  this.instance.emitEvent("onZoomChange", callbackParams);
29984
31290
  }
29985
31291
  }
@@ -32781,6 +34087,7 @@ var WeaveArrowToolAction = class extends WeaveAction {
32781
34087
  ...clonedLine.getAttrs(),
32782
34088
  hitStrokeWidth: 16
32783
34089
  });
34090
+ delete finalArrow.props.dragBoundFunc;
32784
34091
  this.instance.addNode(finalArrow, this.container?.getAttrs().id);
32785
34092
  this.instance.emitEvent("onAddedArrow");
32786
34093
  }
@@ -32816,6 +34123,276 @@ var WeaveArrowToolAction = class extends WeaveAction {
32816
34123
  }
32817
34124
  };
32818
34125
 
34126
+ //#endregion
34127
+ //#region src/actions/stroke-tool/constants.ts
34128
+ const WEAVE_STROKE_TOOL_ACTION_NAME = "strokeTool";
34129
+ const WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES = ["arrowTool"];
34130
+ const WEAVE_STROKE_TOOL_STATE = {
34131
+ ["IDLE"]: "idle",
34132
+ ["ADDING"]: "adding",
34133
+ ["DEFINING_SIZE"]: "definingSize",
34134
+ ["ADDED"]: "added"
34135
+ };
34136
+ const WEAVE_STROKE_TOOL_DEFAULT_CONFIG = { snapAngles: {
34137
+ angles: [
34138
+ 0,
34139
+ 45,
34140
+ 90,
34141
+ 135,
34142
+ 180,
34143
+ 225,
34144
+ 270,
34145
+ 315
34146
+ ],
34147
+ activateThreshold: 5,
34148
+ releaseThreshold: 10
34149
+ } };
34150
+
34151
+ //#endregion
34152
+ //#region src/actions/stroke-tool/stroke-tool.ts
34153
+ var WeaveStrokeToolAction = class extends WeaveAction {
34154
+ initialized = false;
34155
+ initialCursor = null;
34156
+ snappedAngle = null;
34157
+ shiftPressed = false;
34158
+ onPropsChange = void 0;
34159
+ onInit = void 0;
34160
+ constructor(params) {
34161
+ super();
34162
+ this.config = mergeExceptArrays(WEAVE_STROKE_TOOL_DEFAULT_CONFIG, params?.config ?? {});
34163
+ this.pointers = new Map();
34164
+ this.initialized = false;
34165
+ this.state = WEAVE_STROKE_TOOL_STATE.IDLE;
34166
+ this.arrowId = null;
34167
+ this.shiftPressed = false;
34168
+ this.tempLineId = null;
34169
+ this.tempLineNode = null;
34170
+ this.container = void 0;
34171
+ this.snappedAngle = null;
34172
+ this.measureContainer = void 0;
34173
+ this.clickPoint = null;
34174
+ this.snapper = new GreedySnapper({
34175
+ snapAngles: this.config.snapAngles.angles,
34176
+ activateThreshold: this.config.snapAngles.activateThreshold,
34177
+ releaseThreshold: this.config.snapAngles.releaseThreshold
34178
+ });
34179
+ this.props = this.initProps();
34180
+ }
34181
+ getName() {
34182
+ return WEAVE_STROKE_TOOL_ACTION_NAME;
34183
+ }
34184
+ hasAliases() {
34185
+ return true;
34186
+ }
34187
+ getAliases() {
34188
+ return WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES;
34189
+ }
34190
+ initProps() {
34191
+ return {
34192
+ stroke: "#000000ff",
34193
+ strokeWidth: 1,
34194
+ opacity: 1,
34195
+ tipStartStyle: "none",
34196
+ tipEndStyle: "none"
34197
+ };
34198
+ }
34199
+ setupEvents() {
34200
+ const stage = this.instance.getStage();
34201
+ window.addEventListener("keydown", (e) => {
34202
+ if (e.code === "Enter" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34203
+ this.cancelAction();
34204
+ return;
34205
+ }
34206
+ if (e.code === "Escape" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34207
+ this.cancelAction();
34208
+ return;
34209
+ }
34210
+ if (e.key === "Shift" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34211
+ this.snappedAngle = null;
34212
+ this.shiftPressed = true;
34213
+ }
34214
+ });
34215
+ window.addEventListener("keyup", (e) => {
34216
+ if (e.key === "Shift" && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34217
+ this.snappedAngle = null;
34218
+ this.shiftPressed = false;
34219
+ }
34220
+ });
34221
+ stage.on("pointerdown", (e) => {
34222
+ this.setTapStart(e);
34223
+ this.pointers.set(e.evt.pointerId, {
34224
+ x: e.evt.clientX,
34225
+ y: e.evt.clientY
34226
+ });
34227
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34228
+ this.state = WEAVE_STROKE_TOOL_STATE.ADDING;
34229
+ return;
34230
+ }
34231
+ if (!this.tempLineNode && this.state === WEAVE_STROKE_TOOL_STATE.ADDING) this.handleAdding();
34232
+ if (this.tempLineNode && this.state === WEAVE_STROKE_TOOL_STATE.ADDING) this.state = WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE;
34233
+ });
34234
+ stage.on("pointermove", () => {
34235
+ if (this.state === WEAVE_STROKE_TOOL_STATE.IDLE) return;
34236
+ this.setCursor();
34237
+ if (this.pointers.size === 2 && this.instance.getActiveAction() === WEAVE_STROKE_TOOL_ACTION_NAME) {
34238
+ this.state = WEAVE_STROKE_TOOL_STATE.ADDING;
34239
+ return;
34240
+ }
34241
+ if (this.state === WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE) this.handleMovement();
34242
+ });
34243
+ stage.on("pointerup", (e) => {
34244
+ this.pointers.delete(e.evt.pointerId);
34245
+ if (this.state === WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE) this.handleSettingSize();
34246
+ });
34247
+ this.initialized = true;
34248
+ }
34249
+ setState(state) {
34250
+ this.state = state;
34251
+ }
34252
+ addLine() {
34253
+ this.setCursor();
34254
+ this.setFocusStage();
34255
+ this.instance.emitEvent("onAddingStroke", { actionName: this.instance.getActiveAction() ?? WEAVE_STROKE_TOOL_ACTION_NAME });
34256
+ this.shiftPressed = false;
34257
+ this.clickPoint = null;
34258
+ this.setState(WEAVE_STROKE_TOOL_STATE.ADDING);
34259
+ }
34260
+ handleAdding() {
34261
+ const { mousePoint, container, measureContainer } = this.instance.getMousePointer();
34262
+ this.clickPoint = mousePoint;
34263
+ this.container = container;
34264
+ this.measureContainer = measureContainer;
34265
+ this.arrowId = v4_default();
34266
+ this.tempLineId = v4_default();
34267
+ const nodeHandler = this.instance.getNodeHandler(WEAVE_STROKE_SINGLE_NODE_TYPE);
34268
+ if (!this.tempLineNode && nodeHandler) {
34269
+ this.tempLineNode = nodeHandler.onRender({
34270
+ ...this.props,
34271
+ x: this.clickPoint?.x ?? 0,
34272
+ y: this.clickPoint?.y ?? 0,
34273
+ strokeScaleEnabled: true,
34274
+ linePoints: [
34275
+ 0,
34276
+ 0,
34277
+ 1,
34278
+ 1
34279
+ ]
34280
+ });
34281
+ this.measureContainer?.add(this.tempLineNode);
34282
+ this.setState(WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE);
34283
+ }
34284
+ }
34285
+ defineFinalPoint() {
34286
+ if (!this.tempLineNode || !this.measureContainer) return {
34287
+ x: 0,
34288
+ y: 0
34289
+ };
34290
+ const { mousePoint } = this.instance.getMousePointerRelativeToContainer(this.measureContainer);
34291
+ const pos = {
34292
+ x: 0,
34293
+ y: 0
34294
+ };
34295
+ if (this.shiftPressed) {
34296
+ const linePoints = this.tempLineNode.getAttrs().linePoints;
34297
+ let dx = mousePoint.x - (this.tempLineNode.x() + linePoints[0]);
34298
+ let dy = mousePoint.y - (this.tempLineNode.y() + linePoints[1]);
34299
+ const angle = Math.atan2(dy, dx);
34300
+ const angleDeg = angle * 180 / Math.PI;
34301
+ const snapped = this.snapper.apply(angleDeg);
34302
+ const dist = Math.hypot(dx, dy);
34303
+ const rad = snapped * Math.PI / 180;
34304
+ dx = Math.cos(rad) * dist;
34305
+ dy = Math.sin(rad) * dist;
34306
+ pos.x = linePoints[0] + dx;
34307
+ pos.y = linePoints[1] + dy;
34308
+ } else {
34309
+ pos.x = mousePoint.x - this.tempLineNode.x();
34310
+ pos.y = mousePoint.y - this.tempLineNode.y();
34311
+ }
34312
+ return pos;
34313
+ }
34314
+ handleSettingSize() {
34315
+ if (this.arrowId && this.tempLineNode && this.measureContainer) this.cancelAction();
34316
+ }
34317
+ handleMovement() {
34318
+ if (this.state !== WEAVE_STROKE_TOOL_STATE.DEFINING_SIZE) return;
34319
+ const nodeHandler = this.instance.getNodeHandler(WEAVE_STROKE_SINGLE_NODE_TYPE);
34320
+ if (this.tempLineNode && this.measureContainer && nodeHandler) {
34321
+ const pos = this.defineFinalPoint();
34322
+ const linePoints = this.tempLineNode.getAttrs().linePoints;
34323
+ this.tempLineNode.setAttrs({
34324
+ ...this.props,
34325
+ linePoints: [
34326
+ linePoints[0],
34327
+ linePoints[1],
34328
+ pos.x,
34329
+ pos.y
34330
+ ]
34331
+ });
34332
+ nodeHandler.updateLine(this.tempLineNode);
34333
+ }
34334
+ }
34335
+ trigger(cancelAction) {
34336
+ if (!this.instance) throw new Error("Instance not defined");
34337
+ if (!this.initialized) this.setupEvents();
34338
+ const stage = this.instance.getStage();
34339
+ stage.container().tabIndex = 1;
34340
+ stage.container().focus();
34341
+ this.cancelAction = cancelAction;
34342
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34343
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34344
+ this.props = this.initProps();
34345
+ this.addLine();
34346
+ }
34347
+ cleanup() {
34348
+ const stage = this.instance.getStage();
34349
+ this.tempLineNode?.destroy();
34350
+ let nodeCreated = false;
34351
+ if (this.arrowId && this.tempLineNode?.getAttrs().linePoints.length === 4 && !this.tempLineNode?.getAttrs().linePoints.every((coord) => coord === 0)) {
34352
+ const nodeHandler = this.instance.getNodeHandler(WEAVE_STROKE_SINGLE_NODE_TYPE);
34353
+ if (nodeHandler) {
34354
+ const clonedLine = this.tempLineNode.clone();
34355
+ this.tempLineNode.destroy();
34356
+ const finalLine = nodeHandler.create(this.arrowId, {
34357
+ ...this.props,
34358
+ ...clonedLine.getAttrs(),
34359
+ hitStrokeWidth: 16
34360
+ });
34361
+ delete finalLine.props.dragBoundFunc;
34362
+ console.log("node", finalLine);
34363
+ this.instance.addNode(finalLine, this.container?.getAttrs().id);
34364
+ this.instance.emitEvent("onAddedStroke", { actionName: this.instance.getActiveAction() ?? WEAVE_STROKE_TOOL_ACTION_NAME });
34365
+ nodeCreated = true;
34366
+ }
34367
+ }
34368
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34369
+ if (nodeCreated && selectionPlugin) {
34370
+ const node = stage.findOne(`#${this.arrowId}`);
34371
+ if (node) selectionPlugin.setSelectedNodes([node]);
34372
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
34373
+ }
34374
+ stage.container().style.cursor = "default";
34375
+ this.initialCursor = null;
34376
+ this.arrowId = null;
34377
+ this.tempLineId = null;
34378
+ this.tempLineNode = null;
34379
+ this.container = void 0;
34380
+ this.measureContainer = void 0;
34381
+ this.clickPoint = null;
34382
+ this.setState(WEAVE_STROKE_TOOL_STATE.IDLE);
34383
+ }
34384
+ setCursor() {
34385
+ const stage = this.instance.getStage();
34386
+ stage.container().style.cursor = "crosshair";
34387
+ }
34388
+ setFocusStage() {
34389
+ const stage = this.instance.getStage();
34390
+ stage.container().tabIndex = 1;
34391
+ stage.container().blur();
34392
+ stage.container().focus();
34393
+ }
34394
+ };
34395
+
32819
34396
  //#endregion
32820
34397
  //#region src/actions/regular-polygon-tool/constants.ts
32821
34398
  const REGULAR_POLYGON_TOOL_ACTION_NAME = "regularPolygonTool";
@@ -37241,5 +38818,5 @@ function getJSONFromYjsBinary(actualState) {
37241
38818
  }
37242
38819
 
37243
38820
  //#endregion
37244
- export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getJSONFromYjsBinary, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isObject, isServer, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, weavejsToYjsBinary };
38821
+ export { ALIGN_NODES_ALIGN_TO, ALIGN_NODES_TOOL_ACTION_NAME, ALIGN_NODES_TOOL_STATE, ARROW_TOOL_ACTION_NAME, ARROW_TOOL_STATE, BRUSH_TOOL_ACTION_NAME, BRUSH_TOOL_DEFAULT_CONFIG, BRUSH_TOOL_STATE, CONNECTOR_TOOL_ACTION_NAME, CONNECTOR_TOOL_DEFAULT_CONFIG, CONNECTOR_TOOL_STATE, COPY_PASTE_NODES_PLUGIN_STATE, ELLIPSE_TOOL_ACTION_NAME, ELLIPSE_TOOL_STATE, ERASER_TOOL_ACTION_NAME, ERASER_TOOL_STATE, FRAME_TOOL_ACTION_NAME, FRAME_TOOL_STATE, GUIDE_DISTANCE_LINE_DEFAULT_CONFIG, GUIDE_ENTER_SNAPPING_TOLERANCE, GUIDE_EXIT_SNAPPING_TOLERANCE, GUIDE_HORIZONTAL_LINE_NAME, GUIDE_LINE_DEFAULT_CONFIG, GUIDE_LINE_DRAG_SNAPPING_THRESHOLD, GUIDE_LINE_NAME, GUIDE_LINE_TRANSFORM_SNAPPING_THRESHOLD, GUIDE_ORIENTATION, GUIDE_VERTICAL_LINE_NAME, IMAGE_TOOL_ACTION_NAME, IMAGE_TOOL_STATE, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_TOOL_STATE, MEASURE_TOOL_ACTION_NAME, MEASURE_TOOL_STATE, MOVE_TOOL_ACTION_NAME, MOVE_TOOL_STATE, NODE_SNAP, NODE_SNAP_HORIZONTAL, NODE_SNAP_VERTICAL, PEN_TOOL_ACTION_NAME, PEN_TOOL_STATE, RECTANGLE_TOOL_ACTION_NAME, RECTANGLE_TOOL_STATE, REGULAR_POLYGON_TOOL_ACTION_NAME, REGULAR_POLYGON_TOOL_STATE, SELECTION_TOOL_ACTION_NAME, SELECTION_TOOL_STATE, STAGE_MINIMAP_DEFAULT_CONFIG, STAR_TOOL_ACTION_NAME, STAR_TOOL_STATE, TEXT_LAYOUT, TEXT_TOOL_ACTION_NAME, TEXT_TOOL_STATE, VIDEO_TOOL_ACTION_NAME, VIDEO_TOOL_STATE, WEAVE_ARROW_NODE_TYPE, WEAVE_COMMENTS_RENDERER_KEY, WEAVE_COMMENTS_TOOL_LAYER_ID, WEAVE_COMMENT_CREATE_ACTION, WEAVE_COMMENT_NODE_ACTION, WEAVE_COMMENT_NODE_DEFAULTS, WEAVE_COMMENT_NODE_TYPE, WEAVE_COMMENT_STATUS, WEAVE_COMMENT_TOOL_ACTION_NAME, WEAVE_COMMENT_TOOL_DEFAULT_CONFIG, WEAVE_COMMENT_TOOL_STATE, WEAVE_COMMENT_VIEW_ACTION, WEAVE_CONNECTOR_NODE_ANCHOR_ORIGIN, WEAVE_CONNECTOR_NODE_DECORATOR_TYPE, WEAVE_CONNECTOR_NODE_DEFAULT_CONFIG, WEAVE_CONNECTOR_NODE_LINE_ORIGIN, WEAVE_CONNECTOR_NODE_LINE_TYPE, WEAVE_CONNECTOR_NODE_TYPE, WEAVE_COPY_PASTE_CONFIG_DEFAULT, WEAVE_COPY_PASTE_NODES_KEY, WEAVE_COPY_PASTE_PASTE_CATCHER_ID, WEAVE_COPY_PASTE_PASTE_MODES, WEAVE_DEFAULT_USER_INFO_FUNCTION, WEAVE_ELLIPSE_NODE_TYPE, WEAVE_FRAME_DEFAULT_BACKGROUND_COLOR, WEAVE_FRAME_NODE_DEFAULT_CONFIG, WEAVE_FRAME_NODE_DEFAULT_PROPS, WEAVE_FRAME_NODE_TYPE, WEAVE_GRID_DEFAULT_COLOR, WEAVE_GRID_DEFAULT_DOT_MAX_DOTS_PER_AXIS, WEAVE_GRID_DEFAULT_MAJOR_DOT_RATIO, WEAVE_GRID_DEFAULT_MAJOR_EVERY, WEAVE_GRID_DEFAULT_MAJOR_LINE_RATIO, WEAVE_GRID_DEFAULT_ORIGIN_COLOR, WEAVE_GRID_DEFAULT_RADIUS, WEAVE_GRID_DEFAULT_SIZE, WEAVE_GRID_DEFAULT_STROKE, WEAVE_GRID_DEFAULT_TYPE, WEAVE_GRID_LAYER_ID, WEAVE_GRID_TYPES, WEAVE_GROUP_NODE_TYPE, WEAVE_IMAGE_CROP_ANCHOR_POSITION, WEAVE_IMAGE_CROP_END_TYPE, WEAVE_IMAGE_DEFAULT_CONFIG, WEAVE_IMAGE_NODE_TYPE, WEAVE_LAYER_NODE_TYPE, WEAVE_LINE_NODE_DEFAULT_CONFIG, WEAVE_LINE_NODE_TYPE, WEAVE_MEASURE_NODE_DEFAULT_CONFIG, WEAVE_MEASURE_NODE_TYPE, WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, WEAVE_NODES_DISTANCE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_EDGE_SNAPPING_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_DEFAULT_CONFIG, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_KEY, WEAVE_NODES_MULTI_SELECTION_FEEDBACK_PLUGIN_LAYER_ID, WEAVE_NODES_SELECTION_DEFAULT_CONFIG, WEAVE_NODES_SELECTION_KEY, WEAVE_NODES_SELECTION_LAYER_ID, WEAVE_RECTANGLE_NODE_TYPE, WEAVE_REGULAR_POLYGON_NODE_TYPE, WEAVE_STAGE_DEFAULT_MODE, WEAVE_STAGE_GRID_PLUGIN_KEY, WEAVE_STAGE_KEYBOARD_MOVE_DEFAULT_CONFIG, WEAVE_STAGE_KEYBOARD_MOVE_KEY, WEAVE_STAGE_MINIMAP_KEY, WEAVE_STAGE_NODE_TYPE, WEAVE_STAGE_PANNING_DEFAULT_CONFIG, WEAVE_STAGE_PANNING_KEY, WEAVE_STAGE_PANNING_THROTTLE_MS, WEAVE_STAR_NODE_TYPE, WEAVE_STROKE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_NODE_TYPE, WEAVE_STROKE_SINGLE_NODE_DEFAULT_CONFIG, WEAVE_STROKE_SINGLE_NODE_TIP_SIDE, WEAVE_STROKE_SINGLE_NODE_TIP_TYPE, WEAVE_STROKE_SINGLE_NODE_TYPE, WEAVE_STROKE_TOOL_ACTION_NAME, WEAVE_STROKE_TOOL_ACTION_NAME_ALIASES, WEAVE_STROKE_TOOL_DEFAULT_CONFIG, WEAVE_STROKE_TOOL_STATE, WEAVE_TEXT_NODE_TYPE, WEAVE_USERS_POINTERS_CONFIG_DEFAULT_PROPS, WEAVE_USERS_POINTERS_KEY, WEAVE_USERS_PRESENCE_CONFIG_DEFAULT_PROPS, WEAVE_USERS_PRESENCE_PLUGIN_KEY, WEAVE_USERS_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_PRESENCE_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveConnectorNode, WeaveConnectorToolAction, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, WeaveLineToolAction, WeaveMeasureNode, WeaveMeasureToolAction, WeaveMoveToolAction, WeaveNode, WeaveNodesDistanceSnappingPlugin, WeaveNodesEdgeSnappingPlugin, WeaveNodesMultiSelectionFeedbackPlugin, WeaveNodesSelectionPlugin, WeavePenToolAction, WeavePlugin, WeaveRectangleNode, WeaveRectangleToolAction, WeaveRegularPolygonNode, WeaveRegularPolygonToolAction, WeaveSelectionToolAction, WeaveStageDropAreaPlugin, WeaveStageGridPlugin, WeaveStageKeyboardMovePlugin, WeaveStageMinimapPlugin, WeaveStageNode, WeaveStagePanningPlugin, WeaveStageResizePlugin, WeaveStageZoomPlugin, WeaveStarNode, WeaveStarToolAction, WeaveStore, WeaveStrokeNode, WeaveStrokeSingleNode, WeaveStrokeToolAction, WeaveTextNode, WeaveTextToolAction, WeaveUsersPointersPlugin, WeaveUsersPresencePlugin, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getJSONFromYjsBinary, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isArray, isIOS, isInShadowDOM, isNodeInSelection, isObject, isServer, mapJsonToYjsArray, mapJsonToYjsElements, mapJsonToYjsMap, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, weavejsToYjsBinary };
37245
38822
  //# sourceMappingURL=sdk.js.map