@inditextech/weave-sdk 2.10.0 → 2.11.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.node.js CHANGED
@@ -10311,7 +10311,7 @@ var require_lodash = __commonJS({ "../../node_modules/lodash/lodash.js"(exports,
10311
10311
  * _.isNaN(undefined);
10312
10312
  * // => false
10313
10313
  */
10314
- function isNaN(value) {
10314
+ function isNaN$1(value) {
10315
10315
  return isNumber(value) && value != +value;
10316
10316
  }
10317
10317
  /**
@@ -14728,7 +14728,7 @@ var require_lodash = __commonJS({ "../../node_modules/lodash/lodash.js"(exports,
14728
14728
  lodash.isMap = isMap;
14729
14729
  lodash.isMatch = isMatch;
14730
14730
  lodash.isMatchWith = isMatchWith;
14731
- lodash.isNaN = isNaN;
14731
+ lodash.isNaN = isNaN$1;
14732
14732
  lodash.isNative = isNative;
14733
14733
  lodash.isNil = isNil;
14734
14734
  lodash.isNull = isNull;
@@ -15256,6 +15256,7 @@ const WEAVE_NODES_SELECTION_DEFAULT_CONFIG = {
15256
15256
  anchor.offsetX(4);
15257
15257
  }
15258
15258
  },
15259
+ anchorSize: 12,
15259
15260
  borderStroke: "#1a1aff",
15260
15261
  borderStrokeWidth: 2
15261
15262
  },
@@ -20660,6 +20661,7 @@ var WeaveReconciler = class {
20660
20661
  newProps.height = rootContainer.getStageConfiguration().height;
20661
20662
  }
20662
20663
  const element = handler.onRender(newProps);
20664
+ hostContext.emitEvent("onNodeRenderedAdded", element);
20663
20665
  return element;
20664
20666
  },
20665
20667
  detachDeletedInstance(node) {
@@ -21873,7 +21875,7 @@ var WeaveRegisterManager = class {
21873
21875
 
21874
21876
  //#endregion
21875
21877
  //#region package.json
21876
- var version = "2.10.0";
21878
+ var version = "2.11.1";
21877
21879
 
21878
21880
  //#endregion
21879
21881
  //#region src/managers/setup.ts
@@ -22535,6 +22537,10 @@ var Weave = class {
22535
22537
  this.moduleLogger.debug(`Listening event [${event}]`);
22536
22538
  this.emitter.on(event, callback);
22537
22539
  }
22540
+ addOnceEventListener(event, callback) {
22541
+ this.moduleLogger.debug(`Listening once event [${event}]`);
22542
+ this.emitter.once(event).then(callback);
22543
+ }
22538
22544
  removeEventListener(event, callback) {
22539
22545
  this.moduleLogger.debug(`Removing listening to event [${event}]`);
22540
22546
  this.emitter.off(event, callback);
@@ -27005,6 +27011,698 @@ var WeaveVideoNode = class extends WeaveNode {
27005
27011
  }
27006
27012
  };
27007
27013
 
27014
+ //#endregion
27015
+ //#region src/nodes/measure/constants.ts
27016
+ const WEAVE_MEASURE_NODE_TYPE = "measure";
27017
+ const WEAVE_MEASURE_NODE_DEFAULT_CONFIG = { style: {
27018
+ separationLine: {
27019
+ padding: 0,
27020
+ strokeWidth: 1,
27021
+ dash: [],
27022
+ stroke: "#FF3366"
27023
+ },
27024
+ text: {
27025
+ padding: 10,
27026
+ fontSize: 14,
27027
+ fontFamily: "monospace",
27028
+ fill: "#FF3366"
27029
+ },
27030
+ intersectionCircle: {
27031
+ radius: 3,
27032
+ fill: "#FF3366"
27033
+ },
27034
+ measureLine: {
27035
+ stroke: "#FF3366",
27036
+ dash: [4, 4],
27037
+ strokeWidth: 1
27038
+ },
27039
+ handler: {
27040
+ noSpaceSeparationMultiplier: 2.5,
27041
+ spaceSeparationMultiplier: 1.5
27042
+ }
27043
+ } };
27044
+
27045
+ //#endregion
27046
+ //#region src/nodes/measure/measure.ts
27047
+ var WeaveMeasureNode = class extends WeaveNode {
27048
+ nodeType = WEAVE_MEASURE_NODE_TYPE;
27049
+ handlePointCircleRadius = 6;
27050
+ constructor(params) {
27051
+ super();
27052
+ this.config = mergeExceptArrays(WEAVE_MEASURE_NODE_DEFAULT_CONFIG, params?.config ?? {});
27053
+ }
27054
+ onRender(props) {
27055
+ const measure = new Konva.Group({
27056
+ ...props,
27057
+ name: "node",
27058
+ draggable: false
27059
+ });
27060
+ const fromPoint = props.fromPoint;
27061
+ const toPoint = props.toPoint;
27062
+ const separation = props.separation ?? 100;
27063
+ const orientation = props.orientation ?? -1;
27064
+ const unit = props.unit ?? "cms";
27065
+ const unitPerPixel = props.unitPerPixel ?? 100;
27066
+ const measureLine = this.config.style.measureLine;
27067
+ const intersectionCircle = this.config.style.intersectionCircle;
27068
+ const separationLine = this.config.style.separationLine;
27069
+ const textConfig = this.config.style.text;
27070
+ const fromFinalPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, (separation + separationLine.padding) * orientation);
27071
+ const linePerpFrom = new Konva.Line({
27072
+ id: `linePerpFrom-${props.id}`,
27073
+ nodeId: props.id,
27074
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27075
+ points: [
27076
+ fromPoint.x,
27077
+ fromPoint.y,
27078
+ fromFinalPerp.left.x,
27079
+ fromFinalPerp.left.y
27080
+ ],
27081
+ stroke: separationLine.stroke,
27082
+ strokeWidth: separationLine.strokeWidth,
27083
+ dash: separationLine.dash
27084
+ });
27085
+ measure.add(linePerpFrom);
27086
+ const toFinalPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, (separation + separationLine.padding) * orientation);
27087
+ const linePerpTo = new Konva.Line({
27088
+ id: `linePerpTo-${props.id}`,
27089
+ nodeId: props.id,
27090
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27091
+ points: [
27092
+ toPoint.x,
27093
+ toPoint.y,
27094
+ toFinalPerp.left.x,
27095
+ toFinalPerp.left.y
27096
+ ],
27097
+ stroke: separationLine.stroke,
27098
+ strokeWidth: separationLine.strokeWidth,
27099
+ dash: separationLine.dash
27100
+ });
27101
+ measure.add(linePerpTo);
27102
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
27103
+ const fromCircle = new Konva.Circle({
27104
+ id: `fromCircle-${props.id}`,
27105
+ nodeId: props.id,
27106
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27107
+ x: fromPerp.left.x,
27108
+ y: fromPerp.left.y,
27109
+ radius: intersectionCircle.radius,
27110
+ fill: intersectionCircle.fill
27111
+ });
27112
+ measure.add(fromCircle);
27113
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
27114
+ const toCircle = new Konva.Circle({
27115
+ id: `toCircle-${props.id}`,
27116
+ nodeId: props.id,
27117
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27118
+ x: toPerp.left.x,
27119
+ y: toPerp.left.y,
27120
+ radius: intersectionCircle.radius,
27121
+ fill: intersectionCircle.fill
27122
+ });
27123
+ measure.add(toCircle);
27124
+ const midPoint = this.midPoint(fromPerp.left, toPerp.left);
27125
+ const distance = this.distanceBetweenPoints(fromPoint, toPoint);
27126
+ const units = distance / unitPerPixel;
27127
+ const text = `${units.toFixed(2)} ${unit}`;
27128
+ const measureText = new Konva.Text({
27129
+ id: `measureText-${props.id}`,
27130
+ nodeId: props.id,
27131
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27132
+ x: midPoint.x,
27133
+ y: midPoint.y,
27134
+ text,
27135
+ fontFamily: textConfig.fontFamily,
27136
+ fontSize: textConfig.fontSize,
27137
+ verticalAlign: "middle",
27138
+ align: "center",
27139
+ fill: textConfig.fill
27140
+ });
27141
+ const angle = this.getAngle(fromPoint, toPoint);
27142
+ const textSize = measureText.measureSize(text);
27143
+ const textOffsetX = textSize.width / 2;
27144
+ measureText.rotation(angle);
27145
+ measureText.offsetX(textSize.width / 2);
27146
+ measureText.offsetY(textSize.height / 2);
27147
+ if (textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left)) {
27148
+ const perpPointTextMid = this.perpendicularPoint(fromPerp.left, toPerp.left, midPoint, (textSize.height + separationLine.padding) * orientation);
27149
+ measureText.x(perpPointTextMid.left.x);
27150
+ measureText.y(perpPointTextMid.left.y);
27151
+ }
27152
+ measure.add(measureText);
27153
+ const pointLeftText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, false);
27154
+ const pointRightText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, true);
27155
+ const lineLeft = new Konva.Line({
27156
+ id: `lineLeft-${props.id}`,
27157
+ nodeId: props.id,
27158
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27159
+ points: [
27160
+ fromPerp.left.x,
27161
+ fromPerp.left.y,
27162
+ pointLeftText.x,
27163
+ pointLeftText.y
27164
+ ],
27165
+ dash: measureLine.dash,
27166
+ stroke: measureLine.stroke,
27167
+ strokeWidth: measureLine.strokeWidth
27168
+ });
27169
+ const lineRight = new Konva.Line({
27170
+ id: `lineRight-${props.id}`,
27171
+ nodeId: props.id,
27172
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
27173
+ points: [
27174
+ pointRightText.x,
27175
+ pointRightText.y,
27176
+ toPerp.left.x,
27177
+ toPerp.left.y
27178
+ ],
27179
+ dash: measureLine.dash,
27180
+ stroke: measureLine.stroke,
27181
+ strokeWidth: measureLine.strokeWidth
27182
+ });
27183
+ measure.add(measureText);
27184
+ measure.add(lineLeft);
27185
+ measure.add(lineRight);
27186
+ this.setupDefaultNodeAugmentation(measure);
27187
+ measure.getTransformerProperties = function() {
27188
+ return {
27189
+ resizeEnabled: false,
27190
+ rotateEnabled: false,
27191
+ borderEnabled: false
27192
+ };
27193
+ };
27194
+ this.instance.addEventListener("onZoomChange", () => {
27195
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
27196
+ if (selectionPlugin) {
27197
+ const selectedNodes = selectionPlugin.getSelectedNodes();
27198
+ if (selectedNodes.length === 1 && selectedNodes[0].getAttrs().id === measure.getAttrs().id) this.updateSelectionHandlers(measure);
27199
+ }
27200
+ });
27201
+ this.instance.addEventListener("onNodesChange", () => {
27202
+ let isSelected = false;
27203
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
27204
+ if (selectionPlugin) {
27205
+ const selectedNodes = selectionPlugin.getSelectedNodes();
27206
+ if (selectedNodes.length === 1 && selectedNodes[0].getAttrs().id === measure.getAttrs().id) {
27207
+ isSelected = true;
27208
+ this.createSelectionHandlers(measure);
27209
+ this.updateSelectionHandlers(measure);
27210
+ }
27211
+ }
27212
+ if (!isSelected) this.destroySelectionHandlers(measure);
27213
+ });
27214
+ this.instance.addEventListener("onMeasureReferenceChange", ({ unit: unit$1, unitPerPixel: unitPerPixel$1 }) => {
27215
+ measure.setAttrs({
27216
+ unit: unit$1,
27217
+ unitPerPixel: unitPerPixel$1
27218
+ });
27219
+ this.instance.updateNode(this.serialize(measure));
27220
+ });
27221
+ measure.allowedAnchors = function() {
27222
+ return [];
27223
+ };
27224
+ this.setupDefaultNodeEvents(measure);
27225
+ return measure;
27226
+ }
27227
+ createSelectionHandlers(node) {
27228
+ const props = node.getAttrs();
27229
+ const fromPoint = props.fromPoint;
27230
+ const toPoint = props.toPoint;
27231
+ const separation = props.separation ?? 100;
27232
+ const orientation = props.orientation ?? -1;
27233
+ const angle = this.getAngle(fromPoint, toPoint);
27234
+ const moveToCircleAct = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
27235
+ const crosshairFromAct = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
27236
+ const moveFromCircleAct = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
27237
+ const crosshairToAct = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
27238
+ const moveSeparationRectAct = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
27239
+ const measureText = node.findOne(`#measureText-${node.getAttrs().id}`);
27240
+ if (moveToCircleAct && crosshairFromAct && moveFromCircleAct && crosshairToAct && moveSeparationRectAct) return;
27241
+ const textSize = measureText?.measureSize(measureText.text());
27242
+ const moveFromCircle = new Konva.Circle({
27243
+ id: `moveFromCircle-${props.id}`,
27244
+ edgeDistanceDisableOnDrag: true,
27245
+ edgeSnappingDisableOnDrag: true,
27246
+ x: fromPoint.x,
27247
+ y: fromPoint.y,
27248
+ radius: this.handlePointCircleRadius,
27249
+ fill: "#FFFFFF",
27250
+ stroke: "#000000",
27251
+ strokeWidth: 1,
27252
+ draggable: true
27253
+ });
27254
+ const crosshairFrom = this.buildCrosshair("crosshairFrom", node, fromPoint, angle);
27255
+ const moveToCircle = new Konva.Circle({
27256
+ id: `moveToCircle-${props.id}`,
27257
+ edgeDistanceDisableOnDrag: true,
27258
+ edgeSnappingDisableOnDrag: true,
27259
+ x: toPoint.x,
27260
+ y: toPoint.y,
27261
+ radius: this.handlePointCircleRadius,
27262
+ fill: "#FFFFFF",
27263
+ stroke: "#000000",
27264
+ strokeWidth: 1,
27265
+ draggable: true
27266
+ });
27267
+ const crosshairTo = this.buildCrosshair("crosshairTo", node, toPoint, angle);
27268
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
27269
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
27270
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
27271
+ const isTextBiggerThanMeasureSpace = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
27272
+ const multiplier = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
27273
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, multiplier * (textSize?.height ?? 0) * orientation);
27274
+ const moveSeparationRect = new Konva.Rect({
27275
+ id: `moveSeparationRect-${props.id}`,
27276
+ edgeDistanceDisableOnDrag: true,
27277
+ edgeSnappingDisableOnDrag: true,
27278
+ x: separatorPoint.left.x,
27279
+ y: separatorPoint.left.y,
27280
+ width: this.handlePointCircleRadius * 2 * 3,
27281
+ height: this.handlePointCircleRadius * 2,
27282
+ offsetX: this.handlePointCircleRadius * 3,
27283
+ offsetY: this.handlePointCircleRadius,
27284
+ cornerRadius: this.handlePointCircleRadius,
27285
+ rotation: angle,
27286
+ fill: "#FFFFFF",
27287
+ stroke: "#000000",
27288
+ strokeWidth: 1,
27289
+ draggable: true
27290
+ });
27291
+ node.add(moveFromCircle);
27292
+ node.add(crosshairFrom);
27293
+ node.add(moveToCircle);
27294
+ node.add(crosshairTo);
27295
+ node.add(moveSeparationRect);
27296
+ moveFromCircle.moveToTop();
27297
+ crosshairFrom.moveToBottom();
27298
+ moveToCircle.moveToTop();
27299
+ crosshairTo.moveToBottom();
27300
+ moveSeparationRect.moveToTop();
27301
+ moveFromCircle.on("dragstart", () => {
27302
+ moveFromCircle.visible(false);
27303
+ moveToCircle.visible(false);
27304
+ moveSeparationRect.visible(false);
27305
+ crosshairFrom.visible(true);
27306
+ });
27307
+ moveFromCircle.on("dragmove", (e) => {
27308
+ const actCircle = e.target;
27309
+ const realNode = e.target.getParent();
27310
+ const newFromPoint = {
27311
+ x: actCircle.x(),
27312
+ y: actCircle.y()
27313
+ };
27314
+ realNode.setAttrs({ fromPoint: newFromPoint });
27315
+ this.onUpdate(realNode, this.serialize(realNode).props);
27316
+ });
27317
+ moveFromCircle.on("dragend", (e) => {
27318
+ const actCircle = e.target;
27319
+ const realNode = e.target.getParent();
27320
+ moveFromCircle.visible(true);
27321
+ moveToCircle.visible(true);
27322
+ moveSeparationRect.visible(true);
27323
+ crosshairFrom.visible(false);
27324
+ const newFromPoint = {
27325
+ x: actCircle.x(),
27326
+ y: actCircle.y()
27327
+ };
27328
+ realNode.setAttrs({ fromPoint: newFromPoint });
27329
+ this.instance.updateNode(this.serialize(realNode));
27330
+ });
27331
+ moveToCircle.on("dragstart", () => {
27332
+ moveFromCircle.visible(false);
27333
+ moveToCircle.visible(false);
27334
+ moveSeparationRect.visible(false);
27335
+ crosshairTo.visible(true);
27336
+ });
27337
+ moveToCircle.on("dragmove", (e) => {
27338
+ const actCircle = e.target;
27339
+ const realNode = e.target.getParent();
27340
+ const newToPoint = {
27341
+ x: actCircle.x(),
27342
+ y: actCircle.y()
27343
+ };
27344
+ realNode.setAttrs({ toPoint: newToPoint });
27345
+ this.onUpdate(realNode, this.serialize(realNode).props);
27346
+ });
27347
+ moveToCircle.on("dragend", (e) => {
27348
+ const actCircle = e.target;
27349
+ const realNode = e.target.getParent();
27350
+ moveFromCircle.visible(true);
27351
+ moveToCircle.visible(true);
27352
+ moveSeparationRect.visible(true);
27353
+ crosshairTo.visible(false);
27354
+ const newToPoint = {
27355
+ x: actCircle.x(),
27356
+ y: actCircle.y()
27357
+ };
27358
+ realNode.setAttrs({ toPoint: newToPoint });
27359
+ this.instance.updateNode(this.serialize(realNode));
27360
+ });
27361
+ let originalSeparationHandlerPosition = {
27362
+ x: 0,
27363
+ y: 0
27364
+ };
27365
+ moveSeparationRect.on("dragstart", () => {
27366
+ const pos = moveSeparationRect.position();
27367
+ originalSeparationHandlerPosition = pos;
27368
+ });
27369
+ moveSeparationRect.on("dragmove", (e) => {
27370
+ const pos = e.target.position();
27371
+ const realNode = e.target.getParent();
27372
+ const fromPoint$1 = node.getAttrs().fromPoint;
27373
+ const toPoint$1 = node.getAttrs().toPoint;
27374
+ const midPoint = this.midPoint(fromPoint$1, toPoint$1);
27375
+ const isTextBiggerThanMeasureSpace$1 = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
27376
+ const multiplier$1 = isTextBiggerThanMeasureSpace$1 ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
27377
+ const separatorPoint$1 = this.perpendicularPoint(fromPoint$1, toPoint$1, midPoint, multiplier$1 * (textSize?.height ?? 0) * orientation);
27378
+ const pointInLine = this.projectPointToLine(separatorPoint$1.left, originalSeparationHandlerPosition, pos);
27379
+ if (isNaN(pointInLine.t)) {
27380
+ const point = this.movePointPerpendicularToLine(fromPoint$1, toPoint$1, separatorPoint$1.left, (multiplier$1 * (textSize?.height ?? 0) + 1) * orientation);
27381
+ moveSeparationRect.position(point);
27382
+ originalSeparationHandlerPosition = point;
27383
+ realNode.setAttrs({ separation: (textSize?.height ?? 0) + 1 });
27384
+ } else {
27385
+ moveSeparationRect.position(pointInLine);
27386
+ const dx = originalSeparationHandlerPosition.x - separatorPoint$1.left.x;
27387
+ const dy = originalSeparationHandlerPosition.y - separatorPoint$1.left.y;
27388
+ const len = Math.hypot(dx, dy);
27389
+ let newLength = pointInLine.t * len;
27390
+ if (newLength < 0) newLength = 0;
27391
+ realNode.setAttrs({ separation: newLength });
27392
+ }
27393
+ this.onUpdate(realNode, this.serialize(realNode).props);
27394
+ });
27395
+ moveSeparationRect.on("dragend", (e) => {
27396
+ const pos = e.target.position();
27397
+ const realNode = e.target.getParent();
27398
+ const fromPoint$1 = node.getAttrs().fromPoint;
27399
+ const toPoint$1 = node.getAttrs().toPoint;
27400
+ const midPoint = this.midPoint(fromPoint$1, toPoint$1);
27401
+ const multiplier$1 = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
27402
+ const separatorPoint$1 = this.perpendicularPoint(fromPoint$1, toPoint$1, midPoint, multiplier$1 * (textSize?.height ?? 0) * orientation);
27403
+ const pointInLine = this.projectPointToLine(separatorPoint$1.left, originalSeparationHandlerPosition, pos);
27404
+ moveSeparationRect.position(pointInLine);
27405
+ const dx = originalSeparationHandlerPosition.x - separatorPoint$1.left.x;
27406
+ const dy = originalSeparationHandlerPosition.y - separatorPoint$1.left.y;
27407
+ const len = Math.hypot(dx, dy);
27408
+ let newLength = pointInLine.t * len;
27409
+ if (newLength < 0) newLength = 0;
27410
+ realNode.setAttrs({ separation: newLength });
27411
+ this.instance.updateNode(this.serialize(realNode));
27412
+ });
27413
+ }
27414
+ updateSelectionHandlers(node) {
27415
+ const stage = this.instance.getStage();
27416
+ const scale = stage.scaleX();
27417
+ const fromPoint = node.getAttrs().fromPoint;
27418
+ const toPoint = node.getAttrs().toPoint;
27419
+ const moveToCircle = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
27420
+ const crosshairFrom = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
27421
+ const moveFromCircle = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
27422
+ const crosshairTo = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
27423
+ const moveSeparationRect = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
27424
+ if (moveToCircle) moveToCircle.scale({
27425
+ x: 1 / scale,
27426
+ y: 1 / scale
27427
+ });
27428
+ if (crosshairFrom) crosshairFrom.scale({
27429
+ x: 1 / scale,
27430
+ y: 1 / scale
27431
+ });
27432
+ if (moveFromCircle) moveFromCircle.scale({
27433
+ x: 1 / scale,
27434
+ y: 1 / scale
27435
+ });
27436
+ if (crosshairTo) crosshairTo.scale({
27437
+ x: 1 / scale,
27438
+ y: 1 / scale
27439
+ });
27440
+ if (moveSeparationRect) {
27441
+ const measureText = node.findOne(`#measureText-${node.getAttrs().id}`);
27442
+ const angle = this.getAngle(fromPoint, toPoint);
27443
+ const textSize = measureText?.measureSize(measureText.text());
27444
+ const separation = node.getAttrs().separation ?? 100;
27445
+ const orientation = node.getAttrs().orientation ?? -1;
27446
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
27447
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
27448
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
27449
+ const isTextBiggerThanMeasureSpace = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
27450
+ const multiplier = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
27451
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, multiplier * (textSize?.height ?? 0) * orientation);
27452
+ moveSeparationRect.x(separatorPoint.left.x);
27453
+ moveSeparationRect.y(separatorPoint.left.y);
27454
+ moveSeparationRect.rotation(angle);
27455
+ moveSeparationRect.scale({
27456
+ x: 1 / scale,
27457
+ y: 1 / scale
27458
+ });
27459
+ }
27460
+ }
27461
+ destroySelectionHandlers(node) {
27462
+ const moveToCircle = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
27463
+ const crosshairFrom = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
27464
+ const moveFromCircle = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
27465
+ const crosshairTo = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
27466
+ const moveSeparationRect = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
27467
+ if (moveToCircle) moveToCircle.destroy();
27468
+ if (crosshairFrom) crosshairFrom.destroy();
27469
+ if (moveFromCircle) moveFromCircle.destroy();
27470
+ if (crosshairTo) crosshairTo.destroy();
27471
+ if (moveSeparationRect) moveSeparationRect.destroy();
27472
+ }
27473
+ pointFromMid(from, to, distance, towardsSecond = true) {
27474
+ const mx = (from.x + to.x) / 2;
27475
+ const my = (from.y + to.y) / 2;
27476
+ const dx = to.x - from.x;
27477
+ const dy = to.y - from.y;
27478
+ const len = Math.hypot(dx, dy);
27479
+ const ux = dx / len;
27480
+ const uy = dy / len;
27481
+ const sign = towardsSecond ? 1 : -1;
27482
+ return {
27483
+ x: mx + ux * distance * sign,
27484
+ y: my + uy * distance * sign
27485
+ };
27486
+ }
27487
+ angleBetweenPoints(from, to) {
27488
+ return Math.atan2(to.y - from.y, to.x - from.x) * 180 / Math.PI;
27489
+ }
27490
+ midPoint(from, to) {
27491
+ return {
27492
+ x: (from.x + to.x) / 2,
27493
+ y: (from.y + to.y) / 2
27494
+ };
27495
+ }
27496
+ perpendicularPoint(from, to, point, distance) {
27497
+ const dx = to.x - from.x;
27498
+ const dy = to.y - from.y;
27499
+ const perpX = -dy;
27500
+ const perpY = dx;
27501
+ const len = Math.hypot(perpX, perpY);
27502
+ const ux = perpX / len;
27503
+ const uy = perpY / len;
27504
+ return {
27505
+ left: {
27506
+ x: point.x + ux * distance,
27507
+ y: point.y + uy * distance
27508
+ },
27509
+ right: {
27510
+ x: point.x - ux * distance,
27511
+ y: point.y - uy * distance
27512
+ }
27513
+ };
27514
+ }
27515
+ distanceBetweenPoints(from, to) {
27516
+ return Math.hypot(to.x - from.x, to.y - from.y);
27517
+ }
27518
+ onUpdate(nodeInstance, nextProps) {
27519
+ nodeInstance.setAttrs({ ...nextProps });
27520
+ const measure = nodeInstance;
27521
+ const fromPoint = nextProps.fromPoint;
27522
+ const toPoint = nextProps.toPoint;
27523
+ const separation = nextProps.separation ?? 100;
27524
+ const orientation = nextProps.orientation ?? -1;
27525
+ const unit = nextProps.unit ?? "cms";
27526
+ const unitPerPixel = nextProps.unitPerPixel ?? 100;
27527
+ const separationLine = this.config.style.separationLine;
27528
+ const textConfig = this.config.style.text;
27529
+ const fromFinalPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, (separation + separationLine.padding) * orientation);
27530
+ const linePerpFrom = measure.findOne(`#linePerpFrom-${nextProps.id}`);
27531
+ linePerpFrom?.points([
27532
+ fromPoint.x,
27533
+ fromPoint.y,
27534
+ fromFinalPerp.left.x,
27535
+ fromFinalPerp.left.y
27536
+ ]);
27537
+ const toFinalPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, (separation + separationLine.padding) * orientation);
27538
+ const linePerpTo = measure.findOne(`#linePerpTo-${nextProps.id}`);
27539
+ linePerpTo?.points([
27540
+ toPoint.x,
27541
+ toPoint.y,
27542
+ toFinalPerp.left.x,
27543
+ toFinalPerp.left.y
27544
+ ]);
27545
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
27546
+ const fromCircle = measure.findOne(`#fromCircle-${nextProps.id}`);
27547
+ fromCircle?.position({
27548
+ x: fromPerp.left.x,
27549
+ y: fromPerp.left.y
27550
+ });
27551
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
27552
+ const toCircle = measure.findOne(`#toCircle-${nextProps.id}`);
27553
+ toCircle?.position({
27554
+ x: toPerp.left.x,
27555
+ y: toPerp.left.y
27556
+ });
27557
+ const midPoint = this.midPoint(fromPerp.left, toPerp.left);
27558
+ const distance = this.distanceBetweenPoints(fromPoint, toPoint);
27559
+ const units = distance / unitPerPixel;
27560
+ const text = `${units.toFixed(2)} ${unit}`;
27561
+ const measureText = measure.findOne(`#measureText-${nextProps.id}`);
27562
+ const angle = this.getAngle(fromPoint, toPoint);
27563
+ const textSize = measureText.measureSize(text);
27564
+ const textOffsetX = textSize.width / 2;
27565
+ measureText?.text(text);
27566
+ measureText?.rotation(angle);
27567
+ measureText?.x(midPoint.x);
27568
+ measureText?.y(midPoint.y);
27569
+ measureText?.offsetX(textSize.width / 2);
27570
+ measureText?.offsetY(textSize.height / 2);
27571
+ if (textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left)) {
27572
+ const perpPointTextMid = this.perpendicularPoint(fromPerp.left, toPerp.left, midPoint, (textSize.height + separationLine.padding) * orientation);
27573
+ measureText.x(perpPointTextMid.left.x);
27574
+ measureText.y(perpPointTextMid.left.y);
27575
+ }
27576
+ const pointLeftText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, false);
27577
+ const pointRightText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, true);
27578
+ const lineLeft = measure.findOne(`#lineLeft-${nextProps.id}`);
27579
+ lineLeft?.points([
27580
+ fromPerp.left.x,
27581
+ fromPerp.left.y,
27582
+ pointLeftText.x,
27583
+ pointLeftText.y
27584
+ ]);
27585
+ const lineRight = measure.findOne(`#lineRight-${nextProps.id}`);
27586
+ lineRight?.points([
27587
+ pointRightText.x,
27588
+ pointRightText.y,
27589
+ toPerp.left.x,
27590
+ toPerp.left.y
27591
+ ]);
27592
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
27593
+ const crosshairFrom = measure.findOne(`#crosshairFrom-${measure.getAttrs().id}`);
27594
+ if (crosshairFrom) {
27595
+ crosshairFrom.x(fromPoint.x);
27596
+ crosshairFrom.y(fromPoint.y);
27597
+ crosshairFrom.rotation(angle);
27598
+ }
27599
+ const crosshairTo = measure.findOne(`#crosshairTo-${measure.getAttrs().id}`);
27600
+ if (crosshairTo) {
27601
+ crosshairTo.x(toPoint.x);
27602
+ crosshairTo.y(toPoint.y);
27603
+ crosshairTo.rotation(angle);
27604
+ }
27605
+ const moveSeparationRect = measure.findOne(`#moveSeparationRect-${measure.getAttrs().id}`);
27606
+ if (moveSeparationRect) {
27607
+ const textSize$1 = measureText.measureSize(measureText.text());
27608
+ const isTextBiggerThanMeasureSpace = textSize$1.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
27609
+ const multiplier = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
27610
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, multiplier * textSize$1.height * orientation);
27611
+ moveSeparationRect.x(separatorPoint.left.x);
27612
+ moveSeparationRect.y(separatorPoint.left.y);
27613
+ moveSeparationRect.rotation(angle);
27614
+ }
27615
+ }
27616
+ projectPointToLine(fromPoint, toPoint, pointToProject) {
27617
+ const dx = toPoint.x - fromPoint.x;
27618
+ const dy = toPoint.y - fromPoint.y;
27619
+ const lenSq = dx * dx + dy * dy;
27620
+ const t = ((pointToProject.x - fromPoint.x) * dx + (pointToProject.y - fromPoint.y) * dy) / lenSq;
27621
+ return {
27622
+ x: fromPoint.x + t * dx,
27623
+ y: fromPoint.y + t * dy,
27624
+ t,
27625
+ flipped: t < 0
27626
+ };
27627
+ }
27628
+ buildCrosshair(name, node, point, angle) {
27629
+ const props = node.getAttrs();
27630
+ const crosshairSize = 60;
27631
+ const crosshair = new Konva.Group({
27632
+ id: `${name}-${props.id}`,
27633
+ x: point.x,
27634
+ y: point.y,
27635
+ rotation: angle,
27636
+ visible: false,
27637
+ listening: false,
27638
+ draggable: false
27639
+ });
27640
+ const horizontalLineFrom = new Konva.Line({
27641
+ points: [
27642
+ 0,
27643
+ 0,
27644
+ crosshairSize,
27645
+ 0
27646
+ ],
27647
+ x: -1 * (crosshairSize / 2),
27648
+ y: 0,
27649
+ stroke: "#CC0000",
27650
+ strokeWidth: 1
27651
+ });
27652
+ const verticalLineFrom = new Konva.Line({
27653
+ points: [
27654
+ 0,
27655
+ 0,
27656
+ 0,
27657
+ crosshairSize
27658
+ ],
27659
+ x: 0,
27660
+ y: -1 * crosshairSize / 2,
27661
+ stroke: "#CC0000",
27662
+ strokeWidth: 1
27663
+ });
27664
+ crosshair.add(horizontalLineFrom);
27665
+ crosshair.add(verticalLineFrom);
27666
+ return crosshair;
27667
+ }
27668
+ movePointPerpendicularToLine(fromPoint, toPoint, point, distance) {
27669
+ const dx = toPoint.x - fromPoint.x;
27670
+ const dy = toPoint.y - fromPoint.y;
27671
+ const len = Math.hypot(dx, dy);
27672
+ const ux = -dy / len;
27673
+ const uy = dx / len;
27674
+ return {
27675
+ x: point.x + ux * distance,
27676
+ y: point.y + uy * distance
27677
+ };
27678
+ }
27679
+ getAngle(fromPoint, toPoint) {
27680
+ let angle = this.angleBetweenPoints(fromPoint, toPoint);
27681
+ if (fromPoint.x > toPoint.x) angle = angle + 180;
27682
+ return angle;
27683
+ }
27684
+ flipOrientation(node) {
27685
+ this.destroySelectionHandlers(node);
27686
+ const currentOrientation = node.getAttrs().orientation ?? -1;
27687
+ node.setAttrs({ orientation: currentOrientation * -1 });
27688
+ this.instance.updateNode(this.serialize(node));
27689
+ this.createSelectionHandlers(node);
27690
+ this.updateSelectionHandlers(node);
27691
+ }
27692
+ getNormalizedDistance(node) {
27693
+ const stage = this.instance.getStage();
27694
+ const scale = stage.scaleX();
27695
+ const fromCircle = node.findOne(`#fromCircle-${node.getAttrs().id}`);
27696
+ const toCircle = node.findOne(`#toCircle-${node.getAttrs().id}`);
27697
+ if (fromCircle && toCircle) {
27698
+ const fromPoint = fromCircle.getAbsolutePosition();
27699
+ const toPoint = toCircle.getAbsolutePosition();
27700
+ return Math.hypot(toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) / scale;
27701
+ }
27702
+ return 0;
27703
+ }
27704
+ };
27705
+
27008
27706
  //#endregion
27009
27707
  //#region src/plugins/stage-zoom/constants.ts
27010
27708
  const WEAVE_STAGE_ZOOM_TYPE = {
@@ -30759,6 +31457,17 @@ var WeaveVideoToolAction = class extends WeaveAction {
30759
31457
  }
30760
31458
  };
30761
31459
 
31460
+ //#endregion
31461
+ //#region src/actions/measure-tool/constants.ts
31462
+ const MEASURE_TOOL_ACTION_NAME = "measureTool";
31463
+ const MEASURE_TOOL_STATE = {
31464
+ ["IDLE"]: "idle",
31465
+ ["SET_FROM"]: "set_from",
31466
+ ["SET_TO"]: "set_to",
31467
+ ["FINISHED"]: "finished"
31468
+ };
31469
+ const WEAVE_MEASURE_TOOL_DEFAULT_CONFIG = { style: { stroke: "#FF3366" } };
31470
+
30762
31471
  //#endregion
30763
31472
  //#region src/plugins/stage-grid/stage-grid.ts
30764
31473
  var WeaveStageGridPlugin = class extends WeavePlugin {
@@ -31474,6 +32183,11 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
31474
32183
  const containerParent = stage.container().parentNode;
31475
32184
  if (!this.enabled) return;
31476
32185
  if (containerParent) {
32186
+ const upscaleScale = stage.getAttr("upscaleScale");
32187
+ if (upscaleScale === 1) {
32188
+ stage.width(containerParent.clientWidth);
32189
+ stage.height(containerParent.clientHeight);
32190
+ }
31477
32191
  setupUpscaleStage(this.instance, stage);
31478
32192
  const plugins = this.instance.getPlugins();
31479
32193
  for (const pluginId of Object.keys(plugins)) {
@@ -31483,11 +32197,14 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
31483
32197
  }
31484
32198
  }
31485
32199
  onInit() {
31486
- window.addEventListener("resize", () => {
32200
+ const throttledResize = (0, import_lodash.throttle)(() => {
31487
32201
  this.resizeStage();
32202
+ }, 100);
32203
+ window.addEventListener("resize", () => {
32204
+ throttledResize();
31488
32205
  });
31489
32206
  const resizeObserver = new ResizeObserver(() => {
31490
- this.resizeStage();
32207
+ throttledResize();
31491
32208
  });
31492
32209
  const stage = this.instance.getStage();
31493
32210
  resizeObserver.observe(stage.container());
@@ -32139,7 +32856,9 @@ var WeaveNodesEdgeSnappingPlugin = class extends WeavePlugin {
32139
32856
  const utilityLayer = this.instance.getUtilityLayer();
32140
32857
  if (!this.enabled) return;
32141
32858
  if (!utilityLayer) return;
32859
+ if (e.target.getAttr("edgeSnappingDisableOnDrag")) return;
32142
32860
  const { targetNode: node, skipNodes } = getTargetAndSkipNodes(this.instance, e);
32861
+ if (node?.getAttr("edgeSnappingDisable")) return;
32143
32862
  if (typeof node === "undefined") return;
32144
32863
  const nodeParent = this.getSelectionParentNode(node);
32145
32864
  if (nodeParent === null) return;
@@ -33204,5 +33923,276 @@ var WeaveStageKeyboardMovePlugin = class extends WeavePlugin {
33204
33923
  };
33205
33924
 
33206
33925
  //#endregion
33207
- 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, 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, 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_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_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_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_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, 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, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, setupCanvasBackend, setupSkiaBackend };
33926
+ //#region src/actions/measure-tool/measure-tool.ts
33927
+ var WeaveMeasureToolAction = class extends WeaveAction {
33928
+ initialized = false;
33929
+ initialCursor = null;
33930
+ onPropsChange = void 0;
33931
+ onInit = void 0;
33932
+ constructor(params) {
33933
+ super();
33934
+ this.config = mergeExceptArrays(WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, params?.config ?? {});
33935
+ this.initialized = false;
33936
+ this.state = MEASURE_TOOL_STATE.IDLE;
33937
+ this.measureId = null;
33938
+ this.container = void 0;
33939
+ this.clickPoint = null;
33940
+ this.crosshairCursor = null;
33941
+ this.firstPoint = null;
33942
+ this.measureLine = null;
33943
+ this.measureContainer = void 0;
33944
+ this.props = this.initProps();
33945
+ }
33946
+ getName() {
33947
+ return MEASURE_TOOL_ACTION_NAME;
33948
+ }
33949
+ initProps() {
33950
+ return {
33951
+ orientation: -1,
33952
+ separation: 0,
33953
+ unit: "cm",
33954
+ unitPerPixel: 10
33955
+ };
33956
+ }
33957
+ setupEvents() {
33958
+ const stage = this.instance.getStage();
33959
+ window.addEventListener("keydown", (e) => {
33960
+ if (e.code === "Escape" && this.instance.getActiveAction() === MEASURE_TOOL_ACTION_NAME) this.cancelAction();
33961
+ });
33962
+ stage.on("pointermove", () => {
33963
+ if (this.state === MEASURE_TOOL_STATE.IDLE) return;
33964
+ if (this.state === MEASURE_TOOL_STATE.SET_TO) {
33965
+ const finalPoint = this.defineFinalPoint();
33966
+ if (this.measureLine && this.firstPoint) this.measureLine.points([
33967
+ 0,
33968
+ 0,
33969
+ finalPoint.x,
33970
+ finalPoint.y
33971
+ ]);
33972
+ }
33973
+ this.setCursor();
33974
+ });
33975
+ stage.on("pointerclick", () => {
33976
+ if (this.state === MEASURE_TOOL_STATE.IDLE) return;
33977
+ if (this.state === MEASURE_TOOL_STATE.SET_FROM) {
33978
+ this.handleSetFrom();
33979
+ return;
33980
+ }
33981
+ if (this.state === MEASURE_TOOL_STATE.SET_TO) this.handleSetTo();
33982
+ });
33983
+ this.initialized = true;
33984
+ }
33985
+ setState(state) {
33986
+ this.state = state;
33987
+ }
33988
+ addMeasure() {
33989
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
33990
+ if (selectionPlugin) {
33991
+ const tr = selectionPlugin.getTransformer();
33992
+ tr.hide();
33993
+ }
33994
+ this.instance.addEventListener("onZoomChange", () => {
33995
+ if (this.crosshairCursor) {
33996
+ const stage = this.instance.getStage();
33997
+ this.crosshairCursor.scale({
33998
+ x: 1 / stage.scaleX(),
33999
+ y: 1 / stage.scaleY()
34000
+ });
34001
+ }
34002
+ });
34003
+ this.buildCrosshairCursor();
34004
+ this.setCursor();
34005
+ this.setFocusStage();
34006
+ this.clickPoint = null;
34007
+ this.setState(MEASURE_TOOL_STATE.SET_FROM);
34008
+ }
34009
+ buildCrosshairCursor() {
34010
+ const stage = this.instance.getStage();
34011
+ const { mousePoint } = this.instance.getMousePointer();
34012
+ this.crosshairCursor = new Konva.Group({
34013
+ x: mousePoint?.x,
34014
+ y: mousePoint?.y,
34015
+ scale: {
34016
+ x: 1 / stage.scaleX(),
34017
+ y: 1 / stage.scaleY()
34018
+ },
34019
+ listening: false,
34020
+ draggable: false
34021
+ });
34022
+ const crosshairSize = 60;
34023
+ const lineH = new Konva.Line({
34024
+ points: [
34025
+ 0,
34026
+ 0,
34027
+ crosshairSize,
34028
+ 0
34029
+ ],
34030
+ x: -1 * (crosshairSize / 2),
34031
+ y: 0,
34032
+ stroke: this.config.style.stroke,
34033
+ strokeWidth: 1
34034
+ });
34035
+ const lineV = new Konva.Line({
34036
+ points: [
34037
+ 0,
34038
+ 0,
34039
+ 0,
34040
+ crosshairSize
34041
+ ],
34042
+ x: 0,
34043
+ y: -1 * crosshairSize / 2,
34044
+ stroke: this.config.style.stroke,
34045
+ strokeWidth: 1
34046
+ });
34047
+ this.crosshairCursor.add(lineH);
34048
+ this.crosshairCursor.add(lineV);
34049
+ this.instance.getStage().on("pointermove.measureTool", () => {
34050
+ const pos = this.instance.getStage().getRelativePointerPosition();
34051
+ if (this.crosshairCursor && pos) {
34052
+ this.crosshairCursor.position(pos);
34053
+ this.crosshairCursor.moveToTop();
34054
+ }
34055
+ });
34056
+ this.instance.getUtilityLayer()?.add(this.crosshairCursor);
34057
+ }
34058
+ handleSetFrom() {
34059
+ const stage = this.instance.getStage();
34060
+ const realMousePoint = stage.getRelativePointerPosition();
34061
+ const { container, measureContainer } = this.instance.getMousePointer();
34062
+ this.clickPoint = realMousePoint;
34063
+ this.container = container;
34064
+ this.measureContainer = measureContainer;
34065
+ this.firstPoint = new Konva.Circle({
34066
+ x: this.clickPoint?.x ?? 0,
34067
+ y: this.clickPoint?.y ?? 0,
34068
+ radius: 6,
34069
+ fill: "#FFFFFF",
34070
+ stroke: "#000000",
34071
+ scale: {
34072
+ x: 1 / stage.scaleX(),
34073
+ y: 1 / stage.scaleY()
34074
+ },
34075
+ strokeWidth: 1,
34076
+ listening: false,
34077
+ draggable: false
34078
+ });
34079
+ this.measureLine = new Konva.Line({
34080
+ x: this.clickPoint?.x,
34081
+ y: this.clickPoint?.y,
34082
+ points: [0, 0],
34083
+ scale: {
34084
+ x: 1 / stage.scaleX(),
34085
+ y: 1 / stage.scaleY()
34086
+ },
34087
+ stroke: this.config.style.stroke,
34088
+ dashed: [4, 4],
34089
+ strokeWidth: 1,
34090
+ listening: false,
34091
+ draggable: false
34092
+ });
34093
+ this.instance.getUtilityLayer()?.add(this.firstPoint);
34094
+ this.instance.getUtilityLayer()?.add(this.measureLine);
34095
+ this.firstPoint.moveToTop();
34096
+ this.measureLine.moveToBottom();
34097
+ this.setState(MEASURE_TOOL_STATE.SET_TO);
34098
+ }
34099
+ handleSetTo() {
34100
+ const stage = this.instance.getStage();
34101
+ const realMousePoint = stage.getRelativePointerPosition();
34102
+ const { container } = this.instance.getMousePointer();
34103
+ this.clickPoint = realMousePoint;
34104
+ this.container = container;
34105
+ const nodeHandler = this.instance.getNodeHandler("measure");
34106
+ if (nodeHandler && this.firstPoint) {
34107
+ this.measureId = v4_default();
34108
+ const node = nodeHandler.create(this.measureId, {
34109
+ ...this.props,
34110
+ id: this.measureId,
34111
+ x: 0,
34112
+ y: 0,
34113
+ fromPoint: {
34114
+ x: this.firstPoint.x(),
34115
+ y: this.firstPoint.y()
34116
+ },
34117
+ toPoint: {
34118
+ x: this.clickPoint?.x ?? 0,
34119
+ y: this.clickPoint?.y ?? 0
34120
+ },
34121
+ draggable: true
34122
+ });
34123
+ this.instance.addOnceEventListener("onNodeRenderedAdded", (child) => {
34124
+ if (child.getAttrs().id === this.measureId) {
34125
+ if (typeof this.measureContainer !== "undefined" && this.measureContainer?.id() !== "mainLayer") {
34126
+ const nodeInstance = this.instance.getMainLayer()?.findOne(`#${this.measureId}`);
34127
+ const stage$1 = this.instance.getStage();
34128
+ let realContainer = this.measureContainer;
34129
+ if (realContainer?.getAttrs().nodeId !== void 0) realContainer = stage$1.findOne(`#${realContainer?.getAttrs().nodeId}`);
34130
+ if (nodeInstance) moveNodeToContainer(this.instance, nodeInstance, realContainer);
34131
+ }
34132
+ this.cancelAction();
34133
+ }
34134
+ });
34135
+ this.instance.addNode(node, "mainLayer");
34136
+ this.setState(MEASURE_TOOL_STATE.FINISHED);
34137
+ }
34138
+ }
34139
+ trigger(cancelAction) {
34140
+ if (!this.instance) throw new Error("Instance not defined");
34141
+ if (!this.initialized) this.setupEvents();
34142
+ this.cancelAction = cancelAction;
34143
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34144
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
34145
+ this.props = this.initProps();
34146
+ this.addMeasure();
34147
+ }
34148
+ cleanup() {
34149
+ const stage = this.instance.getStage();
34150
+ stage.container().style.cursor = "default";
34151
+ this.instance.getStage().off("pointermove.measureTool");
34152
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
34153
+ if (selectionPlugin) {
34154
+ const node = stage.findOne(`#${this.measureId}`);
34155
+ if (node) selectionPlugin.setSelectedNodes([node]);
34156
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
34157
+ }
34158
+ if (this.crosshairCursor) this.crosshairCursor.destroy();
34159
+ if (this.firstPoint) this.firstPoint.destroy();
34160
+ if (this.measureLine) this.measureLine.destroy();
34161
+ this.initialCursor = null;
34162
+ this.measureId = null;
34163
+ this.container = void 0;
34164
+ this.clickPoint = null;
34165
+ this.firstPoint = null;
34166
+ this.measureLine = null;
34167
+ this.setState(MEASURE_TOOL_STATE.IDLE);
34168
+ }
34169
+ setCursor() {
34170
+ const stage = this.instance.getStage();
34171
+ stage.container().style.cursor = "none";
34172
+ }
34173
+ setFocusStage() {
34174
+ const stage = this.instance.getStage();
34175
+ stage.container().tabIndex = 1;
34176
+ stage.container().blur();
34177
+ stage.container().focus();
34178
+ }
34179
+ defineFinalPoint() {
34180
+ if (!this.measureLine || !this.measureContainer) return {
34181
+ x: 0,
34182
+ y: 0
34183
+ };
34184
+ const stage = this.instance.getStage();
34185
+ const realMousePoint = this.instance.getStage().getRelativePointerPosition();
34186
+ const pos = {
34187
+ x: 0,
34188
+ y: 0
34189
+ };
34190
+ pos.x = ((realMousePoint?.x ?? 0) - this.measureLine.x()) * stage.scaleX();
34191
+ pos.y = ((realMousePoint?.y ?? 0) - this.measureLine.y()) * stage.scaleY();
34192
+ return pos;
34193
+ }
34194
+ };
34195
+
34196
+ //#endregion
34197
+ 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, 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, 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_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_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_SELECTION_KEY, WEAVE_USER_POINTER_KEY, WEAVE_USER_SELECTION_KEY, WEAVE_VIDEO_DEFAULT_CONFIG, WEAVE_VIDEO_NODE_TYPE, Weave, WeaveAction, WeaveAlignNodesToolAction, WeaveArrowNode, WeaveArrowToolAction, WeaveBrushToolAction, WeaveCommentNode, WeaveCommentToolAction, WeaveCommentsRendererPlugin, WeaveConnectedUsersPlugin, WeaveContextMenuPlugin, WeaveCopyPasteNodesPlugin, WeaveEllipseNode, WeaveEllipseToolAction, WeaveEraserToolAction, WeaveExportNodesToolAction, WeaveExportStageToolAction, WeaveFitToScreenToolAction, WeaveFitToSelectionToolAction, WeaveFrameNode, WeaveFrameToolAction, WeaveGroupNode, WeaveImageNode, WeaveImageToolAction, WeaveLayerNode, WeaveLineNode, 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, WeaveUsersSelectionPlugin, WeaveVideoNode, WeaveVideoToolAction, WeaveZoomInToolAction, WeaveZoomOutToolAction, canComposite, clearContainerTargets, containerOverCursor, containsNodeDeep, defaultInitialState, getBoundingBox, getExportBoundingBox, getPositionRelativeToContainerOnPosition, getSelectedNodesMetadata, getStageClickPoint, getTargetAndSkipNodes, getTargetedNode, getTopmostShadowHost, getVisibleNodes, getVisibleNodesInViewport, hasFrames, hasImages, intersectArrays, isIOS, isInShadowDOM, isNodeInSelection, isServer, memoize, mergeExceptArrays, moveNodeToContainer, resetScale, setupCanvasBackend, setupSkiaBackend };
33208
34198
  //# sourceMappingURL=sdk.node.js.map