@inditextech/weave-sdk 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk.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,661 @@ 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
+
24904
+ //#endregion
24905
+ //#region src/nodes/measure/measure.ts
24906
+ const HANDLE_SPACE_SEPARATION_MULTIPLIER = 1.5;
24907
+ const HANDLE_NO_SPACE_SEPARATION_MULTIPLIER = 2.5;
24908
+ var WeaveMeasureNode = class extends WeaveNode {
24909
+ nodeType = WEAVE_MEASURE_NODE_TYPE;
24910
+ handlePointCircleRadius = 6;
24911
+ onRender(props) {
24912
+ const measure = new Konva.Group({
24913
+ ...props,
24914
+ name: "node",
24915
+ draggable: false
24916
+ });
24917
+ const color = props.color || "#FF3366";
24918
+ const fromPoint = props.fromPoint;
24919
+ const toPoint = props.toPoint;
24920
+ const separation = props.separation ?? 100;
24921
+ const orientation = props.orientation ?? -1;
24922
+ const textPadding = props.textPadding ?? 20;
24923
+ const separationPadding = props.separationPadding ?? 30;
24924
+ const unit = props.unit ?? "cms";
24925
+ const unitPerPixel = props.unitPerPixel ?? 100;
24926
+ const fromFinalPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, (separation + separationPadding) * orientation);
24927
+ const linePerpFrom = new Konva.Line({
24928
+ id: `linePerpFrom-${props.id}`,
24929
+ nodeId: props.id,
24930
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24931
+ points: [
24932
+ fromPoint.x,
24933
+ fromPoint.y,
24934
+ fromFinalPerp.left.x,
24935
+ fromFinalPerp.left.y
24936
+ ],
24937
+ stroke: color,
24938
+ strokeWidth: 1,
24939
+ dash: [4, 4]
24940
+ });
24941
+ measure.add(linePerpFrom);
24942
+ const toFinalPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, (separation + separationPadding) * orientation);
24943
+ const linePerpTo = new Konva.Line({
24944
+ id: `linePerpTo-${props.id}`,
24945
+ nodeId: props.id,
24946
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24947
+ points: [
24948
+ toPoint.x,
24949
+ toPoint.y,
24950
+ toFinalPerp.left.x,
24951
+ toFinalPerp.left.y
24952
+ ],
24953
+ stroke: color,
24954
+ strokeWidth: 1,
24955
+ dash: [4, 4]
24956
+ });
24957
+ measure.add(linePerpTo);
24958
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
24959
+ const fromCircle = new Konva.Circle({
24960
+ id: `fromCircle-${props.id}`,
24961
+ nodeId: props.id,
24962
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24963
+ x: fromPerp.left.x,
24964
+ y: fromPerp.left.y,
24965
+ radius: 3,
24966
+ fill: color
24967
+ });
24968
+ measure.add(fromCircle);
24969
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
24970
+ const toCircle = new Konva.Circle({
24971
+ id: `toCircle-${props.id}`,
24972
+ nodeId: props.id,
24973
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24974
+ x: toPerp.left.x,
24975
+ y: toPerp.left.y,
24976
+ radius: 3,
24977
+ fill: color
24978
+ });
24979
+ measure.add(toCircle);
24980
+ const midPoint = this.midPoint(fromPerp.left, toPerp.left);
24981
+ const distance = this.distanceBetweenPoints(fromPoint, toPoint);
24982
+ const units = distance / unitPerPixel;
24983
+ const text = `${units.toFixed(2)} ${unit}`;
24984
+ const measureText = new Konva.Text({
24985
+ id: `measureText-${props.id}`,
24986
+ nodeId: props.id,
24987
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
24988
+ x: midPoint.x,
24989
+ y: midPoint.y,
24990
+ text,
24991
+ fontFamily: "monospace",
24992
+ fontSize: 14,
24993
+ verticalAlign: "middle",
24994
+ align: "center",
24995
+ fill: color
24996
+ });
24997
+ const angle = this.getAngle(fromPoint, toPoint);
24998
+ const textSize = measureText.measureSize(text);
24999
+ const textOffsetX = textSize.width / 2;
25000
+ measureText.rotation(angle);
25001
+ measureText.offsetX(textSize.width / 2);
25002
+ measureText.offsetY(textSize.height / 2);
25003
+ if (textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left)) {
25004
+ const perpPointTextMid = this.perpendicularPoint(fromPerp.left, toPerp.left, midPoint, textSize.height * orientation);
25005
+ measureText.x(perpPointTextMid.left.x);
25006
+ measureText.y(perpPointTextMid.left.y);
25007
+ }
25008
+ measure.add(measureText);
25009
+ const pointLeftText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textPadding, false);
25010
+ const pointRightText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textPadding, true);
25011
+ const lineLeft = new Konva.Line({
25012
+ id: `lineLeft-${props.id}`,
25013
+ nodeId: props.id,
25014
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
25015
+ points: [
25016
+ fromPerp.left.x,
25017
+ fromPerp.left.y,
25018
+ pointLeftText.x,
25019
+ pointLeftText.y
25020
+ ],
25021
+ stroke: color,
25022
+ strokeWidth: 1
25023
+ });
25024
+ const lineRight = new Konva.Line({
25025
+ id: `lineRight-${props.id}`,
25026
+ nodeId: props.id,
25027
+ nodeType: WEAVE_MEASURE_NODE_TYPE,
25028
+ points: [
25029
+ pointRightText.x,
25030
+ pointRightText.y,
25031
+ toPerp.left.x,
25032
+ toPerp.left.y
25033
+ ],
25034
+ stroke: color,
25035
+ strokeWidth: 1
25036
+ });
25037
+ measure.add(measureText);
25038
+ measure.add(lineLeft);
25039
+ measure.add(lineRight);
25040
+ this.setupDefaultNodeAugmentation(measure);
25041
+ measure.getTransformerProperties = function() {
25042
+ return {
25043
+ resizeEnabled: false,
25044
+ rotateEnabled: false,
25045
+ borderEnabled: false
25046
+ };
25047
+ };
25048
+ this.instance.addEventListener("onZoomChange", () => {
25049
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
25050
+ if (selectionPlugin) {
25051
+ const selectedNodes = selectionPlugin.getSelectedNodes();
25052
+ if (selectedNodes.length === 1 && selectedNodes[0].getAttrs().id === measure.getAttrs().id) this.updateSelectionHandlers(measure);
25053
+ }
25054
+ });
25055
+ this.instance.addEventListener("onNodesChange", () => {
25056
+ let isSelected = false;
25057
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
25058
+ if (selectionPlugin) {
25059
+ const selectedNodes = selectionPlugin.getSelectedNodes();
25060
+ if (selectedNodes.length === 1 && selectedNodes[0].getAttrs().id === measure.getAttrs().id) {
25061
+ isSelected = true;
25062
+ this.createSelectionHandlers(measure);
25063
+ this.updateSelectionHandlers(measure);
25064
+ }
25065
+ }
25066
+ if (!isSelected) this.destroySelectionHandlers(measure);
25067
+ });
25068
+ this.instance.addEventListener("onMeasureReferenceChange", ({ unit: unit$1, unitPerPixel: unitPerPixel$1 }) => {
25069
+ measure.setAttrs({
25070
+ unit: unit$1,
25071
+ unitPerPixel: unitPerPixel$1
25072
+ });
25073
+ this.instance.updateNode(this.serialize(measure));
25074
+ });
25075
+ measure.allowedAnchors = function() {
25076
+ return [];
25077
+ };
25078
+ this.setupDefaultNodeEvents(measure);
25079
+ return measure;
25080
+ }
25081
+ createSelectionHandlers(node) {
25082
+ const props = node.getAttrs();
25083
+ const fromPoint = props.fromPoint;
25084
+ const toPoint = props.toPoint;
25085
+ const separation = props.separation ?? 100;
25086
+ const orientation = props.orientation ?? -1;
25087
+ const angle = this.getAngle(fromPoint, toPoint);
25088
+ const moveToCircleAct = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
25089
+ const crosshairFromAct = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
25090
+ const moveFromCircleAct = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
25091
+ const crosshairToAct = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
25092
+ const moveSeparationRectAct = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
25093
+ const measureText = node.findOne(`#measureText-${node.getAttrs().id}`);
25094
+ if (moveToCircleAct && crosshairFromAct && moveFromCircleAct && crosshairToAct && moveSeparationRectAct) return;
25095
+ const textSize = measureText?.measureSize(measureText.text());
25096
+ const moveFromCircle = new Konva.Circle({
25097
+ id: `moveFromCircle-${props.id}`,
25098
+ edgeDistanceDisableOnDrag: true,
25099
+ edgeSnappingDisableOnDrag: true,
25100
+ x: fromPoint.x,
25101
+ y: fromPoint.y,
25102
+ radius: this.handlePointCircleRadius,
25103
+ fill: "#FFFFFF",
25104
+ stroke: "#000000",
25105
+ strokeWidth: 1,
25106
+ draggable: true
25107
+ });
25108
+ const crosshairFrom = this.buildCrosshair("crosshairFrom", node, fromPoint, angle);
25109
+ const moveToCircle = new Konva.Circle({
25110
+ id: `moveToCircle-${props.id}`,
25111
+ edgeDistanceDisableOnDrag: true,
25112
+ edgeSnappingDisableOnDrag: true,
25113
+ x: toPoint.x,
25114
+ y: toPoint.y,
25115
+ radius: this.handlePointCircleRadius,
25116
+ fill: "#FFFFFF",
25117
+ stroke: "#000000",
25118
+ strokeWidth: 1,
25119
+ draggable: true
25120
+ });
25121
+ const crosshairTo = this.buildCrosshair("crosshairTo", node, toPoint, angle);
25122
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
25123
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25124
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
25125
+ const isTextBiggerThanMeasureSpace = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25126
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, (isTextBiggerThanMeasureSpace ? HANDLE_NO_SPACE_SEPARATION_MULTIPLIER : HANDLE_SPACE_SEPARATION_MULTIPLIER) * (textSize?.height ?? 0) * orientation);
25127
+ const moveSeparationRect = new Konva.Rect({
25128
+ id: `moveSeparationRect-${props.id}`,
25129
+ edgeDistanceDisableOnDrag: true,
25130
+ edgeSnappingDisableOnDrag: true,
25131
+ x: separatorPoint.left.x,
25132
+ y: separatorPoint.left.y,
25133
+ width: this.handlePointCircleRadius * 2 * 3,
25134
+ height: this.handlePointCircleRadius * 2,
25135
+ offsetX: this.handlePointCircleRadius * 3,
25136
+ offsetY: this.handlePointCircleRadius,
25137
+ cornerRadius: this.handlePointCircleRadius,
25138
+ rotation: angle,
25139
+ fill: "#FFFFFF",
25140
+ stroke: "#000000",
25141
+ strokeWidth: 1,
25142
+ draggable: true
25143
+ });
25144
+ node.add(moveFromCircle);
25145
+ node.add(crosshairFrom);
25146
+ node.add(moveToCircle);
25147
+ node.add(crosshairTo);
25148
+ node.add(moveSeparationRect);
25149
+ moveFromCircle.moveToTop();
25150
+ crosshairFrom.moveToBottom();
25151
+ moveToCircle.moveToTop();
25152
+ crosshairTo.moveToBottom();
25153
+ moveSeparationRect.moveToTop();
25154
+ moveFromCircle.on("dragstart", () => {
25155
+ moveFromCircle.visible(false);
25156
+ moveToCircle.visible(false);
25157
+ moveSeparationRect.visible(false);
25158
+ crosshairFrom.visible(true);
25159
+ });
25160
+ moveFromCircle.on("dragmove", (e) => {
25161
+ const actCircle = e.target;
25162
+ const realNode = e.target.getParent();
25163
+ const newFromPoint = {
25164
+ x: actCircle.x(),
25165
+ y: actCircle.y()
25166
+ };
25167
+ realNode.setAttrs({ fromPoint: newFromPoint });
25168
+ this.onUpdate(realNode, this.serialize(realNode).props);
25169
+ });
25170
+ moveFromCircle.on("dragend", (e) => {
25171
+ const actCircle = e.target;
25172
+ const realNode = e.target.getParent();
25173
+ moveFromCircle.visible(true);
25174
+ moveToCircle.visible(true);
25175
+ moveSeparationRect.visible(true);
25176
+ crosshairFrom.visible(false);
25177
+ const newFromPoint = {
25178
+ x: actCircle.x(),
25179
+ y: actCircle.y()
25180
+ };
25181
+ realNode.setAttrs({ fromPoint: newFromPoint });
25182
+ this.instance.updateNode(this.serialize(realNode));
25183
+ });
25184
+ moveToCircle.on("dragstart", () => {
25185
+ moveFromCircle.visible(false);
25186
+ moveToCircle.visible(false);
25187
+ moveSeparationRect.visible(false);
25188
+ crosshairTo.visible(true);
25189
+ });
25190
+ moveToCircle.on("dragmove", (e) => {
25191
+ const actCircle = e.target;
25192
+ const realNode = e.target.getParent();
25193
+ const newToPoint = {
25194
+ x: actCircle.x(),
25195
+ y: actCircle.y()
25196
+ };
25197
+ realNode.setAttrs({ toPoint: newToPoint });
25198
+ this.onUpdate(realNode, this.serialize(realNode).props);
25199
+ });
25200
+ moveToCircle.on("dragend", (e) => {
25201
+ const actCircle = e.target;
25202
+ const realNode = e.target.getParent();
25203
+ moveFromCircle.visible(true);
25204
+ moveToCircle.visible(true);
25205
+ moveSeparationRect.visible(true);
25206
+ crosshairTo.visible(false);
25207
+ const newToPoint = {
25208
+ x: actCircle.x(),
25209
+ y: actCircle.y()
25210
+ };
25211
+ realNode.setAttrs({ toPoint: newToPoint });
25212
+ this.instance.updateNode(this.serialize(realNode));
25213
+ });
25214
+ let originalSeparationHandlerPosition = {
25215
+ x: 0,
25216
+ y: 0
25217
+ };
25218
+ moveSeparationRect.on("dragstart", () => {
25219
+ const pos = moveSeparationRect.position();
25220
+ originalSeparationHandlerPosition = pos;
25221
+ });
25222
+ moveSeparationRect.on("dragmove", (e) => {
25223
+ const pos = e.target.position();
25224
+ const realNode = e.target.getParent();
25225
+ const fromPoint$1 = node.getAttrs().fromPoint;
25226
+ const toPoint$1 = node.getAttrs().toPoint;
25227
+ const midPoint = this.midPoint(fromPoint$1, toPoint$1);
25228
+ const isTextBiggerThanMeasureSpace$1 = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25229
+ const separatorPoint$1 = this.perpendicularPoint(fromPoint$1, toPoint$1, midPoint, (isTextBiggerThanMeasureSpace$1 ? HANDLE_NO_SPACE_SEPARATION_MULTIPLIER : HANDLE_SPACE_SEPARATION_MULTIPLIER) * (textSize?.height ?? 0) * orientation);
25230
+ const pointInLine = this.projectPointToLine(separatorPoint$1.left, originalSeparationHandlerPosition, pos);
25231
+ if (isNaN(pointInLine.t)) {
25232
+ const point = this.movePointPerpendicularToLine(fromPoint$1, toPoint$1, separatorPoint$1.left, ((isTextBiggerThanMeasureSpace$1 ? HANDLE_NO_SPACE_SEPARATION_MULTIPLIER : HANDLE_SPACE_SEPARATION_MULTIPLIER) * (textSize?.height ?? 0) + 1) * orientation);
25233
+ moveSeparationRect.position(point);
25234
+ originalSeparationHandlerPosition = point;
25235
+ realNode.setAttrs({ separation: (textSize?.height ?? 0) + 1 });
25236
+ } else {
25237
+ moveSeparationRect.position(pointInLine);
25238
+ const dx = originalSeparationHandlerPosition.x - separatorPoint$1.left.x;
25239
+ const dy = originalSeparationHandlerPosition.y - separatorPoint$1.left.y;
25240
+ const len = Math.hypot(dx, dy);
25241
+ let newLength = pointInLine.t * len;
25242
+ if (newLength < 0) newLength = 0;
25243
+ realNode.setAttrs({ separation: newLength });
25244
+ }
25245
+ this.onUpdate(realNode, this.serialize(realNode).props);
25246
+ });
25247
+ moveSeparationRect.on("dragend", (e) => {
25248
+ const pos = e.target.position();
25249
+ const realNode = e.target.getParent();
25250
+ const fromPoint$1 = node.getAttrs().fromPoint;
25251
+ const toPoint$1 = node.getAttrs().toPoint;
25252
+ const midPoint = this.midPoint(fromPoint$1, toPoint$1);
25253
+ const separatorPoint$1 = this.perpendicularPoint(fromPoint$1, toPoint$1, midPoint, (isTextBiggerThanMeasureSpace ? HANDLE_NO_SPACE_SEPARATION_MULTIPLIER : HANDLE_SPACE_SEPARATION_MULTIPLIER) * (textSize?.height ?? 0) * orientation);
25254
+ const pointInLine = this.projectPointToLine(separatorPoint$1.left, originalSeparationHandlerPosition, pos);
25255
+ moveSeparationRect.position(pointInLine);
25256
+ const dx = originalSeparationHandlerPosition.x - separatorPoint$1.left.x;
25257
+ const dy = originalSeparationHandlerPosition.y - separatorPoint$1.left.y;
25258
+ const len = Math.hypot(dx, dy);
25259
+ let newLength = pointInLine.t * len;
25260
+ if (newLength < 0) newLength = 0;
25261
+ realNode.setAttrs({ separation: newLength });
25262
+ this.instance.updateNode(this.serialize(realNode));
25263
+ });
25264
+ }
25265
+ updateSelectionHandlers(node) {
25266
+ const stage = this.instance.getStage();
25267
+ const scale = stage.scaleX();
25268
+ const fromPoint = node.getAttrs().fromPoint;
25269
+ const toPoint = node.getAttrs().toPoint;
25270
+ const moveToCircle = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
25271
+ const crosshairFrom = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
25272
+ const moveFromCircle = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
25273
+ const crosshairTo = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
25274
+ const moveSeparationRect = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
25275
+ if (moveToCircle) moveToCircle.scale({
25276
+ x: 1 / scale,
25277
+ y: 1 / scale
25278
+ });
25279
+ if (crosshairFrom) crosshairFrom.scale({
25280
+ x: 1 / scale,
25281
+ y: 1 / scale
25282
+ });
25283
+ if (moveFromCircle) moveFromCircle.scale({
25284
+ x: 1 / scale,
25285
+ y: 1 / scale
25286
+ });
25287
+ if (crosshairTo) crosshairTo.scale({
25288
+ x: 1 / scale,
25289
+ y: 1 / scale
25290
+ });
25291
+ if (moveSeparationRect) {
25292
+ const measureText = node.findOne(`#measureText-${node.getAttrs().id}`);
25293
+ const angle = this.getAngle(fromPoint, toPoint);
25294
+ const textSize = measureText?.measureSize(measureText.text());
25295
+ const separation = node.getAttrs().separation ?? 100;
25296
+ const orientation = node.getAttrs().orientation ?? -1;
25297
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
25298
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25299
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
25300
+ const isTextBiggerThanMeasureSpace = (textSize?.width ?? 0) > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25301
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, (isTextBiggerThanMeasureSpace ? HANDLE_NO_SPACE_SEPARATION_MULTIPLIER : HANDLE_SPACE_SEPARATION_MULTIPLIER) * (textSize?.height ?? 0) * orientation);
25302
+ moveSeparationRect.x(separatorPoint.left.x);
25303
+ moveSeparationRect.y(separatorPoint.left.y);
25304
+ moveSeparationRect.rotation(angle);
25305
+ moveSeparationRect.scale({
25306
+ x: 1 / scale,
25307
+ y: 1 / scale
25308
+ });
25309
+ }
25310
+ }
25311
+ destroySelectionHandlers(node) {
25312
+ const moveToCircle = node.findOne(`#moveToCircle-${node.getAttrs().id}`);
25313
+ const crosshairFrom = node.findOne(`#crosshairFrom-${node.getAttrs().id}`);
25314
+ const moveFromCircle = node.findOne(`#moveFromCircle-${node.getAttrs().id}`);
25315
+ const crosshairTo = node.findOne(`#crosshairTo-${node.getAttrs().id}`);
25316
+ const moveSeparationRect = node.findOne(`#moveSeparationRect-${node.getAttrs().id}`);
25317
+ if (moveToCircle) moveToCircle.destroy();
25318
+ if (crosshairFrom) crosshairFrom.destroy();
25319
+ if (moveFromCircle) moveFromCircle.destroy();
25320
+ if (crosshairTo) crosshairTo.destroy();
25321
+ if (moveSeparationRect) moveSeparationRect.destroy();
25322
+ }
25323
+ pointFromMid(from, to, distance, towardsSecond = true) {
25324
+ const mx = (from.x + to.x) / 2;
25325
+ const my = (from.y + to.y) / 2;
25326
+ const dx = to.x - from.x;
25327
+ const dy = to.y - from.y;
25328
+ const len = Math.hypot(dx, dy);
25329
+ const ux = dx / len;
25330
+ const uy = dy / len;
25331
+ const sign = towardsSecond ? 1 : -1;
25332
+ return {
25333
+ x: mx + ux * distance * sign,
25334
+ y: my + uy * distance * sign
25335
+ };
25336
+ }
25337
+ angleBetweenPoints(from, to) {
25338
+ return Math.atan2(to.y - from.y, to.x - from.x) * 180 / Math.PI;
25339
+ }
25340
+ midPoint(from, to) {
25341
+ return {
25342
+ x: (from.x + to.x) / 2,
25343
+ y: (from.y + to.y) / 2
25344
+ };
25345
+ }
25346
+ perpendicularPoint(from, to, point, distance) {
25347
+ const dx = to.x - from.x;
25348
+ const dy = to.y - from.y;
25349
+ const perpX = -dy;
25350
+ const perpY = dx;
25351
+ const len = Math.hypot(perpX, perpY);
25352
+ const ux = perpX / len;
25353
+ const uy = perpY / len;
25354
+ return {
25355
+ left: {
25356
+ x: point.x + ux * distance,
25357
+ y: point.y + uy * distance
25358
+ },
25359
+ right: {
25360
+ x: point.x - ux * distance,
25361
+ y: point.y - uy * distance
25362
+ }
25363
+ };
25364
+ }
25365
+ distanceBetweenPoints(from, to) {
25366
+ return Math.hypot(to.x - from.x, to.y - from.y);
25367
+ }
25368
+ onUpdate(nodeInstance, nextProps) {
25369
+ nodeInstance.setAttrs({ ...nextProps });
25370
+ const measure = nodeInstance;
25371
+ const fromPoint = nextProps.fromPoint;
25372
+ const toPoint = nextProps.toPoint;
25373
+ const separation = nextProps.separation ?? 100;
25374
+ const orientation = nextProps.orientation ?? -1;
25375
+ const textPadding = nextProps.textPadding ?? 20;
25376
+ const separationPadding = nextProps.separationPadding ?? 30;
25377
+ const unit = nextProps.unit ?? "cms";
25378
+ const unitPerPixel = nextProps.unitPerPixel ?? 100;
25379
+ const fromFinalPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, (separation + separationPadding) * orientation);
25380
+ const linePerpFrom = measure.findOne(`#linePerpFrom-${nextProps.id}`);
25381
+ linePerpFrom?.points([
25382
+ fromPoint.x,
25383
+ fromPoint.y,
25384
+ fromFinalPerp.left.x,
25385
+ fromFinalPerp.left.y
25386
+ ]);
25387
+ const toFinalPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, (separation + separationPadding) * orientation);
25388
+ const linePerpTo = measure.findOne(`#linePerpTo-${nextProps.id}`);
25389
+ linePerpTo?.points([
25390
+ toPoint.x,
25391
+ toPoint.y,
25392
+ toFinalPerp.left.x,
25393
+ toFinalPerp.left.y
25394
+ ]);
25395
+ const fromPerp = this.perpendicularPoint(fromPoint, toPoint, fromPoint, separation * orientation);
25396
+ const fromCircle = measure.findOne(`#fromCircle-${nextProps.id}`);
25397
+ fromCircle?.position({
25398
+ x: fromPerp.left.x,
25399
+ y: fromPerp.left.y
25400
+ });
25401
+ const toPerp = this.perpendicularPoint(fromPoint, toPoint, toPoint, separation * orientation);
25402
+ const toCircle = measure.findOne(`#toCircle-${nextProps.id}`);
25403
+ toCircle?.position({
25404
+ x: toPerp.left.x,
25405
+ y: toPerp.left.y
25406
+ });
25407
+ const midPoint = this.midPoint(fromPerp.left, toPerp.left);
25408
+ const distance = this.distanceBetweenPoints(fromPoint, toPoint);
25409
+ const units = distance / unitPerPixel;
25410
+ const text = `${units.toFixed(2)} ${unit}`;
25411
+ const measureText = measure.findOne(`#measureText-${nextProps.id}`);
25412
+ const angle = this.getAngle(fromPoint, toPoint);
25413
+ const textSize = measureText.measureSize(text);
25414
+ const textOffsetX = textSize.width / 2;
25415
+ measureText?.text(text);
25416
+ measureText?.rotation(angle);
25417
+ measureText?.x(midPoint.x);
25418
+ measureText?.y(midPoint.y);
25419
+ measureText?.offsetX(textSize.width / 2);
25420
+ measureText?.offsetY(textSize.height / 2);
25421
+ if (textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left)) {
25422
+ const perpPointTextMid = this.perpendicularPoint(fromPerp.left, toPerp.left, midPoint, textSize.height * orientation);
25423
+ measureText.x(perpPointTextMid.left.x);
25424
+ measureText.y(perpPointTextMid.left.y);
25425
+ }
25426
+ const pointLeftText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textPadding, false);
25427
+ const pointRightText = this.pointFromMid(fromPerp.left, toPerp.left, textSize.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left) ? 0 : textOffsetX + textPadding, true);
25428
+ const lineLeft = measure.findOne(`#lineLeft-${nextProps.id}`);
25429
+ lineLeft?.points([
25430
+ fromPerp.left.x,
25431
+ fromPerp.left.y,
25432
+ pointLeftText.x,
25433
+ pointLeftText.y
25434
+ ]);
25435
+ const lineRight = measure.findOne(`#lineRight-${nextProps.id}`);
25436
+ lineRight?.points([
25437
+ pointRightText.x,
25438
+ pointRightText.y,
25439
+ toPerp.left.x,
25440
+ toPerp.left.y
25441
+ ]);
25442
+ const pointMidMeasure = this.pointFromMid(fromPerp.left, toPerp.left, 0, false);
25443
+ const crosshairFrom = measure.findOne(`#crosshairFrom-${measure.getAttrs().id}`);
25444
+ if (crosshairFrom) {
25445
+ crosshairFrom.x(fromPoint.x);
25446
+ crosshairFrom.y(fromPoint.y);
25447
+ crosshairFrom.rotation(angle);
25448
+ }
25449
+ const crosshairTo = measure.findOne(`#crosshairTo-${measure.getAttrs().id}`);
25450
+ if (crosshairTo) {
25451
+ crosshairTo.x(toPoint.x);
25452
+ crosshairTo.y(toPoint.y);
25453
+ crosshairTo.rotation(angle);
25454
+ }
25455
+ const moveSeparationRect = measure.findOne(`#moveSeparationRect-${measure.getAttrs().id}`);
25456
+ if (moveSeparationRect) {
25457
+ const textSize$1 = measureText.measureSize(measureText.text());
25458
+ const isTextBiggerThanMeasureSpace = textSize$1.width > this.distanceBetweenPoints(fromPerp.left, toPerp.left);
25459
+ const separatorPoint = this.perpendicularPoint(fromPerp.left, toPerp.left, pointMidMeasure, (isTextBiggerThanMeasureSpace ? HANDLE_NO_SPACE_SEPARATION_MULTIPLIER : HANDLE_SPACE_SEPARATION_MULTIPLIER) * textSize$1.height * orientation);
25460
+ moveSeparationRect.x(separatorPoint.left.x);
25461
+ moveSeparationRect.y(separatorPoint.left.y);
25462
+ moveSeparationRect.rotation(angle);
25463
+ }
25464
+ }
25465
+ projectPointToLine(fromPoint, toPoint, pointToProject) {
25466
+ const dx = toPoint.x - fromPoint.x;
25467
+ const dy = toPoint.y - fromPoint.y;
25468
+ const lenSq = dx * dx + dy * dy;
25469
+ const t = ((pointToProject.x - fromPoint.x) * dx + (pointToProject.y - fromPoint.y) * dy) / lenSq;
25470
+ return {
25471
+ x: fromPoint.x + t * dx,
25472
+ y: fromPoint.y + t * dy,
25473
+ t,
25474
+ flipped: t < 0
25475
+ };
25476
+ }
25477
+ buildCrosshair(name, node, point, angle) {
25478
+ const props = node.getAttrs();
25479
+ const crosshairSize = 60;
25480
+ const crosshair = new Konva.Group({
25481
+ id: `${name}-${props.id}`,
25482
+ x: point.x,
25483
+ y: point.y,
25484
+ rotation: angle,
25485
+ visible: false,
25486
+ listening: false,
25487
+ draggable: false
25488
+ });
25489
+ const horizontalLineFrom = new Konva.Line({
25490
+ points: [
25491
+ 0,
25492
+ 0,
25493
+ crosshairSize,
25494
+ 0
25495
+ ],
25496
+ x: -1 * (crosshairSize / 2),
25497
+ y: 0,
25498
+ stroke: "#CC0000",
25499
+ strokeWidth: 1
25500
+ });
25501
+ const verticalLineFrom = new Konva.Line({
25502
+ points: [
25503
+ 0,
25504
+ 0,
25505
+ 0,
25506
+ crosshairSize
25507
+ ],
25508
+ x: 0,
25509
+ y: -1 * crosshairSize / 2,
25510
+ stroke: "#CC0000",
25511
+ strokeWidth: 1
25512
+ });
25513
+ crosshair.add(horizontalLineFrom);
25514
+ crosshair.add(verticalLineFrom);
25515
+ return crosshair;
25516
+ }
25517
+ movePointPerpendicularToLine(fromPoint, toPoint, point, distance) {
25518
+ const dx = toPoint.x - fromPoint.x;
25519
+ const dy = toPoint.y - fromPoint.y;
25520
+ const len = Math.hypot(dx, dy);
25521
+ const ux = -dy / len;
25522
+ const uy = dx / len;
25523
+ return {
25524
+ x: point.x + ux * distance,
25525
+ y: point.y + uy * distance
25526
+ };
25527
+ }
25528
+ getAngle(fromPoint, toPoint) {
25529
+ let angle = this.angleBetweenPoints(fromPoint, toPoint);
25530
+ if (fromPoint.x > toPoint.x) angle = angle + 180;
25531
+ return angle;
25532
+ }
25533
+ flipOrientation(node) {
25534
+ this.destroySelectionHandlers(node);
25535
+ const currentOrientation = node.getAttrs().orientation ?? -1;
25536
+ node.setAttrs({ orientation: currentOrientation * -1 });
25537
+ this.instance.updateNode(this.serialize(node));
25538
+ this.createSelectionHandlers(node);
25539
+ this.updateSelectionHandlers(node);
25540
+ }
25541
+ getNormalizedDistance(node) {
25542
+ const stage = this.instance.getStage();
25543
+ const scale = stage.scaleX();
25544
+ const fromCircle = node.findOne(`#fromCircle-${node.getAttrs().id}`);
25545
+ const toCircle = node.findOne(`#toCircle-${node.getAttrs().id}`);
25546
+ if (fromCircle && toCircle) {
25547
+ const fromPoint = fromCircle.getAbsolutePosition();
25548
+ const toPoint = toCircle.getAbsolutePosition();
25549
+ return Math.hypot(toPoint.x - fromPoint.x, toPoint.y - fromPoint.y) / scale;
25550
+ }
25551
+ return 0;
25552
+ }
25553
+ };
25554
+
24898
25555
  //#endregion
