@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.js CHANGED
@@ -10312,7 +10312,7 @@ var require_lodash = __commonJS({ "../../node_modules/lodash/lodash.js"(exports,
10312
10312
  * _.isNaN(undefined);
10313
10313
  * // => false
10314
10314
  */
10315
- function isNaN(value) {
10315
+ function isNaN$1(value) {
10316
10316
  return isNumber(value) && value != +value;
10317
10317
  }
10318
10318
  /**
@@ -14729,7 +14729,7 @@ var require_lodash = __commonJS({ "../../node_modules/lodash/lodash.js"(exports,
14729
14729
  lodash.isMap = isMap;
14730
14730
  lodash.isMatch = isMatch;
14731
14731
  lodash.isMatchWith = isMatchWith;
14732
- lodash.isNaN = isNaN;
14732
+ lodash.isNaN = isNaN$1;
14733
14733
  lodash.isNative = isNative;
14734
14734
  lodash.isNil = isNil;
14735
14735
  lodash.isNull = isNull;
@@ -15257,6 +15257,7 @@ const WEAVE_NODES_SELECTION_DEFAULT_CONFIG = {
15257
15257
  anchor.offsetX(4);
15258
15258
  }
15259
15259
  },
15260
+ anchorSize: 12,
15260
15261
  borderStroke: "#1a1aff",
15261
15262
  borderStrokeWidth: 2
15262
15263
  },
@@ -20661,6 +20662,7 @@ var WeaveReconciler = class {
20661
20662
  newProps.height = rootContainer.getStageConfiguration().height;
20662
20663
  }
20663
20664
  const element = handler.onRender(newProps);
20665
+ hostContext.emitEvent("onNodeRenderedAdded", element);
20664
20666
  return element;
20665
20667
  },
20666
20668
  detachDeletedInstance(node) {
@@ -24895,6 +24897,698 @@ var WeaveVideoNode = class extends WeaveNode {
24895
24897
  }
24896
24898
  };
24897
24899
 
24900
+ //#endregion
24901
+ //#region src/nodes/measure/constants.ts
24902
+ const WEAVE_MEASURE_NODE_TYPE = "measure";
24903
+ const WEAVE_MEASURE_NODE_DEFAULT_CONFIG = { style: {
24904
+ separationLine: {
24905
+ padding: 0,
24906
+ strokeWidth: 1,
24907
+ dash: [],
24908
+ stroke: "#FF3366"
24909
+ },
24910
+ text: {
24911
+ padding: 10,
24912
+ fontSize: 14,
24913
+ fontFamily: "monospace",
24914
+ fill: "#FF3366"
24915
+ },
24916
+ intersectionCircle: {
24917
+ radius: 3,
24918
+ fill: "#FF3366"
24919
+ },
24920
+ measureLine: {
24921
+ stroke: "#FF3366",
24922
+ dash: [4, 4],
24923
+ strokeWidth: 1
24924
+ },
24925
+ handler: {
24926
+ noSpaceSeparationMultiplier: 2.5,
24927
+ spaceSeparationMultiplier: 1.5
24928
+ }
24929
+ } };
24930
+
24931
+ //#endregion
24932
+ //#region src/nodes/measure/measure.ts
24933
+ var WeaveMeasureNode = class extends WeaveNode {
24934
+ nodeType = WEAVE_MEASURE_NODE_TYPE;
24935
+ handlePointCircleRadius = 6;
24936
+ constructor(params) {
24937
+ super();
24938
+ this.config = mergeExceptArrays(WEAVE_MEASURE_NODE_DEFAULT_CONFIG, params?.config ?? {});
24939
+ }
24940
+ onRender(props) {
24941
+ const measure = new Konva.Group({
24942
+ ...props,
24943
+ name: "node",
24944
+ draggable: false
24945
+ });
24946
+ const fromPoint = props.fromPoint;
24947
+ const toPoint = props.toPoint;
24948
+ const separation = props.separation ?? 100;
24949
+ const orientation = props.orientation ?? -1;
24950
+ const unit = props.unit ?? "cms";
24951
+ const unitPerPixel = props.unitPerPixel ?? 100;
24952
+ const measureLine = this.config.style.measureLine;
24953
+ const intersectionCircle = this.config.style.intersectionCircle;
24954
+ const separationLine = this.config.style.separationLine;
24955
+ const textConfig = this.config.style.text;
24956
+ const fromFinalPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, (separation + separationLine.padding) * orientation);
24957
+ const linePerpFrom = new Konva.Line({
24958
+ id: `linePerpFrom-${props.id}`,
24959
+ nodeId: props.id,
24960
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24961
+ points: [
24962
+ fromPoint.x,
24963
+ fromPoint.y,
24964
+ fromFinalPerp.left.x,
24965
+ fromFinalPerp.left.y
24966
+ ],
24967
+ stroke: separationLine.stroke,
24968
+ strokeWidth: separationLine.strokeWidth,
24969
+ dash: separationLine.dash
24970
+ });
24971
+ measure.add(linePerpFrom);
24972
+ const toFinalPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, (separation + separationLine.padding) * orientation);
24973
+ const linePerpTo = new Konva.Line({
24974
+ id: `linePerpTo-${props.id}`,
24975
+ nodeId: props.id,
24976
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24977
+ points: [
24978
+ toPoint.x,
24979
+ toPoint.y,
24980
+ toFinalPerp.left.x,
24981
+ toFinalPerp.left.y
24982
+ ],
24983
+ stroke: separationLine.stroke,
24984
+ strokeWidth: separationLine.strokeWidth,
24985
+ dash: separationLine.dash
24986
+ });
24987
+ measure.add(linePerpTo);
24988
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
24989
+ const fromCircle = new Konva.Circle({
24990
+ id: `fromCircle-${props.id}`,
24991
+ nodeId: props.id,
24992
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24993
+ x: fromPerp.left.x,
24994
+ y: fromPerp.left.y,
24995
+ radius: intersectionCircle.radius,
24996
+ fill: intersectionCircle.fill
24997
+ });
24998
+ measure.add(fromCircle);
24999
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25000
+ const toCircle = new Konva.Circle({
25001
+ id: `toCircle-${props.id}`,
25002
+ nodeId: props.id,
25003
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
25004
+ x: toPerp.left.x,
25005
+ y: toPerp.left.y,
25006
+ radius: intersectionCircle.radius,
25007
+ fill: intersectionCircle.fill
25008
+ });
25009
+ measure.add(toCircle);
25010
+ const midPoint = this.midPoint(fromPerp.left, toPerp.left);
25011
+ const distance = this.distanceBetweenPoints(fromPoint, toPoint);
25012
+ const units = distance / unitPerPixel;
25013
+ const text = `${units.toFixed(2)} ${unit}`;
25014
+ const measureText = new Konva.Text({
25015
+ id: `measureText-${props.id}`,
25016
+ nodeId: props.id,
25017
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
25018
+ x: midPoint.x,
25019
+ y: midPoint.y,
25020
+ text,
25021
+ fontFamily: textConfig.fontFamily,
25022
+ fontSize: textConfig.fontSize,
25023
+ verticalAlign: "middle",
25024
+ align: "center",
25025
+ fill: textConfig.fill
25026
+ });
25027
+ const angle = this.getAngle(fromPoint, toPoint);
25028
+ const textSize = measureText.measureSize(text);
25029
+ const textOffsetX = textSize.width / 2;
25030
+ measureText.rotation(angle);
25031
+ measureText.offsetX(textSize.width / 2);
25032
+ measureText.offsetY(textSize.height / 2);
25033
+ if (textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left)) {
25034
+ const perpPointTextMid = this.perpendicularPoint(fromPerp.left, toPerp.left, midPoint, (textSize.height + separationLine.padding) * orientation);
25035
+ measureText.x(perpPointTextMid.left.x);
25036
+ measureText.y(perpPointTextMid.left.y);
25037
+ }
25038
+ measure.add(measureText);
25039
+ const pointLeftText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, false);
25040
+ const pointRightText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, true);
25041
+ const lineLeft = new Konva.Line({
25042
+ id: `lineLeft-${props.id}`,
25043
+ nodeId: props.id,
25044
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
25045
+ points: [
25046
+ fromPerp.left.x,
25047
+ fromPerp.left.y,
25048
+ pointLeftText.x,
25049
+ pointLeftText.y
25050
+ ],
25051
+ dash: measureLine.dash,
25052
+ stroke: measureLine.stroke,
25053
+ strokeWidth: measureLine.strokeWidth
25054
+ });
25055
+ const lineRight = new Konva.Line({
25056
+ id: `lineRight-${props.id}`,
25057
+ nodeId: props.id,
25058
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
25059
+ points: [
25060
+ pointRightText.x,
25061
+ pointRightText.y,
25062
+ toPerp.left.x,
25063
+ toPerp.left.y
25064
+ ],
25065
+ dash: measureLine.dash,
25066
+ stroke: measureLine.stroke,
25067
+ strokeWidth: measureLine.strokeWidth
25068
+ });
25069
+ measure.add(measureText);
25070
+ measure.add(lineLeft);
25071
+ measure.add(lineRight);
25072
+ this.setupDefaultNodeAugmentation(measure);
25073
+ measure.getTransformerProperties = function() {
25074
+ return {
25075
+ resizeEnabled: false,
25076
+ rotateEnabled: false,
25077
+ borderEnabled: false
25078
+ };
25079
+ };
25080
+ this.instance.addEventListener("onZoomChange", () => {
25081
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
25082
+ if (selectionPlugin) {
25083
+ const selectedNodes = selectionPlugin.getSelectedNodes();
25084
+ if (selectedNodes.length === 1 && selectedNodes[0].getAttrs().id === measure.getAttrs().id) this.updateSelectionHandlers(measure);
25085
+ }
25086
+ });
25087
+ this.instance.addEventListener("onNodesChange", () => {
25088
+ let isSelected = false;
25089
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
25090
+ if (selectionPlugin) {
25091
+ const selectedNodes = selectionPlugin.getSelectedNodes();
25092
+ if (selectedNodes.length === 1 && selectedNodes[0].getAttrs().id === measure.getAttrs().id) {
25093
+ isSelected = true;
25094
+ this.createSelectionHandlers(measure);
25095
+ this.updateSelectionHandlers(measure);
25096
+ }
25097
+ }
25098
+ if (!isSelected) this.destroySelectionHandlers(measure);
25099
+ });
25100
+ this.instance.addEventListener("onMeasureReferenceChange", ({ unit: unit$1, unitPerPixel: unitPerPixel$1 }) => {
25101
+ measure.setAttrs({
25102
+ unit: unit$1,
25103
+ unitPerPixel: unitPerPixel$1
25104
+ });
25105
+ this.instance.updateNode(this.serialize(measure));
25106
+ });
25107
+ measure.allowedAnchors = function() {
25108
+ return [];
25109
+ };
25110
+ this.setupDefaultNodeEvents(measure);
25111
+ return measure;
25112
+ }
25113
+ createSelectionHandlers(node) {
25114
+ const props = node.getAttrs();
25115
+ const fromPoint = props.fromPoint;
25116
+ const toPoint = props.toPoint;
25117
+ const separation = props.separation ?? 100;
25118
+ const orientation = props.orientation ?? -1;
25119
+ const angle = this.getAngle(fromPoint, toPoint);
25120
+ const moveToCircleAct = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
25121
+ const crosshairFromAct = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
25122
+ const moveFromCircleAct = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
25123
+ const crosshairToAct = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
25124
+ const moveSeparationRectAct = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
25125
+ const measureText = node.findOne(`#measureText-${node.getAttrs().id}`);
25126
+ if (moveToCircleAct && crosshairFromAct && moveFromCircleAct && crosshairToAct && moveSeparationRectAct) return;
25127
+ const textSize = measureText?.measureSize(measureText.text());
25128
+ const moveFromCircle = new Konva.Circle({
25129
+ id: `moveFromCircle-${props.id}`,
25130
+ edgeDistanceDisableOnDrag: true,
25131
+ edgeSnappingDisableOnDrag: true,
25132
+ x: fromPoint.x,
25133
+ y: fromPoint.y,
25134
+ radius: this.handlePointCircleRadius,
25135
+ fill: "#FFFFFF",
25136
+ stroke: "#000000",
25137
+ strokeWidth: 1,
25138
+ draggable: true
25139
+ });
25140
+ const crosshairFrom = this.buildCrosshair("crosshairFrom", node, fromPoint, angle);
25141
+ const moveToCircle = new Konva.Circle({
25142
+ id: `moveToCircle-${props.id}`,
25143
+ edgeDistanceDisableOnDrag: true,
25144
+ edgeSnappingDisableOnDrag: true,
25145
+ x: toPoint.x,
25146
+ y: toPoint.y,
25147
+ radius: this.handlePointCircleRadius,
25148
+ fill: "#FFFFFF",
25149
+ stroke: "#000000",
25150
+ strokeWidth: 1,
25151
+ draggable: true
25152
+ });
25153
+ const crosshairTo = this.buildCrosshair("crosshairTo", node, toPoint, angle);
25154
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
25155
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25156
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
25157
+ const isTextBiggerThanMeasureSpace = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25158
+ const multiplier = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
25159
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, multiplier * (textSize?.height ?? 0) * orientation);
25160
+ const moveSeparationRect = new Konva.Rect({
25161
+ id: `moveSeparationRect-${props.id}`,
25162
+ edgeDistanceDisableOnDrag: true,
25163
+ edgeSnappingDisableOnDrag: true,
25164
+ x: separatorPoint.left.x,
25165
+ y: separatorPoint.left.y,
25166
+ width: this.handlePointCircleRadius * 2 * 3,
25167
+ height: this.handlePointCircleRadius * 2,
25168
+ offsetX: this.handlePointCircleRadius * 3,
25169
+ offsetY: this.handlePointCircleRadius,
25170
+ cornerRadius: this.handlePointCircleRadius,
25171
+ rotation: angle,
25172
+ fill: "#FFFFFF",
25173
+ stroke: "#000000",
25174
+ strokeWidth: 1,
25175
+ draggable: true
25176
+ });
25177
+ node.add(moveFromCircle);
25178
+ node.add(crosshairFrom);
25179
+ node.add(moveToCircle);
25180
+ node.add(crosshairTo);
25181
+ node.add(moveSeparationRect);
25182
+ moveFromCircle.moveToTop();
25183
+ crosshairFrom.moveToBottom();
25184
+ moveToCircle.moveToTop();
25185
+ crosshairTo.moveToBottom();
25186
+ moveSeparationRect.moveToTop();
25187
+ moveFromCircle.on("dragstart", () => {
25188
+ moveFromCircle.visible(false);
25189
+ moveToCircle.visible(false);
25190
+ moveSeparationRect.visible(false);
25191
+ crosshairFrom.visible(true);
25192
+ });
25193
+ moveFromCircle.on("dragmove", (e) => {
25194
+ const actCircle = e.target;
25195
+ const realNode = e.target.getParent();
25196
+ const newFromPoint = {
25197
+ x: actCircle.x(),
25198
+ y: actCircle.y()
25199
+ };
25200
+ realNode.setAttrs({ fromPoint: newFromPoint });
25201
+ this.onUpdate(realNode, this.serialize(realNode).props);
25202
+ });
25203
+ moveFromCircle.on("dragend", (e) => {
25204
+ const actCircle = e.target;
25205
+ const realNode = e.target.getParent();
25206
+ moveFromCircle.visible(true);
25207
+ moveToCircle.visible(true);
25208
+ moveSeparationRect.visible(true);
25209
+ crosshairFrom.visible(false);
25210
+ const newFromPoint = {
25211
+ x: actCircle.x(),
25212
+ y: actCircle.y()
25213
+ };
25214
+ realNode.setAttrs({ fromPoint: newFromPoint });
25215
+ this.instance.updateNode(this.serialize(realNode));
25216
+ });
25217
+ moveToCircle.on("dragstart", () => {
25218
+ moveFromCircle.visible(false);
25219
+ moveToCircle.visible(false);
25220
+ moveSeparationRect.visible(false);
25221
+ crosshairTo.visible(true);
25222
+ });
25223
+ moveToCircle.on("dragmove", (e) => {
25224
+ const actCircle = e.target;
25225
+ const realNode = e.target.getParent();
25226
+ const newToPoint = {
25227
+ x: actCircle.x(),
25228
+ y: actCircle.y()
25229
+ };
25230
+ realNode.setAttrs({ toPoint: newToPoint });
25231
+ this.onUpdate(realNode, this.serialize(realNode).props);
25232
+ });
25233
+ moveToCircle.on("dragend", (e) => {
25234
+ const actCircle = e.target;
25235
+ const realNode = e.target.getParent();
25236
+ moveFromCircle.visible(true);
25237
+ moveToCircle.visible(true);
25238
+ moveSeparationRect.visible(true);
25239
+ crosshairTo.visible(false);
25240
+ const newToPoint = {
25241
+ x: actCircle.x(),
25242
+ y: actCircle.y()
25243
+ };
25244
+ realNode.setAttrs({ toPoint: newToPoint });
25245
+ this.instance.updateNode(this.serialize(realNode));
25246
+ });
25247
+ let originalSeparationHandlerPosition = {
25248
+ x: 0,
25249
+ y: 0
25250
+ };
25251
+ moveSeparationRect.on("dragstart", () => {
25252
+ const pos = moveSeparationRect.position();
25253
+ originalSeparationHandlerPosition = pos;
25254
+ });
25255
+ moveSeparationRect.on("dragmove", (e) => {
25256
+ const pos = e.target.position();
25257
+ const realNode = e.target.getParent();
25258
+ const fromPoint$1 = node.getAttrs().fromPoint;
25259
+ const toPoint$1 = node.getAttrs().toPoint;
25260
+ const midPoint = this.midPoint(fromPoint$1, toPoint$1);
25261
+ const isTextBiggerThanMeasureSpace$1 = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25262
+ const multiplier$1 = isTextBiggerThanMeasureSpace$1 ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
25263
+ const separatorPoint$1 = this.perpendicularPoint(fromPoint$1, toPoint$1, midPoint, multiplier$1 * (textSize?.height ?? 0) * orientation);
25264
+ const pointInLine = this.projectPointToLine(separatorPoint$1.left, originalSeparationHandlerPosition, pos);
25265
+ if (isNaN(pointInLine.t)) {
25266
+ const point = this.movePointPerpendicularToLine(fromPoint$1, toPoint$1, separatorPoint$1.left, (multiplier$1 * (textSize?.height ?? 0) + 1) * orientation);
25267
+ moveSeparationRect.position(point);
25268
+ originalSeparationHandlerPosition = point;
25269
+ realNode.setAttrs({ separation: (textSize?.height ?? 0) + 1 });
25270
+ } else {
25271
+ moveSeparationRect.position(pointInLine);
25272
+ const dx = originalSeparationHandlerPosition.x - separatorPoint$1.left.x;
25273
+ const dy = originalSeparationHandlerPosition.y - separatorPoint$1.left.y;
25274
+ const len = Math.hypot(dx, dy);
25275
+ let newLength = pointInLine.t * len;
25276
+ if (newLength < 0) newLength = 0;
25277
+ realNode.setAttrs({ separation: newLength });
25278
+ }
25279
+ this.onUpdate(realNode, this.serialize(realNode).props);
25280
+ });
25281
+ moveSeparationRect.on("dragend", (e) => {
25282
+ const pos = e.target.position();
25283
+ const realNode = e.target.getParent();
25284
+ const fromPoint$1 = node.getAttrs().fromPoint;
25285
+ const toPoint$1 = node.getAttrs().toPoint;
25286
+ const midPoint = this.midPoint(fromPoint$1, toPoint$1);
25287
+ const multiplier$1 = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
25288
+ const separatorPoint$1 = this.perpendicularPoint(fromPoint$1, toPoint$1, midPoint, multiplier$1 * (textSize?.height ?? 0) * orientation);
25289
+ const pointInLine = this.projectPointToLine(separatorPoint$1.left, originalSeparationHandlerPosition, pos);
25290
+ moveSeparationRect.position(pointInLine);
25291
+ const dx = originalSeparationHandlerPosition.x - separatorPoint$1.left.x;
25292
+ const dy = originalSeparationHandlerPosition.y - separatorPoint$1.left.y;
25293
+ const len = Math.hypot(dx, dy);
25294
+ let newLength = pointInLine.t * len;
25295
+ if (newLength < 0) newLength = 0;
25296
+ realNode.setAttrs({ separation: newLength });
25297
+ this.instance.updateNode(this.serialize(realNode));
25298
+ });
25299
+ }
25300
+ updateSelectionHandlers(node) {
25301
+ const stage = this.instance.getStage();
25302
+ const scale = stage.scaleX();
25303
+ const fromPoint = node.getAttrs().fromPoint;
25304
+ const toPoint = node.getAttrs().toPoint;
25305
+ const moveToCircle = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
25306
+ const crosshairFrom = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
25307
+ const moveFromCircle = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
25308
+ const crosshairTo = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
25309
+ const moveSeparationRect = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
25310
+ if (moveToCircle) moveToCircle.scale({
25311
+ x: 1 / scale,
25312
+ y: 1 / scale
25313
+ });
25314
+ if (crosshairFrom) crosshairFrom.scale({
25315
+ x: 1 / scale,
25316
+ y: 1 / scale
25317
+ });
25318
+ if (moveFromCircle) moveFromCircle.scale({
25319
+ x: 1 / scale,
25320
+ y: 1 / scale
25321
+ });
25322
+ if (crosshairTo) crosshairTo.scale({
25323
+ x: 1 / scale,
25324
+ y: 1 / scale
25325
+ });
25326
+ if (moveSeparationRect) {
25327
+ const measureText = node.findOne(`#measureText-${node.getAttrs().id}`);
25328
+ const angle = this.getAngle(fromPoint, toPoint);
25329
+ const textSize = measureText?.measureSize(measureText.text());
25330
+ const separation = node.getAttrs().separation ?? 100;
25331
+ const orientation = node.getAttrs().orientation ?? -1;
25332
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
25333
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25334
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
25335
+ const isTextBiggerThanMeasureSpace = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25336
+ const multiplier = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
25337
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, multiplier * (textSize?.height ?? 0) * orientation);
25338
+ moveSeparationRect.x(separatorPoint.left.x);
25339
+ moveSeparationRect.y(separatorPoint.left.y);
25340
+ moveSeparationRect.rotation(angle);
25341
+ moveSeparationRect.scale({
25342
+ x: 1 / scale,
25343
+ y: 1 / scale
25344
+ });
25345
+ }
25346
+ }
25347
+ destroySelectionHandlers(node) {
25348
+ const moveToCircle = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
25349
+ const crosshairFrom = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
25350
+ const moveFromCircle = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
25351
+ const crosshairTo = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
25352
+ const moveSeparationRect = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
25353
+ if (moveToCircle) moveToCircle.destroy();
25354
+ if (crosshairFrom) crosshairFrom.destroy();
25355
+ if (moveFromCircle) moveFromCircle.destroy();
25356
+ if (crosshairTo) crosshairTo.destroy();
25357
+ if (moveSeparationRect) moveSeparationRect.destroy();
25358
+ }
25359
+ pointFromMid(from, to, distance, towardsSecond = true) {
25360
+ const mx = (from.x + to.x) / 2;
25361
+ const my = (from.y + to.y) / 2;
25362
+ const dx = to.x - from.x;
25363
+ const dy = to.y - from.y;
25364
+ const len = Math.hypot(dx, dy);
25365
+ const ux = dx / len;
25366
+ const uy = dy / len;
25367
+ const sign = towardsSecond ? 1 : -1;
25368
+ return {
25369
+ x: mx + ux * distance * sign,
25370
+ y: my + uy * distance * sign
25371
+ };
25372
+ }
25373
+ angleBetweenPoints(from, to) {
25374
+ return Math.atan2(to.y - from.y, to.x - from.x) * 180 / Math.PI;
25375
+ }
25376
+ midPoint(from, to) {
25377
+ return {
25378
+ x: (from.x + to.x) / 2,
25379
+ y: (from.y + to.y) / 2
25380
+ };
25381
+ }
25382
+ perpendicularPoint(from, to, point, distance) {
25383
+ const dx = to.x - from.x;
25384
+ const dy = to.y - from.y;
25385
+ const perpX = -dy;
25386
+ const perpY = dx;
25387
+ const len = Math.hypot(perpX, perpY);
25388
+ const ux = perpX / len;
25389
+ const uy = perpY / len;
25390
+ return {
25391
+ left: {
25392
+ x: point.x + ux * distance,
25393
+ y: point.y + uy * distance
25394
+ },
25395
+ right: {
25396
+ x: point.x - ux * distance,
25397
+ y: point.y - uy * distance
25398
+ }
25399
+ };
25400
+ }
25401
+ distanceBetweenPoints(from, to) {
25402
+ return Math.hypot(to.x - from.x, to.y - from.y);
25403
+ }
25404
+ onUpdate(nodeInstance, nextProps) {
25405
+ nodeInstance.setAttrs({ ...nextProps });
25406
+ const measure = nodeInstance;
25407
+ const fromPoint = nextProps.fromPoint;
25408
+ const toPoint = nextProps.toPoint;
25409
+ const separation = nextProps.separation ?? 100;
25410
+ const orientation = nextProps.orientation ?? -1;
25411
+ const unit = nextProps.unit ?? "cms";
25412
+ const unitPerPixel = nextProps.unitPerPixel ?? 100;
25413
+ const separationLine = this.config.style.separationLine;
25414
+ const textConfig = this.config.style.text;
25415
+ const fromFinalPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, (separation + separationLine.padding) * orientation);
25416
+ const linePerpFrom = measure.findOne(`#linePerpFrom-${nextProps.id}`);
25417
+ linePerpFrom?.points([
25418
+ fromPoint.x,
25419
+ fromPoint.y,
25420
+ fromFinalPerp.left.x,
25421
+ fromFinalPerp.left.y
25422
+ ]);
25423
+ const toFinalPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, (separation + separationLine.padding) * orientation);
25424
+ const linePerpTo = measure.findOne(`#linePerpTo-${nextProps.id}`);
25425
+ linePerpTo?.points([
25426
+ toPoint.x,
25427
+ toPoint.y,
25428
+ toFinalPerp.left.x,
25429
+ toFinalPerp.left.y
25430
+ ]);
25431
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
25432
+ const fromCircle = measure.findOne(`#fromCircle-${nextProps.id}`);
25433
+ fromCircle?.position({
25434
+ x: fromPerp.left.x,
25435
+ y: fromPerp.left.y
25436
+ });
25437
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25438
+ const toCircle = measure.findOne(`#toCircle-${nextProps.id}`);
25439
+ toCircle?.position({
25440
+ x: toPerp.left.x,
25441
+ y: toPerp.left.y
25442
+ });
25443
+ const midPoint = this.midPoint(fromPerp.left, toPerp.left);
25444
+ const distance = this.distanceBetweenPoints(fromPoint, toPoint);
25445
+ const units = distance / unitPerPixel;
25446
+ const text = `${units.toFixed(2)} ${unit}`;
25447
+ const measureText = measure.findOne(`#measureText-${nextProps.id}`);
25448
+ const angle = this.getAngle(fromPoint, toPoint);
25449
+ const textSize = measureText.measureSize(text);
25450
+ const textOffsetX = textSize.width / 2;
25451
+ measureText?.text(text);
25452
+ measureText?.rotation(angle);
25453
+ measureText?.x(midPoint.x);
25454
+ measureText?.y(midPoint.y);
25455
+ measureText?.offsetX(textSize.width / 2);
25456
+ measureText?.offsetY(textSize.height / 2);
25457
+ if (textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left)) {
25458
+ const perpPointTextMid = this.perpendicularPoint(fromPerp.left, toPerp.left, midPoint, (textSize.height + separationLine.padding) * orientation);
25459
+ measureText.x(perpPointTextMid.left.x);
25460
+ measureText.y(perpPointTextMid.left.y);
25461
+ }
25462
+ const pointLeftText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, false);
25463
+ const pointRightText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textConfig.padding, true);
25464
+ const lineLeft = measure.findOne(`#lineLeft-${nextProps.id}`);
25465
+ lineLeft?.points([
25466
+ fromPerp.left.x,
25467
+ fromPerp.left.y,
25468
+ pointLeftText.x,
25469
+ pointLeftText.y
25470
+ ]);
25471
+ const lineRight = measure.findOne(`#lineRight-${nextProps.id}`);
25472
+ lineRight?.points([
25473
+ pointRightText.x,
25474
+ pointRightText.y,
25475
+ toPerp.left.x,
25476
+ toPerp.left.y
25477
+ ]);
25478
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
25479
+ const crosshairFrom = measure.findOne(`#crosshairFrom-${measure.getAttrs().id}`);
25480
+ if (crosshairFrom) {
25481
+ crosshairFrom.x(fromPoint.x);
25482
+ crosshairFrom.y(fromPoint.y);
25483
+ crosshairFrom.rotation(angle);
25484
+ }
25485
+ const crosshairTo = measure.findOne(`#crosshairTo-${measure.getAttrs().id}`);
25486
+ if (crosshairTo) {
25487
+ crosshairTo.x(toPoint.x);
25488
+ crosshairTo.y(toPoint.y);
25489
+ crosshairTo.rotation(angle);
25490
+ }
25491
+ const moveSeparationRect = measure.findOne(`#moveSeparationRect-${measure.getAttrs().id}`);
25492
+ if (moveSeparationRect) {
25493
+ const textSize$1 = measureText.measureSize(measureText.text());
25494
+ const isTextBiggerThanMeasureSpace = textSize$1.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25495
+ const multiplier = isTextBiggerThanMeasureSpace ? this.config.style.handler.noSpaceSeparationMultiplier : this.config.style.handler.spaceSeparationMultiplier;
25496
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, multiplier * textSize$1.height * orientation);
25497
+ moveSeparationRect.x(separatorPoint.left.x);
25498
+ moveSeparationRect.y(separatorPoint.left.y);
25499
+ moveSeparationRect.rotation(angle);
25500
+ }
25501
+ }
25502
+ projectPointToLine(fromPoint, toPoint, pointToProject) {
25503
+ const dx = toPoint.x - fromPoint.x;
25504
+ const dy = toPoint.y - fromPoint.y;
25505
+ const lenSq = dx * dx + dy * dy;
25506
+ const t = ((pointToProject.x - fromPoint.x) * dx + (pointToProject.y - fromPoint.y) * dy) / lenSq;
25507
+ return {
25508
+ x: fromPoint.x + t * dx,
25509
+ y: fromPoint.y + t * dy,
25510
+ t,
25511
+ flipped: t < 0
25512
+ };
25513
+ }
25514
+ buildCrosshair(name, node, point, angle) {
25515
+ const props = node.getAttrs();
25516
+ const crosshairSize = 60;
25517
+ const crosshair = new Konva.Group({
25518
+ id: `${name}-${props.id}`,
25519
+ x: point.x,
25520
+ y: point.y,
25521
+ rotation: angle,
25522
+ visible: false,
25523
+ listening: false,
25524
+ draggable: false
25525
+ });
25526
+ const horizontalLineFrom = new Konva.Line({
25527
+ points: [
25528
+ 0,
25529
+ 0,
25530
+ crosshairSize,
25531
+ 0
25532
+ ],
25533
+ x: -1 * (crosshairSize / 2),
25534
+ y: 0,
25535
+ stroke: "#CC0000",
25536
+ strokeWidth: 1
25537
+ });
25538
+ const verticalLineFrom = new Konva.Line({
25539
+ points: [
25540
+ 0,
25541
+ 0,
25542
+ 0,
25543
+ crosshairSize
25544
+ ],
25545
+ x: 0,
25546
+ y: -1 * crosshairSize / 2,
25547
+ stroke: "#CC0000",
25548
+ strokeWidth: 1
25549
+ });
25550
+ crosshair.add(horizontalLineFrom);
25551
+ crosshair.add(verticalLineFrom);
25552
+ return crosshair;
25553
+ }
25554
+ movePointPerpendicularToLine(fromPoint, toPoint, point, distance) {
25555
+ const dx = toPoint.x - fromPoint.x;
25556
+ const dy = toPoint.y - fromPoint.y;
25557
+ const len = Math.hypot(dx, dy);
25558
+ const ux = -dy / len;
25559
+ const uy = dx / len;
25560
+ return {
25561
+ x: point.x + ux * distance,
25562
+ y: point.y + uy * distance
25563
+ };
25564
+ }
25565
+ getAngle(fromPoint, toPoint) {
25566
+ let angle = this.angleBetweenPoints(fromPoint, toPoint);
25567
+ if (fromPoint.x > toPoint.x) angle = angle + 180;
25568
+ return angle;
25569
+ }
25570
+ flipOrientation(node) {
25571
+ this.destroySelectionHandlers(node);
25572
+ const currentOrientation = node.getAttrs().orientation ?? -1;
25573
+ node.setAttrs({ orientation: currentOrientation * -1 });
25574
+ this.instance.updateNode(this.serialize(node));
25575
+ this.createSelectionHandlers(node);
25576
+ this.updateSelectionHandlers(node);
25577
+ }
25578
+ getNormalizedDistance(node) {
25579
+ const stage = this.instance.getStage();
25580
+ const scale = stage.scaleX();
25581
+ const fromCircle = node.findOne(`#fromCircle-${node.getAttrs().id}`);
25582
+ const toCircle = node.findOne(`#toCircle-${node.getAttrs().id}`);
25583
+ if (fromCircle && toCircle) {
25584
+ const fromPoint = fromCircle.getAbsolutePosition();
25585
+ const toPoint = toCircle.getAbsolutePosition();
25586
+ return Math.hypot(toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) / scale;
25587
+ }
25588
+ return 0;
25589
+ }
25590
+ };
25591
+
24898
25592
  //#endregion
24899
25593
  //#region src/plugins/stage-zoom/constants.ts
24900
25594
  const WEAVE_STAGE_ZOOM_TYPE = {
@@ -28654,6 +29348,288 @@ var WeaveVideoToolAction = class extends WeaveAction {
28654
29348
  }
28655
29349
  };
28656
29350
 
29351
+ //#endregion
29352
+ //#region src/actions/measure-tool/constants.ts
29353
+ const MEASURE_TOOL_ACTION_NAME = "measureTool";
29354
+ const MEASURE_TOOL_STATE = {
29355
+ ["IDLE"]: "idle",
29356
+ ["SET_FROM"]: "set_from",
29357
+ ["SET_TO"]: "set_to",
29358
+ ["FINISHED"]: "finished"
29359
+ };
29360
+ const WEAVE_MEASURE_TOOL_DEFAULT_CONFIG = { style: { stroke: "#FF3366" } };
29361
+
29362
+ //#endregion
29363
+ //#region src/actions/measure-tool/measure-tool.ts
29364
+ var WeaveMeasureToolAction = class extends WeaveAction {
29365
+ initialized = false;
29366
+ initialCursor = null;
29367
+ onPropsChange = void 0;
29368
+ onInit = void 0;
29369
+ constructor(params) {
29370
+ super();
29371
+ this.config = mergeExceptArrays(WEAVE_MEASURE_TOOL_DEFAULT_CONFIG, params?.config ?? {});
29372
+ this.initialized = false;
29373
+ this.state = MEASURE_TOOL_STATE.IDLE;
29374
+ this.measureId = null;
29375
+ this.container = void 0;
29376
+ this.clickPoint = null;
29377
+ this.crosshairCursor = null;
29378
+ this.firstPoint = null;
29379
+ this.measureLine = null;
29380
+ this.measureContainer = void 0;
29381
+ this.props = this.initProps();
29382
+ }
29383
+ getName() {
29384
+ return MEASURE_TOOL_ACTION_NAME;
29385
+ }
29386
+ initProps() {
29387
+ return {
29388
+ orientation: -1,
29389
+ separation: 0,
29390
+ unit: "cm",
29391
+ unitPerPixel: 10
29392
+ };
29393
+ }
29394
+ setupEvents() {
29395
+ const stage = this.instance.getStage();
29396
+ window.addEventListener("keydown", (e) => {
29397
+ if (e.code === "Escape" && this.instance.getActiveAction() === MEASURE_TOOL_ACTION_NAME) this.cancelAction();
29398
+ });
29399
+ stage.on("pointermove", () => {
29400
+ if (this.state === MEASURE_TOOL_STATE.IDLE) return;
29401
+ if (this.state === MEASURE_TOOL_STATE.SET_TO) {
29402
+ const finalPoint = this.defineFinalPoint();
29403
+ if (this.measureLine && this.firstPoint) this.measureLine.points([
29404
+ 0,
29405
+ 0,
29406
+ finalPoint.x,
29407
+ finalPoint.y
29408
+ ]);
29409
+ }
29410
+ this.setCursor();
29411
+ });
29412
+ stage.on("pointerclick", () => {
29413
+ if (this.state === MEASURE_TOOL_STATE.IDLE) return;
29414
+ if (this.state === MEASURE_TOOL_STATE.SET_FROM) {
29415
+ this.handleSetFrom();
29416
+ return;
29417
+ }
29418
+ if (this.state === MEASURE_TOOL_STATE.SET_TO) this.handleSetTo();
29419
+ });
29420
+ this.initialized = true;
29421
+ }
29422
+ setState(state) {
29423
+ this.state = state;
29424
+ }
29425
+ addMeasure() {
29426
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
29427
+ if (selectionPlugin) {
29428
+ const tr = selectionPlugin.getTransformer();
29429
+ tr.hide();
29430
+ }
29431
+ this.instance.addEventListener("onZoomChange", () => {
29432
+ if (this.crosshairCursor) {
29433
+ const stage = this.instance.getStage();
29434
+ this.crosshairCursor.scale({
29435
+ x: 1 / stage.scaleX(),
29436
+ y: 1 / stage.scaleY()
29437
+ });
29438
+ }
29439
+ });
29440
+ this.buildCrosshairCursor();
29441
+ this.setCursor();
29442
+ this.setFocusStage();
29443
+ this.clickPoint = null;
29444
+ this.setState(MEASURE_TOOL_STATE.SET_FROM);
29445
+ }
29446
+ buildCrosshairCursor() {
29447
+ const stage = this.instance.getStage();
29448
+ const { mousePoint } = this.instance.getMousePointer();
29449
+ this.crosshairCursor = new Konva.Group({
29450
+ x: mousePoint?.x,
29451
+ y: mousePoint?.y,
29452
+ scale: {
29453
+ x: 1 / stage.scaleX(),
29454
+ y: 1 / stage.scaleY()
29455
+ },
29456
+ listening: false,
29457
+ draggable: false
29458
+ });
29459
+ const crosshairSize = 60;
29460
+ const lineH = new Konva.Line({
29461
+ points: [
29462
+ 0,
29463
+ 0,
29464
+ crosshairSize,
29465
+ 0
29466
+ ],
29467
+ x: -1 * (crosshairSize / 2),
29468
+ y: 0,
29469
+ stroke: this.config.style.stroke,
29470
+ strokeWidth: 1
29471
+ });
29472
+ const lineV = new Konva.Line({
29473
+ points: [
29474
+ 0,
29475
+ 0,
29476
+ 0,
29477
+ crosshairSize
29478
+ ],
29479
+ x: 0,
29480
+ y: -1 * crosshairSize / 2,
29481
+ stroke: this.config.style.stroke,
29482
+ strokeWidth: 1
29483
+ });
29484
+ this.crosshairCursor.add(lineH);
29485
+ this.crosshairCursor.add(lineV);
29486
+ this.instance.getStage().on("pointermove.measureTool", () => {
29487
+ const pos = this.instance.getStage().getRelativePointerPosition();
29488
+ if (this.crosshairCursor && pos) {
29489
+ this.crosshairCursor.position(pos);
29490
+ this.crosshairCursor.moveToTop();
29491
+ }
29492
+ });
29493
+ this.instance.getUtilityLayer()?.add(this.crosshairCursor);
29494
+ }
29495
+ handleSetFrom() {
29496
+ const stage = this.instance.getStage();
29497
+ const realMousePoint = stage.getRelativePointerPosition();
29498
+ const { container, measureContainer } = this.instance.getMousePointer();
29499
+ this.clickPoint = realMousePoint;
29500
+ this.container = container;
29501
+ this.measureContainer = measureContainer;
29502
+ this.firstPoint = new Konva.Circle({
29503
+ x: this.clickPoint?.x ?? 0,
29504
+ y: this.clickPoint?.y ?? 0,
29505
+ radius: 6,
29506
+ fill: "#FFFFFF",
29507
+ stroke: "#000000",
29508
+ scale: {
29509
+ x: 1 / stage.scaleX(),
29510
+ y: 1 / stage.scaleY()
29511
+ },
29512
+ strokeWidth: 1,
29513
+ listening: false,
29514
+ draggable: false
29515
+ });
29516
+ this.measureLine = new Konva.Line({
29517
+ x: this.clickPoint?.x,
29518
+ y: this.clickPoint?.y,
29519
+ points: [0, 0],
29520
+ scale: {
29521
+ x: 1 / stage.scaleX(),
29522
+ y: 1 / stage.scaleY()
29523
+ },
29524
+ stroke: this.config.style.stroke,
29525
+ dashed: [4, 4],
29526
+ strokeWidth: 1,
29527
+ listening: false,
29528
+ draggable: false
29529
+ });
29530
+ this.instance.getUtilityLayer()?.add(this.firstPoint);
29531
+ this.instance.getUtilityLayer()?.add(this.measureLine);
29532
+ this.firstPoint.moveToTop();
29533
+ this.measureLine.moveToBottom();
29534
+ this.setState(MEASURE_TOOL_STATE.SET_TO);
29535
+ }
29536
+ handleSetTo() {
29537
+ const stage = this.instance.getStage();
29538
+ const realMousePoint = stage.getRelativePointerPosition();
29539
+ const { container } = this.instance.getMousePointer();
29540
+ this.clickPoint = realMousePoint;
29541
+ this.container = container;
29542
+ const nodeHandler = this.instance.getNodeHandler("measure");
29543
+ if (nodeHandler && this.firstPoint) {
29544
+ this.measureId = v4_default();
29545
+ const node = nodeHandler.create(this.measureId, {
29546
+ ...this.props,
29547
+ id: this.measureId,
29548
+ x: 0,
29549
+ y: 0,
29550
+ fromPoint: {
29551
+ x: this.firstPoint.x(),
29552
+ y: this.firstPoint.y()
29553
+ },
29554
+ toPoint: {
29555
+ x: this.clickPoint?.x ?? 0,
29556
+ y: this.clickPoint?.y ?? 0
29557
+ },
29558
+ draggable: true
29559
+ });
29560
+ this.instance.addOnceEventListener("onNodeRenderedAdded", (child) => {
29561
+ if (child.getAttrs().id === this.measureId) {
29562
+ if (typeof this.measureContainer !== "undefined" && this.measureContainer?.id() !== "mainLayer") {
29563
+ const nodeInstance = this.instance.getMainLayer()?.findOne(`#${this.measureId}`);
29564
+ const stage$1 = this.instance.getStage();
29565
+ let realContainer = this.measureContainer;
29566
+ if (realContainer?.getAttrs().nodeId !== void 0) realContainer = stage$1.findOne(`#${realContainer?.getAttrs().nodeId}`);
29567
+ if (nodeInstance) moveNodeToContainer(this.instance, nodeInstance, realContainer);
29568
+ }
29569
+ this.cancelAction();
29570
+ }
29571
+ });
29572
+ this.instance.addNode(node, "mainLayer");
29573
+ this.setState(MEASURE_TOOL_STATE.FINISHED);
29574
+ }
29575
+ }
29576
+ trigger(cancelAction) {
29577
+ if (!this.instance) throw new Error("Instance not defined");
29578
+ if (!this.initialized) this.setupEvents();
29579
+ this.cancelAction = cancelAction;
29580
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
29581
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
29582
+ this.props = this.initProps();
29583
+ this.addMeasure();
29584
+ }
29585
+ cleanup() {
29586
+ const stage = this.instance.getStage();
29587
+ stage.container().style.cursor = "default";
29588
+ this.instance.getStage().off("pointermove.measureTool");
29589
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
29590
+ if (selectionPlugin) {
29591
+ const node = stage.findOne(`#${this.measureId}`);
29592
+ if (node) selectionPlugin.setSelectedNodes([node]);
29593
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
29594
+ }
29595
+ if (this.crosshairCursor) this.crosshairCursor.destroy();
29596
+ if (this.firstPoint) this.firstPoint.destroy();
29597
+ if (this.measureLine) this.measureLine.destroy();
29598
+ this.initialCursor = null;
29599
+ this.measureId = null;
29600
+ this.container = void 0;
29601
+ this.clickPoint = null;
29602
+ this.firstPoint = null;
29603
+ this.measureLine = null;
29604
+ this.setState(MEASURE_TOOL_STATE.IDLE);
29605
+ }
29606
+ setCursor() {
29607
+ const stage = this.instance.getStage();
29608
+ stage.container().style.cursor = "none";
29609
+ }
29610
+ setFocusStage() {
29611
+ const stage = this.instance.getStage();
29612
+ stage.container().tabIndex = 1;
29613
+ stage.container().blur();
29614
+ stage.container().focus();
29615
+ }
29616
+ defineFinalPoint() {
29617
+ if (!this.measureLine || !this.measureContainer) return {
29618
+ x: 0,
29619
+ y: 0
29620
+ };
29621
+ const stage = this.instance.getStage();
29622
+ const realMousePoint = this.instance.getStage().getRelativePointerPosition();
29623
+ const pos = {
29624
+ x: 0,
29625
+ y: 0
29626
+ };
29627
+ pos.x = ((realMousePoint?.x ?? 0) - this.measureLine.x()) * stage.scaleX();
29628
+ pos.y = ((realMousePoint?.y ?? 0) - this.measureLine.y()) * stage.scaleY();
29629
+ return pos;
29630
+ }
29631
+ };
29632
+
28657
29633
  //#endregion
28658
29634
  //#region src/plugins/stage-grid/stage-grid.ts
28659
29635
  var WeaveStageGridPlugin = class extends WeavePlugin {
@@ -29369,6 +30345,11 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
29369
30345
  const containerParent = stage.container().parentNode;
29370
30346
  if (!this.enabled) return;
29371
30347
  if (containerParent) {
30348
+ const upscaleScale = stage.getAttr("upscaleScale");
30349
+ if (upscaleScale === 1) {
30350
+ stage.width(containerParent.clientWidth);
30351
+ stage.height(containerParent.clientHeight);
30352
+ }
29372
30353
  setupUpscaleStage(this.instance, stage);
29373
30354
  const plugins = this.instance.getPlugins();
29374
30355
  for (const pluginId of Object.keys(plugins)) {
@@ -29378,11 +30359,14 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
29378
30359
  }
29379
30360
  }
29380
30361
  onInit() {
29381
- window.addEventListener("resize", () => {
30362
+ const throttledResize = (0, import_lodash.throttle)(() => {
29382
30363
  this.resizeStage();
30364
+ }, 100);
30365
+ window.addEventListener("resize", () => {
30366
+ throttledResize();
29383
30367
  });
29384
30368
  const resizeObserver = new ResizeObserver(() => {
29385
- this.resizeStage();
30369
+ throttledResize();
29386
30370
  });
29387
30371
  const stage = this.instance.getStage();
29388
30372
  resizeObserver.observe(stage.container());
@@ -30034,7 +31018,9 @@ var WeaveNodesEdgeSnappingPlugin = class extends WeavePlugin {
30034
31018
  const utilityLayer = this.instance.getUtilityLayer();
30035
31019
  if (!this.enabled) return;
30036
31020
  if (!utilityLayer) return;
31021
+ if (e.target.getAttr("edgeSnappingDisableOnDrag")) return;
30037
31022
  const { targetNode: node, skipNodes } = getTargetAndSkipNodes(this.instance, e);
31023
+ if (node?.getAttr("edgeSnappingDisable")) return;
30038
31024
  if (typeof node === "undefined") return;
30039
31025
  const nodeParent = this.getSelectionParentNode(node);
30040
31026
  if (nodeParent === null) return;
@@ -32136,7 +33122,7 @@ var WeaveRegisterManager = class {
32136
33122
 
32137
33123
  //#endregion
32138
33124
  //#region package.json
32139
- var version = "2.10.0";
33125
+ var version = "2.11.1";
32140
33126
 
32141
33127
  //#endregion
32142
33128
  //#region src/managers/setup.ts
@@ -32793,6 +33779,10 @@ var Weave = class {
32793
33779
  this.moduleLogger.debug(`Listening event [${event}]`);
32794
33780
  this.emitter.on(event, callback);
32795
33781
  }
33782
+ addOnceEventListener(event, callback) {
33783
+ this.moduleLogger.debug(`Listening once event [${event}]`);
33784
+ this.emitter.once(event).then(callback);
33785
+ }
32796
33786
  removeEventListener(event, callback) {
32797
33787
  this.moduleLogger.debug(`Removing listening to event [${event}]`);
32798
33788
  this.emitter.off(event, callback);
@@ -33519,5 +34509,5 @@ var WeaveLineToolAction = class extends WeaveAction {
33519
34509
  };
33520
34510
 
33521
34511
  //#endregion
33522
- 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, LINE_TOOL_ACTION_NAME, LINE_TOOL_DEFAULT_CONFIG, LINE_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, WeaveLineToolAction, 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, 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 };
34512
+ 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, 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_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, 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, 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 };
33523
34513
  //# sourceMappingURL=sdk.js.map