@inditextech/weave-sdk 0.20.1 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk.cjs CHANGED
@@ -16462,6 +16462,7 @@ const setNodesDefaultConfiguration = (config) => {
16462
16462
  };
16463
16463
  };
16464
16464
  konva.default.Node.prototype.updatePosition = function() {};
16465
+ konva.default.Node.prototype.resetCrop = function() {};
16465
16466
  };
16466
16467
  var WeaveNode = class {
16467
16468
  register(instance) {
@@ -16509,6 +16510,10 @@ var WeaveNode = class {
16509
16510
  }
16510
16511
  node.width(Math.max(5, node.width() * node.scaleX()));
16511
16512
  node.height(Math.max(5, node.height() * node.scaleY()));
16513
+ if (node.getAttrs().nodeType === "image") node.setAttrs({ uncroppedImage: {
16514
+ width: node.getAttrs().uncroppedImage.width * node.scaleX(),
16515
+ height: node.getAttrs().uncroppedImage.height * node.scaleY()
16516
+ } });
16512
16517
  node.scaleX(1);
16513
16518
  node.scaleY(1);
16514
16519
  }
@@ -16523,7 +16528,9 @@ var WeaveNode = class {
16523
16528
  });
16524
16529
  node.on("transform", (e) => {
16525
16530
  const node$1 = e.target;
16531
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
16526
16532
  const nodesSnappingPlugin = this.instance.getPlugin("nodesSnapping");
16533
+ if (nodesSelectionPlugin && this.isSelecting() && this.isNodeSelected(node$1)) nodesSelectionPlugin.getTransformer().forceUpdate();
16527
16534
  if (nodesSnappingPlugin && this.isSelecting() && this.isNodeSelected(node$1)) nodesSnappingPlugin.evaluateGuidelines(e);
16528
16535
  if (this.isSelecting() && this.isNodeSelected(node$1)) {
16529
16536
  this.scaleReset(node$1);
@@ -16534,8 +16541,10 @@ var WeaveNode = class {
16534
16541
  });
16535
16542
  node.on("transformend", (e) => {
16536
16543
  const node$1 = e.target;
16544
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
16537
16545
  const nodesSnappingPlugin = this.instance.getPlugin("nodesSnapping");
16538
16546
  if (nodesSnappingPlugin && this.isSelecting() && this.isNodeSelected(node$1)) nodesSnappingPlugin.cleanupEvaluateGuidelines();
16547
+ if (nodesSelectionPlugin && this.isSelecting() && this.isNodeSelected(node$1)) nodesSelectionPlugin.getTransformer().forceUpdate();
16539
16548
  });
16540
16549
  node.on("dragmove", (e) => {
16541
16550
  if (this.isSelecting() && this.isNodeSelected(node)) {
@@ -16548,6 +16557,8 @@ var WeaveNode = class {
16548
16557
  node.on("dragend", (e) => {
16549
16558
  if (this.isSelecting() && this.isNodeSelected(node)) {
16550
16559
  clearContainerTargets(this.instance);
16560
+ const nodesSnappingPlugin = this.instance.getPlugin("nodesSnapping");
16561
+ if (nodesSnappingPlugin && this.isSelecting() && this.isNodeSelected(node)) nodesSnappingPlugin.cleanupEvaluateGuidelines();
16551
16562
  const containerToMove = moveNodeToContainer(this.instance, e.target);
16552
16563
  if (containerToMove) return;
16553
16564
  this.instance.updateNode(this.serialize(node));
@@ -18024,7 +18035,7 @@ var WeaveRegisterManager = class {
18024
18035
 
18025
18036
  //#endregion
18026
18037
  //#region package.json
18027
- var version = "0.20.1";
18038
+ var version = "0.20.2";
18028
18039
 
18029
18040
  //#endregion
18030
18041
  //#region src/managers/setup.ts
@@ -18760,6 +18771,8 @@ var WeaveGroupNode = class extends WeaveNode {
18760
18771
  }
18761
18772
  onUpdate(nodeInstance, nextProps) {
18762
18773
  nodeInstance.setAttrs({ ...nextProps });
18774
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
18775
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
18763
18776
  }
18764
18777
  serialize(instance) {
18765
18778
  const attrs = instance.getAttrs();
@@ -18811,6 +18824,8 @@ var WeaveRectangleNode = class extends WeaveNode {
18811
18824
  }
18812
18825
  onUpdate(nodeInstance, nextProps) {
18813
18826
  nodeInstance.setAttrs({ ...nextProps });
18827
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
18828
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
18814
18829
  }
18815
18830
  };
18816
18831
 
@@ -18843,6 +18858,8 @@ var WeaveLineNode = class extends WeaveNode {
18843
18858
  }
18844
18859
  onUpdate(nodeInstance, nextProps) {
18845
18860
  nodeInstance.setAttrs({ ...nextProps });
18861
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
18862
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
18846
18863
  }
18847
18864
  };
18848
18865
 
@@ -19378,6 +19395,7 @@ var WeaveImageToolAction = class extends WeaveAction {
19378
19395
  width: 100 * aspectRatio,
19379
19396
  height: 100,
19380
19397
  opacity: 1,
19398
+ adding: true,
19381
19399
  imageURL: this.imageURL,
19382
19400
  stroke: "#000000ff",
19383
19401
  strokeWidth: 0,
@@ -19404,18 +19422,21 @@ var WeaveImageToolAction = class extends WeaveAction {
19404
19422
  x: this.clickPoint?.x ?? 0,
19405
19423
  y: this.clickPoint?.y ?? 0,
19406
19424
  opacity: 1,
19425
+ adding: false,
19407
19426
  imageURL: this.imageURL,
19408
19427
  stroke: "#000000ff",
19409
19428
  strokeWidth: 0,
19410
19429
  strokeScaleEnabled: false,
19430
+ imageWidth: this.preloadImgs[this.imageId].width,
19431
+ imageHeight: this.preloadImgs[this.imageId].height,
19411
19432
  imageInfo: {
19412
19433
  width: this.preloadImgs[this.imageId].width,
19413
19434
  height: this.preloadImgs[this.imageId].height
19414
19435
  }
19415
19436
  });
19416
19437
  this.instance.addNode(node, this.container?.getAttrs().id);
19417
- const rectangleNodeHandler = this.instance.getNodeHandler("rectangle");
19418
- this.instance.removeNode(rectangleNodeHandler.serialize(tempImage));
19438
+ const imageNodeHandler = this.instance.getNodeHandler("image");
19439
+ this.instance.removeNode(imageNodeHandler.serialize(tempImage));
19419
19440
  this.setState(IMAGE_TOOL_STATE.FINISHED);
19420
19441
  }
19421
19442
  this.cancelAction();
@@ -19459,20 +19480,17 @@ var WeaveImageToolAction = class extends WeaveAction {
19459
19480
  };
19460
19481
 
19461
19482
  //#endregion
19462
- //#region src/nodes/image/clip.ts
19463
- var WeaveImageClip = class {
19483
+ //#region src/nodes/image/crop.ts
19484
+ var WeaveImageCrop = class WeaveImageCrop {
19464
19485
  constructor(instance, node, image, internalImage, clipGroup) {
19465
19486
  this.instance = instance;
19466
19487
  this.node = node;
19467
19488
  this.image = image;
19468
19489
  this.internalImage = internalImage;
19469
- this.clipGroup = clipGroup;
19490
+ this.cropGroup = clipGroup;
19470
19491
  this.handleHide = this.hide.bind(this);
19471
- this.handleCrop = this.handleClipTransform.bind(this);
19472
- this.handleDrag = this.handleClipDrag.bind(this);
19473
19492
  }
19474
19493
  show() {
19475
- const originalImage = this.internalImage.getAttr("image");
19476
19494
  const nodeSnappingPlugin = this.instance.getPlugin("nodesSnapping");
19477
19495
  if (nodeSnappingPlugin) this.instance.disablePlugin("nodesSnapping");
19478
19496
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
@@ -19481,74 +19499,153 @@ var WeaveImageClip = class {
19481
19499
  selectionPlugin.getTransformer().nodes([]);
19482
19500
  selectionPlugin.getTransformer().hide();
19483
19501
  }
19484
- const ratio = this.internalImage.cropWidth() === 0 ? this.image.width() / this.image.width() : this.image.width() / this.internalImage.cropWidth();
19485
- const originWidth = ratio * originalImage.width;
19486
- const originHeight = ratio * originalImage.height;
19487
- const cropX = this.internalImage.cropX() * ratio;
19488
- const cropY = this.internalImage.cropY() * ratio;
19502
+ this.image.setAttrs({ cropping: true });
19503
+ const imageAttrs = this.image.getAttrs();
19489
19504
  this.internalImage.hide();
19490
- const clipImage = this.internalImage.clone({
19491
- width: originWidth,
19492
- height: originHeight,
19493
- cropX: 0,
19494
- cropY: 0,
19495
- cropWidth: 0,
19496
- cropHeight: 0,
19505
+ this.cropGroup.destroyChildren();
19506
+ const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
19507
+ const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
19508
+ const realScale = actualScale / cropScale;
19509
+ this.cropImage = new konva.default.Image({
19510
+ x: imageAttrs.cropInfo ? -imageAttrs.cropInfo.x * realScale : 0,
19511
+ y: imageAttrs.cropInfo ? -imageAttrs.cropInfo.y * realScale : 0,
19512
+ width: imageAttrs.uncroppedImage.width,
19513
+ height: imageAttrs.uncroppedImage.height,
19514
+ scaleX: 1,
19515
+ scaleY: 1,
19516
+ image: this.internalImage.image(),
19517
+ crop: void 0,
19497
19518
  visible: true,
19498
- draggable: false,
19499
- rotation: 0
19519
+ listening: false,
19520
+ draggable: false
19500
19521
  });
19501
- this.clipRect = new konva.default.Rect({
19502
- width: this.internalImage.width(),
19503
- height: this.internalImage.height(),
19504
- fill: "rgba(0,0,0,0.5)",
19522
+ this.imageOffsetX = imageAttrs.cropInfo ? imageAttrs.cropInfo.x * realScale : 0;
19523
+ this.imageOffsetY = imageAttrs.cropInfo ? imageAttrs.cropInfo.y * realScale : 0;
19524
+ this.cropRect = new konva.default.Rect({
19505
19525
  x: 0,
19506
19526
  y: 0,
19527
+ width: imageAttrs.cropInfo ? imageAttrs.cropInfo.width * realScale : imageAttrs.uncroppedImage.width,
19528
+ height: imageAttrs.cropInfo ? imageAttrs.cropInfo.height * realScale : imageAttrs.uncroppedImage.height,
19529
+ fill: "rgba(0,0,0,0.2)",
19530
+ stroke: "#ff0000ff",
19531
+ strokeWidth: 0,
19532
+ strokeScaleEnabled: false,
19507
19533
  draggable: true,
19508
19534
  rotation: 0
19509
19535
  });
19510
19536
  this.transformer = new konva.default.Transformer({
19537
+ id: `${this.image.getAttrs().id}_transformer`,
19538
+ x: 0,
19539
+ y: 0,
19511
19540
  flipEnabled: false,
19512
19541
  keepRatio: false,
19542
+ ignoreStroke: false,
19513
19543
  rotateEnabled: false,
19514
19544
  enabledAnchors: [
19515
19545
  "top-left",
19546
+ "top-center",
19516
19547
  "top-right",
19548
+ "middle-right",
19517
19549
  "bottom-left",
19518
- "bottom-right"
19550
+ "middle-left",
19551
+ "bottom-right",
19552
+ "bottom-center"
19519
19553
  ],
19554
+ anchorDragBoundFunc: (_, newPos) => {
19555
+ let closestSnap = newPos;
19556
+ let minDist = 10;
19557
+ const nodeRotation = this.image.getAbsoluteRotation();
19558
+ const stage = this.instance.getStage();
19559
+ const rotation = nodeRotation * (Math.PI / 180);
19560
+ const center = this.cropImage.getAbsolutePosition();
19561
+ const width = this.cropImage.width() * stage.scaleX();
19562
+ const height = this.cropImage.height() * stage.scaleY();
19563
+ const offset = this.cropImage.offset();
19564
+ const corners = [
19565
+ {
19566
+ x: -offset.x,
19567
+ y: -offset.y
19568
+ },
19569
+ {
19570
+ x: width - offset.x,
19571
+ y: -offset.y
19572
+ },
19573
+ {
19574
+ x: width - offset.x,
19575
+ y: height - offset.y
19576
+ },
19577
+ {
19578
+ x: -offset.x,
19579
+ y: height - offset.y
19580
+ }
19581
+ ].map((pt) => {
19582
+ const cos = Math.cos(rotation);
19583
+ const sin = Math.sin(rotation);
19584
+ return {
19585
+ x: center.x + pt.x * cos - pt.y * sin,
19586
+ y: center.y + pt.x * sin + pt.y * cos
19587
+ };
19588
+ });
19589
+ const edges = [
19590
+ [corners[0], corners[1]],
19591
+ [corners[1], corners[2]],
19592
+ [corners[2], corners[3]],
19593
+ [corners[3], corners[0]]
19594
+ ];
19595
+ for (const [a, b] of edges) {
19596
+ const candidate = this.closestPointOnLine(newPos, a, b);
19597
+ const dist = Math.hypot(newPos.x - candidate.x, newPos.y - candidate.y);
19598
+ if (dist < minDist) {
19599
+ closestSnap = candidate;
19600
+ minDist = dist;
19601
+ }
19602
+ }
19603
+ return closestSnap;
19604
+ },
19520
19605
  rotation: 0
19521
19606
  });
19522
19607
  this.grid = new konva.default.Group();
19523
- this.transformer.on("dragmove", this.handleDrag);
19524
- this.transformer.on("transform", this.handleCrop);
19525
- this.transformer.nodes([this.clipRect]);
19526
- this.clipGroup.add(clipImage);
19527
- this.clipGroup.add(this.clipRect);
19528
- this.clipGroup.add(this.grid);
19529
- this.clipGroup.add(this.transformer);
19530
- this.clipGroup.setPosition({
19531
- x: -cropX,
19532
- y: -cropY
19608
+ const cropRect = this.cropRect.getClientRect({
19609
+ relativeTo: this.cropGroup,
19610
+ skipStroke: true
19611
+ });
19612
+ this.drawGridLines(0, 0, cropRect.width, cropRect.height);
19613
+ this.cropRect.on("dragmove", () => {
19614
+ const cropRect$1 = this.cropRect.getClientRect({
19615
+ relativeTo: this.cropGroup,
19616
+ skipStroke: true
19617
+ });
19618
+ this.drawGridLines(cropRect$1.x, cropRect$1.y, cropRect$1.width, cropRect$1.height);
19533
19619
  });
19534
- this.clipRect.position({
19535
- x: cropX,
19536
- y: cropY
19620
+ this.cropRect.on("transform", () => {
19621
+ const cropRect$1 = this.cropRect.getClientRect({
19622
+ relativeTo: this.cropGroup,
19623
+ skipStroke: true
19624
+ });
19625
+ this.drawGridLines(cropRect$1.x, cropRect$1.y, cropRect$1.width, cropRect$1.height);
19537
19626
  });
19538
- this.handleClipTransform();
19539
- this.clipGroup.show();
19627
+ this.transformer.nodes([this.cropRect]);
19628
+ this.cropGroup.add(this.cropImage);
19629
+ this.cropGroup.add(this.cropRect);
19630
+ this.cropGroup.add(this.grid);
19631
+ const utilityLayer = this.instance.getUtilityLayer();
19632
+ utilityLayer?.add(this.transformer);
19633
+ this.transformer.forceUpdate();
19634
+ this.cropGroup.show();
19540
19635
  this.instance.getStage().container().addEventListener("keydown", this.handleHide);
19541
19636
  }
19542
- hide() {
19543
- this.handleClipEnd();
19544
- this.node.cropping = false;
19637
+ hide(e) {
19638
+ if (!["Enter", "Escape"].includes(e.key)) return;
19639
+ this.image.setAttrs({ cropping: false });
19640
+ if (e.key === "Enter") this.handleClipEnd();
19641
+ const utilityLayer = this.instance.getUtilityLayer();
19642
+ utilityLayer?.destroyChildren();
19545
19643
  this.instance.getStage().container().removeEventListener("keydown", this.handleHide);
19546
- this.transformer.off("dragmove", this.handleDrag);
19547
- this.transformer.off("transform", this.handleCrop);
19548
- this.clipGroup.destroyChildren();
19549
- this.clipGroup.hide();
19644
+ this.cropGroup.destroyChildren();
19645
+ this.cropGroup.hide();
19550
19646
  const nodeSnappingPlugin = this.instance.getPlugin("nodesSnapping");
19551
19647
  if (nodeSnappingPlugin) this.instance.enablePlugin("nodesSnapping");
19648
+ this.internalImage.show();
19552
19649
  const selectionPlugin = this.instance.getPlugin("nodesSelection");
19553
19650
  if (selectionPlugin) {
19554
19651
  this.instance.enablePlugin("nodesSelection");
@@ -19556,126 +19653,145 @@ var WeaveImageClip = class {
19556
19653
  selectionTransformer.nodes([this.image]);
19557
19654
  selectionTransformer.show();
19558
19655
  setTimeout(() => {
19656
+ selectionPlugin.triggerSelectedNodesEvent();
19559
19657
  selectionTransformer.forceUpdate();
19560
19658
  }, 0);
19561
19659
  }
19562
- this.internalImage.show();
19563
- }
19564
- handleClipTransform() {
19565
- if (!this.node.cropping) return;
19566
- const originalImage = this.internalImage.getAttr("image");
19567
- let x = this.clipRect.x();
19568
- let y = this.clipRect.y();
19569
- let width = this.clipRect.width() * this.clipRect.scaleX();
19570
- let height = this.clipRect.height() * this.clipRect.scaleY();
19571
- if (x < 0) {
19572
- width += x;
19573
- x = 0;
19574
- }
19575
- if (x + width > originalImage.width) width = originalImage.width - x;
19576
- if (y < 0) {
19577
- height += y;
19578
- y = 0;
19579
- }
19580
- if (y + height > originalImage.height) height = originalImage.height - y;
19581
- this.clipRect.setAttrs({
19582
- x,
19583
- y,
19584
- width,
19585
- height,
19586
- scaleX: 1,
19587
- scaleY: 1
19588
- });
19589
- this.transformer.absolutePosition(this.clipRect.absolutePosition());
19590
- this.grid.position({
19591
- x,
19592
- y
19593
- });
19594
- this.drawGridLines(width, height);
19595
- }
19596
- handleClipDrag() {
19597
- if (!this.node.cropping) return;
19598
- const originalImage = this.internalImage.getAttr("image");
19599
- let x = this.clipRect.x();
19600
- let y = this.clipRect.y();
19601
- let width = this.clipRect.width();
19602
- let height = this.clipRect.height();
19603
- const originWidth = originalImage.width;
19604
- const originHeight = originalImage.height;
19605
- if (x < 0) x = 0;
19606
- if (x + width > originWidth) {
19607
- x = originWidth - width;
19608
- width = originWidth - x;
19609
- }
19610
- if (y < 0) y = 0;
19611
- if (y + height > originHeight) {
19612
- y = originHeight - height;
19613
- height = originHeight - y;
19614
- }
19615
- this.clipRect.setAttrs({
19616
- x,
19617
- y,
19618
- width,
19619
- height
19620
- });
19621
- this.grid.position({
19622
- x,
19623
- y
19624
- });
19625
- this.drawGridLines(width, height);
19626
19660
  }
19627
- drawGridLines(width, height) {
19628
- if (!this.node.cropping) return;
19661
+ drawGridLines(x, y, width, height) {
19662
+ if (!this.image.getAttrs().cropping) return;
19629
19663
  this.grid.destroyChildren();
19630
19664
  const stepX = width / 3;
19631
19665
  const stepY = height / 3;
19632
19666
  for (let i = 1; i <= 2; i++) {
19633
19667
  const vLine = new konva.default.Line({
19634
19668
  points: [
19635
- stepX * i,
19636
- 0,
19637
- stepX * i,
19638
- height
19669
+ x + stepX * i,
19670
+ y,
19671
+ x + stepX * i,
19672
+ y + height
19639
19673
  ],
19640
- stroke: "#ffffff",
19641
- strokeWidth: 1
19674
+ stroke: "#0074ffcc",
19675
+ strokeWidth: 1,
19676
+ strokeScaleEnabled: false
19642
19677
  });
19643
19678
  const hLine = new konva.default.Line({
19644
19679
  points: [
19645
- 0,
19646
- stepY * i,
19647
- width,
19648
- stepY * i
19680
+ x,
19681
+ y + stepY * i,
19682
+ x + width,
19683
+ y + stepY * i
19649
19684
  ],
19650
- stroke: "#ffffff",
19651
- strokeWidth: 1
19685
+ stroke: "#0074ffcc",
19686
+ strokeWidth: 1,
19687
+ strokeScaleEnabled: false
19652
19688
  });
19653
19689
  this.grid.add(vLine, hLine);
19654
19690
  }
19655
19691
  }
19692
+ unCrop() {
19693
+ const imageAttrs = this.image.getAttrs();
19694
+ this.cropGroup.destroyChildren();
19695
+ const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
19696
+ const cropScale = imageAttrs.cropInfo ? imageAttrs.cropInfo.scaleX : actualScale;
19697
+ const realScale = actualScale / cropScale;
19698
+ this.cropImage = new konva.default.Image({
19699
+ x: imageAttrs.cropInfo ? -imageAttrs.cropInfo.x * realScale : 0,
19700
+ y: imageAttrs.cropInfo ? -imageAttrs.cropInfo.y * realScale : 0,
19701
+ width: imageAttrs.uncroppedImage.width,
19702
+ height: imageAttrs.uncroppedImage.height,
19703
+ scaleX: 1,
19704
+ scaleY: 1,
19705
+ image: this.internalImage.image(),
19706
+ crop: void 0,
19707
+ visible: false,
19708
+ listening: false,
19709
+ draggable: false
19710
+ });
19711
+ this.cropGroup.add(this.cropImage);
19712
+ const cropImageStage = this.cropImage.getAbsolutePosition();
19713
+ this.image.setAttrs({
19714
+ width: imageAttrs.uncroppedImage.width,
19715
+ height: imageAttrs.uncroppedImage.height
19716
+ });
19717
+ this.image.setAbsolutePosition(cropImageStage);
19718
+ this.image.attrs.cropInfo = void 0;
19719
+ this.instance.updateNode(this.node.serialize(this.image));
19720
+ }
19656
19721
  handleClipEnd() {
19657
- if (!this.node.cropping) return;
19658
- const cropX = this.clipRect.x();
19659
- const cropY = this.clipRect.y();
19660
- const width = this.clipRect.width();
19661
- const height = this.clipRect.height();
19662
- if (this.image) {
19722
+ const clipRect = this.cropRect.getClientRect({ relativeTo: this.cropGroup });
19723
+ const originalRotation = this.image.getAbsoluteRotation();
19724
+ this.cropImage.rotation(-originalRotation);
19725
+ this.cropRect.rotation(-originalRotation);
19726
+ const intersectionRect = this.getIntersectionRect(this.cropImage, this.cropRect);
19727
+ this.cropImage.rotation(0);
19728
+ this.cropRect.rotation(0);
19729
+ const clipRectGroup = this.cropRect.getClientRect({ relativeTo: this.cropGroup });
19730
+ if (!intersectionRect) return;
19731
+ const imageAttrs = this.internalImage.getAttrs();
19732
+ const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
19733
+ const realClipRect = {
19734
+ scaleX: actualScale,
19735
+ scaleY: actualScale,
19736
+ x: WeaveImageCrop.roundTo6Decimals(clipRectGroup.x + this.imageOffsetX),
19737
+ y: WeaveImageCrop.roundTo6Decimals(clipRectGroup.y + this.imageOffsetY),
19738
+ width: WeaveImageCrop.roundTo6Decimals(clipRectGroup.width),
19739
+ height: WeaveImageCrop.roundTo6Decimals(clipRectGroup.height)
19740
+ };
19741
+ if (this.image && clipRect) {
19742
+ const clipRectStage = this.cropRect.getAbsolutePosition();
19743
+ const clipRectGroup$1 = this.cropRect.getClientRect({ relativeTo: this.cropGroup });
19663
19744
  this.image.setAttrs({
19664
- width,
19665
- height,
19666
- cropX,
19667
- cropY,
19668
- cropWidth: width,
19669
- cropHeight: height
19670
- });
19671
- const clipRectPos = this.clipRect.getAbsolutePosition();
19672
- this.image.setPosition({
19673
- x: clipRectPos.x,
19674
- y: clipRectPos.y
19745
+ width: clipRectGroup$1.width,
19746
+ height: clipRectGroup$1.height,
19747
+ cropInfo: realClipRect,
19748
+ cropSize: clipRectGroup$1,
19749
+ uncroppedImage: {
19750
+ width: imageAttrs.uncroppedImage.width,
19751
+ height: imageAttrs.uncroppedImage.height
19752
+ }
19675
19753
  });
19754
+ this.image.setAbsolutePosition(clipRectStage);
19676
19755
  this.instance.updateNode(this.node.serialize(this.image));
19677
19756
  }
19678
19757
  }
19758
+ static roundTo6Decimals(value) {
19759
+ return parseFloat(value.toFixed(6));
19760
+ }
19761
+ getIntersectionRect(a, b) {
19762
+ const rectA = a.getClientRect({ skipStroke: true });
19763
+ const rectB = b.getClientRect({ skipStroke: true });
19764
+ const x1 = WeaveImageCrop.roundTo6Decimals(Math.max(rectA.x, rectB.x));
19765
+ const y1 = WeaveImageCrop.roundTo6Decimals(Math.max(rectA.y, rectB.y));
19766
+ const x2 = WeaveImageCrop.roundTo6Decimals(Math.min(rectA.x + rectA.width, rectB.x + rectB.width));
19767
+ const y2 = WeaveImageCrop.roundTo6Decimals(Math.min(rectA.y + rectA.height, rectB.y + rectB.height));
19768
+ const width = WeaveImageCrop.roundTo6Decimals(x2 - x1);
19769
+ const height = WeaveImageCrop.roundTo6Decimals(y2 - y1);
19770
+ if (width <= 0 || height <= 0) return null;
19771
+ return {
19772
+ x: x1,
19773
+ y: y1,
19774
+ width,
19775
+ height
19776
+ };
19777
+ }
19778
+ closestPointOnLine(p, a, b) {
19779
+ const ab = {
19780
+ x: b.x - a.x,
19781
+ y: b.y - a.y
19782
+ };
19783
+ const abLengthSquared = ab.x ** 2 + ab.y ** 2;
19784
+ if (abLengthSquared === 0) return a;
19785
+ const ap = {
19786
+ x: p.x - a.x,
19787
+ y: p.y - a.y
19788
+ };
19789
+ const t = Math.max(0, Math.min(1, (ap.x * ab.x + ap.y * ab.y) / abLengthSquared));
19790
+ return {
19791
+ x: a.x + t * ab.x,
19792
+ y: a.y + t * ab.y
19793
+ };
19794
+ }
19679
19795
  };
19680
19796
 
19681
19797
  //#endregion
@@ -19693,8 +19809,8 @@ var WeaveImageNode = class extends WeaveNode {
19693
19809
  ...__inditextech_weave_types.WEAVE_DEFAULT_TRANSFORM_PROPERTIES,
19694
19810
  ...config?.transform
19695
19811
  } };
19812
+ this.cachedCropInfo = {};
19696
19813
  this.imageLoaded = false;
19697
- this.cropping = false;
19698
19814
  }
19699
19815
  onRender(props) {
19700
19816
  const imageProperties = props.imageProperties;
@@ -19710,9 +19826,18 @@ var WeaveImageNode = class extends WeaveNode {
19710
19826
  delete internalImageProps.zIndex;
19711
19827
  const image = new konva.default.Group({
19712
19828
  ...groupImageProps,
19829
+ ...internalImageProps,
19713
19830
  id,
19714
19831
  name: "node"
19715
19832
  });
19833
+ image.resetCrop = () => {
19834
+ const stage = this.instance.getStage();
19835
+ const image$1 = stage.findOne(`#${id}`);
19836
+ if (!image$1) return;
19837
+ const imageCrop = new WeaveImageCrop(this.instance, this, image$1, internalImage, cropGroup);
19838
+ imageCrop.unCrop();
19839
+ this.cachedCropInfo[image$1.getAttrs().id ?? ""] = void 0;
19840
+ };
19716
19841
  image.getTransformerProperties = () => {
19717
19842
  return this.config.transform;
19718
19843
  };
@@ -19745,25 +19870,30 @@ var WeaveImageNode = class extends WeaveNode {
19745
19870
  rotation: 0,
19746
19871
  width: 0,
19747
19872
  height: 0,
19873
+ stroke: "#ff0000ff",
19874
+ strokeWidth: 0,
19875
+ strokeScaleEnabled: false,
19748
19876
  draggable: false,
19749
19877
  visible: false
19750
19878
  });
19751
19879
  image.add(internalImage);
19752
- const clipGroup = new konva.default.Group({
19880
+ const cropGroup = new konva.default.Group({
19881
+ id: `${id}-cropGroup`,
19753
19882
  x: 0,
19754
19883
  y: 0,
19884
+ scaleX: 1,
19885
+ scaleY: 1,
19755
19886
  visible: false
19756
19887
  });
19757
- image.add(clipGroup);
19888
+ image.add(cropGroup);
19758
19889
  this.setupDefaultNodeEvents(image);
19759
19890
  image.on("dblclick dbltap", (evt) => {
19760
19891
  evt.cancelBubble = true;
19761
- if (this.cropping) return;
19892
+ if (image.getAttrs().cropping ?? false) return;
19762
19893
  if (!internalImage.getAttr("image")) return;
19763
19894
  if (!(this.isSelecting() && this.isNodeSelected(image))) return;
19764
- this.cropping = true;
19765
- const imageClip = new WeaveImageClip(this.instance, this, image, internalImage, clipGroup);
19766
- imageClip.show();
19895
+ const imageCrop = new WeaveImageCrop(this.instance, this, image, internalImage, cropGroup);
19896
+ imageCrop.show();
19767
19897
  });
19768
19898
  const imageActionTool = this.getImageToolAction();
19769
19899
  const preloadImg = imageActionTool.getPreloadedImage(imageProps.id);
@@ -19782,6 +19912,12 @@ var WeaveImageNode = class extends WeaveNode {
19782
19912
  this.imageLoaded = true;
19783
19913
  image.setAttr("width", image.width() ? image.width() : preloadImg.width);
19784
19914
  image.setAttr("height", image.height() ? image.height() : preloadImg.height);
19915
+ const imageRect = image.getClientRect();
19916
+ image.setAttr("cropInfo", void 0);
19917
+ image.setAttr("uncroppedImage", {
19918
+ width: imageRect.width,
19919
+ height: imageRect.height
19920
+ });
19785
19921
  image.setAttr("imageInfo", {
19786
19922
  width: preloadImg.width,
19787
19923
  height: preloadImg.height
@@ -19837,25 +19973,33 @@ var WeaveImageNode = class extends WeaveNode {
19837
19973
  zIndex: 1
19838
19974
  });
19839
19975
  }
19840
- if (this.imageLoaded) internalImage?.setAttrs({
19841
- ...internalImageProps,
19842
- ...nodeAttrs.imageProperties ?? {},
19843
- name: void 0,
19844
- id: `${id}-image`,
19845
- nodeId: id,
19846
- x: 0,
19847
- y: 0,
19848
- scaleX: 1,
19849
- scaleY: 1,
19850
- rotation: 0,
19851
- visible: true,
19852
- draggable: false,
19853
- zIndex: 0
19854
- });
19976
+ if (this.imageLoaded) {
19977
+ internalImage?.setAttrs({
19978
+ ...internalImageProps,
19979
+ ...nodeAttrs.imageProperties ?? {},
19980
+ name: void 0,
19981
+ id: `${id}-image`,
19982
+ nodeId: id,
19983
+ x: 0,
19984
+ y: 0,
19985
+ scaleX: 1,
19986
+ scaleY: 1,
19987
+ rotation: 0,
19988
+ visible: true,
19989
+ draggable: false,
19990
+ zIndex: 0
19991
+ });
19992
+ this.updateCrop(nextProps);
19993
+ }
19994
+ try {
19995
+ const selectionPlugin = this.instance.getPlugin("nodesSelection");
19996
+ if (selectionPlugin) selectionPlugin.getTransformer().forceUpdate();
19997
+ } catch (error) {
19998
+ console.error("Error updating transformer", error);
19999
+ }
19855
20000
  }
19856
20001
  loadImage(params, image) {
19857
20002
  const imageProps = params;
19858
- const imageGroup = image.findOne(`#${imageProps.id}`);
19859
20003
  const imagePlaceholder = image.findOne(`#${imageProps.id}-placeholder`);
19860
20004
  const internalImage = image.findOne(`#${imageProps.id}-image`);
19861
20005
  const imageObj = new Image();
@@ -19865,29 +20009,71 @@ var WeaveImageNode = class extends WeaveNode {
19865
20009
  internalImage?.setAttrs({ visible: false });
19866
20010
  };
19867
20011
  imageObj.onload = () => {
19868
- imageGroup?.setAttrs({
19869
- width: imageProps.width ? imageProps.width : imageObj.width,
19870
- height: imageProps.height ? imageProps.height : imageObj.height
19871
- });
19872
- imagePlaceholder?.destroy();
19873
- internalImage?.setAttrs({
19874
- width: imageProps.width ? imageProps.width : imageObj.width,
19875
- height: imageProps.height ? imageProps.height : imageObj.height,
19876
- image: imageObj,
19877
- visible: true
19878
- });
19879
- internalImage?.zIndex(0);
19880
- this.imageLoaded = true;
19881
- image.setAttr("width", imageProps.width ? imageProps.width : imageObj.width);
19882
- image.setAttr("height", imageProps.height ? imageProps.height : imageObj.height);
19883
- image.setAttr("imageInfo", {
19884
- width: imageObj.width,
19885
- height: imageObj.height
19886
- });
19887
- this.instance.updateNode(this.serialize(image));
20012
+ if (image && imagePlaceholder && internalImage) {
20013
+ image.setAttrs({
20014
+ width: imageProps.width ? imageProps.width : imageObj.width,
20015
+ height: imageProps.height ? imageProps.height : imageObj.height
20016
+ });
20017
+ imagePlaceholder.destroy();
20018
+ internalImage.setAttrs({
20019
+ width: imageProps.width ? imageProps.width : imageObj.width,
20020
+ height: imageProps.height ? imageProps.height : imageObj.height,
20021
+ image: imageObj,
20022
+ visible: true
20023
+ });
20024
+ internalImage.setAttr("imageInfo", {
20025
+ width: imageObj.width,
20026
+ height: imageObj.height
20027
+ });
20028
+ internalImage.zIndex(0);
20029
+ this.imageLoaded = true;
20030
+ image.setAttrs({
20031
+ width: imageProps.width ? imageProps.width : imageObj.width,
20032
+ height: imageProps.height ? imageProps.height : imageObj.height
20033
+ });
20034
+ image.setAttr("imageInfo", {
20035
+ width: imageObj.width,
20036
+ height: imageObj.height
20037
+ });
20038
+ this.updateCrop(imageProps);
20039
+ }
19888
20040
  };
19889
20041
  if (imageProps.imageURL) imageObj.src = imageProps.imageURL;
19890
20042
  }
20043
+ updateCrop(nextProps) {
20044
+ const imageAttrs = nextProps;
20045
+ const stage = this.instance.getStage();
20046
+ const image = stage.findOne(`#${imageAttrs.id}`);
20047
+ const internalImage = image?.findOne(`#${imageAttrs.id}-image`);
20048
+ if (image && internalImage && !imageAttrs.adding && imageAttrs.cropInfo && !(0, import_lodash.isEqual)(imageAttrs.cropInfo, this.cachedCropInfo[imageAttrs.id ?? ""])) {
20049
+ const actualScale = imageAttrs.uncroppedImage.width / imageAttrs.imageInfo.width;
20050
+ internalImage.width(imageAttrs.uncroppedImage.width);
20051
+ internalImage.height(imageAttrs.uncroppedImage.height);
20052
+ internalImage.rotation(0);
20053
+ internalImage.scaleX(1);
20054
+ internalImage.scaleY(1);
20055
+ internalImage.crop({
20056
+ x: imageAttrs.cropInfo.x / actualScale,
20057
+ y: imageAttrs.cropInfo.y / actualScale,
20058
+ width: imageAttrs.cropInfo.width / actualScale,
20059
+ height: imageAttrs.cropInfo.height / actualScale
20060
+ });
20061
+ internalImage.width(imageAttrs.cropSize.width);
20062
+ internalImage.height(imageAttrs.cropSize.height);
20063
+ this.cachedCropInfo[imageAttrs.id ?? ""] = imageAttrs.cropInfo;
20064
+ }
20065
+ if (image && internalImage && !imageAttrs.adding && !imageAttrs.cropInfo && !(0, import_lodash.isEqual)(imageAttrs.cropInfo, this.cachedCropInfo[imageAttrs.id ?? ""])) {
20066
+ internalImage.width(imageAttrs.uncroppedImage.width);
20067
+ internalImage.height(imageAttrs.uncroppedImage.height);
20068
+ internalImage.rotation(0);
20069
+ internalImage.scaleX(1);
20070
+ internalImage.scaleY(1);
20071
+ internalImage.crop(void 0);
20072
+ internalImage.width(imageAttrs.uncroppedImage.width);
20073
+ internalImage.height(imageAttrs.uncroppedImage.height);
20074
+ this.cachedCropInfo[imageAttrs.id ?? ""] = void 0;
20075
+ }
20076
+ }
19891
20077
  getImageToolAction() {
19892
20078
  const imageToolAction = this.instance.getActionHandler("imageTool");
19893
20079
  if (!imageToolAction) throw new Error("Image Tool action not found");
@@ -20201,41 +20387,45 @@ var WeaveFrameNode = class extends WeaveNode {
20201
20387
  nodeInstance.setAttrs({ ...newProps });
20202
20388
  const selectorArea = frameNode.findOne(`#${id}-selector-area`);
20203
20389
  if (selectorArea) {
20390
+ const width = nextProps.width ? nextProps.width : nextProps.frameWidth;
20391
+ const height = nextProps.height ? nextProps.height : nextProps.frameHeight;
20204
20392
  selectorArea.setAttrs({
20205
20393
  x: 0,
20206
20394
  y: 0,
20207
- width: nextProps.width,
20208
- height: nextProps.height
20395
+ width,
20396
+ height
20209
20397
  });
20210
20398
  const frameInternalGroup = frameNode.findOne(`#${id}-selector`);
20211
20399
  if (frameInternalGroup) frameInternalGroup.setAttrs({
20212
20400
  x: 0,
20213
20401
  y: 0,
20214
- width: nextProps.width * selectorArea.scaleX(),
20215
- height: nextProps.height * selectorArea.scaleY()
20402
+ width: width * selectorArea.scaleX(),
20403
+ height: height * selectorArea.scaleY()
20216
20404
  });
20217
20405
  const background = frameNode.findOne(`#${id}-bg`);
20218
20406
  if (background) background.setAttrs({
20219
20407
  x: 0,
20220
20408
  y: 0,
20221
- width: nextProps.width * selectorArea.scaleX(),
20222
- height: nextProps.height * selectorArea.scaleY()
20409
+ width: width * selectorArea.scaleX(),
20410
+ height: height * selectorArea.scaleY()
20223
20411
  });
20224
20412
  const text = frameNode.findOne(`#${id}-title`);
20225
20413
  if (text) text.setAttrs({
20226
20414
  x: 0,
20227
20415
  y: -titleHeight,
20228
20416
  text: nextProps.title,
20229
- width: nextProps.width * selectorArea.scaleX()
20417
+ width: width * selectorArea.scaleX()
20230
20418
  });
20231
20419
  const frameInternal = frameNode.findOne(`#${id}-group-internal`);
20232
20420
  if (frameInternal) frameInternal.setAttrs({
20233
20421
  x: 0,
20234
20422
  y: titleHeight,
20235
- width: nextProps.width * selectorArea.scaleX(),
20236
- height: nextProps.height * selectorArea.scaleY()
20423
+ width: width * selectorArea.scaleX(),
20424
+ height: height * selectorArea.scaleY()
20237
20425
  });
20238
20426
  }
20427
+ const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
20428
+ if (nodesSelectionPlugin) nodesSelectionPlugin.getTransformer().forceUpdate();
20239
20429
  }
20240
20430
  serialize(instance) {
20241
20431
  const stage = this.instance.getStage();
@@ -22194,6 +22384,7 @@ var WeaveConnectedUsersPlugin = class extends WeavePlugin {
22194
22384
  //#endregion
22195
22385
  //#region src/plugins/users-selection/users-selection.ts
22196
22386
  var WeaveUsersSelectionPlugin = class extends WeavePlugin {
22387
+ padding = 1;
22197
22388
  constructor(params) {
22198
22389
  super();
22199
22390
  const { config } = params;
@@ -22311,17 +22502,15 @@ var WeaveUsersSelectionPlugin = class extends WeavePlugin {
22311
22502
  id: `selector_${userSelector.actualNodes.user}`,
22312
22503
  x: selectionRect.x,
22313
22504
  y: selectionRect.y,
22314
- width: selectionRect.width / stage.scaleX(),
22315
- height: selectionRect.height / stage.scaleY(),
22316
22505
  listening: false
22317
22506
  });
22318
22507
  userSelectorNode.moveToBottom();
22319
22508
  const userSelectorRect = new konva.default.Rect({
22320
- x: 0,
22321
- y: 0,
22509
+ x: -this.padding / stage.scaleX(),
22510
+ y: -this.padding / stage.scaleY(),
22322
22511
  id: `selector_${userSelector.actualNodes.user}_rect`,
22323
- width: selectionRect.width / stage.scaleX(),
22324
- height: selectionRect.height / stage.scaleY(),
22512
+ width: (selectionRect.width + 2 * this.padding) / stage.scaleX(),
22513
+ height: (selectionRect.height + 2 * this.padding) / stage.scaleY(),
22325
22514
  fill: "transparent",
22326
22515
  stroke: this.stringToColor(userSelector.actualNodes.user),
22327
22516
  strokeWidth: 3,