24899
25556
  //#region src/plugins/stage-zoom/constants.ts
24900
25557
  const WEAVE_STAGE_ZOOM_TYPE = {
@@ -28654,6 +29311,282 @@ var WeaveVideoToolAction = class extends WeaveAction {
28654
29311
  }
28655
29312
  };
28656
29313
 
29314
+ //#endregion
29315
+ //#region src/actions/measure-tool/constants.ts
29316
+ const MEASURE_TOOL_ACTION_NAME = "measureTool";
29317
+ const MEASURE_TOOL_STATE = {
29318
+ ["IDLE"]: "idle",
29319
+ ["SET_FROM"]: "set_from",
29320
+ ["SET_TO"]: "set_to",
29321
+ ["FINISHED"]: "finished"
29322
+ };
29323
+
29324
+ //#endregion
29325
+ //#region src/actions/measure-tool/measure-tool.ts
29326
+ var WeaveMeasureToolAction = class extends WeaveAction {
29327
+ initialized = false;
29328
+ initialCursor = null;
29329
+ color = "#FF3366";
29330
+ onPropsChange = void 0;
29331
+ onInit = void 0;
29332
+ constructor() {
29333
+ super();
29334
+ this.initialized = false;
29335
+ this.state = MEASURE_TOOL_STATE.IDLE;
29336
+ this.measureId = null;
29337
+ this.container = void 0;
29338
+ this.clickPoint = null;
29339
+ this.crosshairCursor = null;
29340
+ this.firstPoint = null;
29341
+ this.measureLine = null;
29342
+ this.measureContainer = void 0;
29343
+ this.props = this.initProps();
29344
+ }
29345
+ getName() {
29346
+ return MEASURE_TOOL_ACTION_NAME;
29347
+ }
29348
+ initProps() {
29349
+ return {
29350
+ orientation: -1,
29351
+ separation: 0,
29352
+ textPadding: 20,
29353
+ separationPadding: 0,
29354
+ unit: "cms",
29355
+ unitPerPixel: 10,
29356
+ color: this.color,
29357
+ strokeEnabled: false
29358
+ };
29359
+ }
29360
+ setupEvents() {
29361
+ const stage = this.instance.getStage();
29362
+ window.addEventListener("keydown", (e) => {
29363
+ if (e.code === "Escape" && this.instance.getActiveAction() === MEASURE_TOOL_ACTION_NAME) this.cancelAction();
29364
+ });
29365
+ stage.on("pointermove", () => {
29366
+ if (this.state === MEASURE_TOOL_STATE.IDLE) return;
29367
+ if (this.state === MEASURE_TOOL_STATE.SET_TO) {
29368
+ const finalPoint = this.defineFinalPoint();
29369
+ if (this.measureLine && this.firstPoint) this.measureLine.points([
29370
+ 0,
29371
+ 0,
29372
+ finalPoint.x,
29373
+ finalPoint.y
29374
+ ]);
29375
+ }
29376
+ this.setCursor();
29377
+ });
29378
+ stage.on("pointerclick", () => {
29379
+ if (this.state === MEASURE_TOOL_STATE.IDLE) return;
29380
+ if (this.state === MEASURE_TOOL_STATE.SET_FROM) {
29381
+ this.handleSetFrom();
29382
+ return;
29383
+ }
29384
+ if (this.state === MEASURE_TOOL_STATE.SET_TO) this.handleSetTo();
29385
+ });
29386
+ this.initialized = true;
29387
+ }
29388
+ setState(state) {
29389
+ this.state = state;
29390
+ }
29391
+ addMeasure() {
29392
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
29393
+ if (selectionPlugin) {
29394
+ const tr = selectionPlugin.getTransformer();
29395
+ tr.hide();
29396
+ }
29397
+ this.buildCrosshairCursor();
29398
+ this.setCursor();
29399
+ this.setFocusStage();
29400
+ this.clickPoint = null;
29401
+ this.setState(MEASURE_TOOL_STATE.SET_FROM);
29402
+ }
29403
+ buildCrosshairCursor() {
29404
+ const stage = this.instance.getStage();
29405
+ const { mousePoint } = this.instance.getMousePointer();
29406
+ this.crosshairCursor = new Konva.Group({
29407
+ x: mousePoint?.x,
29408
+ y: mousePoint?.y,
29409
+ scale: {
29410
+ x: 1 / stage.scaleX(),
29411
+ y: 1 / stage.scaleY()
29412
+ },
29413
+ listening: false,
29414
+ draggable: false
29415
+ });
29416
+ const crosshairSize = 60;
29417
+ const lineH = new Konva.Line({
29418
+ points: [
29419
+ 0,
29420
+ 0,
29421
+ crosshairSize,
29422
+ 0
29423
+ ],
29424
+ x: -1 * (crosshairSize / 2),
29425
+ y: 0,
29426
+ stroke: this.color,
29427
+ strokeWidth: 1
29428
+ });
29429
+ const lineV = new Konva.Line({
29430
+ points: [
29431
+ 0,
29432
+ 0,
29433
+ 0,
29434
+ crosshairSize
29435
+ ],
29436
+ x: 0,
29437
+ y: -1 * crosshairSize / 2,
29438
+ stroke: this.color,
29439
+ strokeWidth: 1
29440
+ });
29441
+ this.crosshairCursor.add(lineH);
29442
+ this.crosshairCursor.add(lineV);
29443
+ this.instance.getStage().on("pointermove.measureTool", () => {
29444
+ const pos = this.instance.getStage().getRelativePointerPosition();
29445
+ if (this.crosshairCursor && pos) {
29446
+ this.crosshairCursor.position(pos);
29447
+ this.crosshairCursor.moveToTop();
29448
+ }
29449
+ });
29450
+ this.instance.getUtilityLayer()?.add(this.crosshairCursor);
29451
+ }
29452
+ handleSetFrom() {
29453
+ const stage = this.instance.getStage();
29454
+ const realMousePoint = stage.getRelativePointerPosition();
29455
+ const { container, measureContainer } = this.instance.getMousePointer();
29456
+ this.clickPoint = realMousePoint;
29457
+ this.container = container;
29458
+ this.measureContainer = measureContainer;
29459
+ this.firstPoint = new Konva.Circle({
29460
+ x: this.clickPoint?.x ?? 0,
29461
+ y: this.clickPoint?.y ?? 0,
29462
+ radius: 6,
29463
+ fill: "#FFFFFF",
29464
+ stroke: "#000000",
29465
+ scale: {
29466
+ x: 1 / stage.scaleX(),
29467
+ y: 1 / stage.scaleY()
29468
+ },
29469
+ strokeWidth: 1,
29470
+ listening: false,
29471
+ draggable: false
29472
+ });
29473
+ this.measureLine = new Konva.Line({
29474
+ x: this.clickPoint?.x,
29475
+ y: this.clickPoint?.y,
29476
+ points: [0, 0],
29477
+ scale: {
29478
+ x: 1 / stage.scaleX(),
29479
+ y: 1 / stage.scaleY()
29480
+ },
29481
+ stroke: this.color,
29482
+ dashed: [4, 4],
29483
+ strokeWidth: 1,
29484
+ listening: false,
29485
+ draggable: false
29486
+ });
29487
+ this.instance.getUtilityLayer()?.add(this.firstPoint);
29488
+ this.instance.getUtilityLayer()?.add(this.measureLine);
29489
+ this.firstPoint.moveToTop();
29490
+ this.measureLine.moveToBottom();
29491
+ this.setState(MEASURE_TOOL_STATE.SET_TO);
29492
+ }
29493
+ handleSetTo() {
29494
+ const stage = this.instance.getStage();
29495
+ const realMousePoint = stage.getRelativePointerPosition();
29496
+ const { container } = this.instance.getMousePointer();
29497
+ this.clickPoint = realMousePoint;
29498
+ this.container = container;
29499
+ const nodeHandler = this.instance.getNodeHandler("measure");
29500
+ if (nodeHandler && this.firstPoint) {
29501
+ this.measureId = v4_default();
29502
+ const node = nodeHandler.create(this.measureId, {
29503
+ ...this.props,
29504
+ id: this.measureId,
29505
+ x: 0,
29506
+ y: 0,
29507
+ fromPoint: {
29508
+ x: this.firstPoint.x(),
29509
+ y: this.firstPoint.y()
29510
+ },
29511
+ toPoint: {
29512
+ x: this.clickPoint?.x ?? 0,
29513
+ y: this.clickPoint?.y ?? 0
29514
+ },
29515
+ draggable: true
29516
+ });
29517
+ this.instance.addOnceEventListener("onNodeRenderedAdded", (child) => {
29518
+ if (child.getAttrs().id === this.measureId) {
29519
+ if (typeof this.measureContainer !== "undefined" && this.measureContainer?.id() !== "mainLayer") {
29520
+ const nodeInstance = this.instance.getMainLayer()?.findOne(`#${this.measureId}`);
29521
+ const stage$1 = this.instance.getStage();
29522
+ let realContainer = this.measureContainer;
29523
+ if (realContainer?.getAttrs().nodeId !== void 0) realContainer = stage$1.findOne(`#${realContainer?.getAttrs().nodeId}`);
29524
+ if (nodeInstance) moveNodeToContainer(this.instance, nodeInstance, realContainer);
29525
+ }
29526
+ this.cancelAction();
29527
+ }
29528
+ });
29529
+ this.instance.addNode(node, "mainLayer");
29530
+ this.setState(MEASURE_TOOL_STATE.FINISHED);
29531
+ }
29532
+ }
29533
+ trigger(cancelAction) {
29534
+ if (!this.instance) throw new Error("Instance not defined");
29535
+ if (!this.initialized) this.setupEvents();
29536
+ this.cancelAction = cancelAction;
29537
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
29538
+ if (selectionPlugin) selectionPlugin.setSelectedNodes([]);
29539
+ this.props = this.initProps();
29540
+ this.addMeasure();
29541
+ }
29542
+ cleanup() {
29543
+ const stage = this.instance.getStage();
29544
+ stage.container().style.cursor = "default";
29545
+ this.instance.getStage().off("pointermove.measureTool");
29546
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
29547
+ if (selectionPlugin) {
29548
+ const node = stage.findOne(`#${this.measureId}`);
29549
+ if (node) selectionPlugin.setSelectedNodes([node]);
29550
+ this.instance.triggerAction(SELECTION_TOOL_ACTION_NAME);
29551
+ }
29552
+ if (this.crosshairCursor) this.crosshairCursor.destroy();
29553
+ if (this.firstPoint) this.firstPoint.destroy();
29554
+ if (this.measureLine) this.measureLine.destroy();
29555
+ this.initialCursor = null;
29556
+ this.measureId = null;
29557
+ this.container = void 0;
29558
+ this.clickPoint = null;
29559
+ this.firstPoint = null;
29560
+ this.measureLine = null;
29561
+ this.setState(MEASURE_TOOL_STATE.IDLE);
29562
+ }
29563
+ setCursor() {
29564
+ const stage = this.instance.getStage();
29565
+ stage.container().style.cursor = "none";
29566
+ }
29567
+ setFocusStage() {
29568
+ const stage = this.instance.getStage();
29569
+ stage.container().tabIndex = 1;
29570
+ stage.container().blur();
29571
+ stage.container().focus();
29572
+ }
29573
+ defineFinalPoint() {
29574
+ if (!this.measureLine || !this.measureContainer) return {
29575
+ x: 0,
29576
+ y: 0
29577
+ };
29578
+ const stage = this.instance.getStage();
29579
+ const realMousePoint = this.instance.getStage().getRelativePointerPosition();
29580
+ const pos = {
29581
+ x: 0,
29582
+ y: 0
29583
+ };
29584
+ pos.x = ((realMousePoint?.x ?? 0) - this.measureLine.x()) * stage.scaleX();
29585
+ pos.y = ((realMousePoint?.y ?? 0) - this.measureLine.y()) * stage.scaleY();
29586
+ return pos;
29587
+ }
29588
+ };
29589
+
28657
29590
  //#endregion
28658
29591
  //#region src/plugins/stage-grid/stage-grid.ts
28659
29592
  var WeaveStageGridPlugin = class extends WeavePlugin {
@@ -29369,6 +30302,11 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
29369
30302
  const containerParent = stage.container().parentNode;
29370
30303
  if (!this.enabled) return;
29371
30304
  if (containerParent) {
30305
+ const upscaleScale = stage.getAttr("upscaleScale");
30306
+ if (upscaleScale === 1) {
30307
+ stage.width(containerParent.clientWidth);
30308
+ stage.height(containerParent.clientHeight);
30309
+ }
29372
30310
  setupUpscaleStage(this.instance, stage);
29373
30311
  const plugins = this.instance.getPlugins();
29374
30312
  for (const pluginId of Object.keys(plugins)) {
@@ -29378,11 +30316,14 @@ var WeaveStageResizePlugin = class extends WeavePlugin {
29378
30316
  }
29379
30317
  }
29380
30318
  onInit() {
29381
- window.addEventListener("resize", () => {
30319
+ const throttledResize = (0, import_lodash.throttle)(() => {
29382
30320
  this.resizeStage();
30321
+ }, 100);
30322
+ window.addEventListener("resize", () => {
30323
+ throttledResize();
29383
30324
  });
29384
30325
  const resizeObserver = new ResizeObserver(() => {
29385
- this.resizeStage();
30326
+ throttledResize();
29386
30327
  });
29387
30328
  const stage = this.instance.getStage();
29388
30329
  resizeObserver.observe(stage.container());
@@ -30034,7 +30975,9 @@ var WeaveNodesEdgeSnappingPlugin = class extends WeavePlugin {
30034
30975
  const utilityLayer = this.instance.getUtilityLayer();
30035
30976
  if (!this.enabled) return;
30036
30977
  if (!utilityLayer) return;
30978
+ if (e.target.getAttr("edgeSnappingDisableOnDrag")) return;
30037
30979
  const { targetNode: node, skipNodes } = getTargetAndSkipNodes(this.instance, e);
30980
+ if (node?.getAttr("edgeSnappingDisable")) return;
30038
30981
  if (typeof node === "undefined") return;
30039
30982
  const nodeParent = this.getSelectionParentNode(node);
30040
30983
  if (nodeParent === null) return;
@@ -32136,7 +33079,7 @@ var WeaveRegisterManager = class {
32136
33079
 
32137
33080
  //#endregion
32138
33081
  //#region package.json
32139
- var version = "2.10.0";
33082
+ var version = "2.11.0";
32140
33083
 
32141
33084
  //#endregion
32142
33085
  //#region src/managers/setup.ts
@@ -32793,6 +33736,10 @@ var Weave = class {
32793
33736
  this.moduleLogger.debug(`Listening event [${event}]`);
32794
33737
  this.emitter.on(event, callback);
32795
33738
  }
33739
+ addOnceEventListener(event, callback) {
33740
+ this.moduleLogger.debug(`Listening once event [${event}]`);
33741
+ this.emitter.once(event).then(callback);
33742
+ }
32796
33743
  removeEventListener(event, callback) {
32797
33744
  this.moduleLogger.debug(`Removing listening to event [${event}]`);
32798
33745
  this.emitter.off(event, callback);
@@ -33519,5 +34466,5 @@ var WeaveLineToolAction = class extends WeaveAction {
33519
34466
  };
33520
34467
 
33521
34468
  //#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 };
34469
+ 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_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, 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
34470
  //# sourceMappingURL=sdk.js.map