microboard-temp 0.10.2 → 0.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.
@@ -1050,6 +1050,24 @@ class Matrix {
1050
1050
  const { translateX, translateY, scaleX, scaleY, shearX, shearY } = matrix;
1051
1051
  return this.translateX === translateX && this.translateY === translateY && this.scaleX === scaleX && this.scaleY === scaleY && this.shearX === shearX && this.shearY === shearY;
1052
1052
  }
1053
+ composeWith(parent) {
1054
+ const result = parent.copy();
1055
+ result.multiplyByMatrix(this);
1056
+ return result;
1057
+ }
1058
+ toLocalOf(parent) {
1059
+ const result = parent.getInverse();
1060
+ result.multiplyByMatrix(this);
1061
+ return result;
1062
+ }
1063
+ applyInverseLinear(dx, dy) {
1064
+ const { scaleX, scaleY, shearX, shearY } = this;
1065
+ const denom = scaleX * scaleY - shearX * shearY;
1066
+ return {
1067
+ x: (scaleY * dx - shearX * dy) / denom,
1068
+ y: (-shearY * dx + scaleX * dy) / denom
1069
+ };
1070
+ }
1053
1071
  }
1054
1072
 
1055
1073
  // src/Subject.ts
@@ -17795,6 +17813,15 @@ class Transformation {
17795
17813
  getRotation() {
17796
17814
  return this.rotate;
17797
17815
  }
17816
+ setLocalMatrix(matrix) {
17817
+ this.previous = this._matrix.copy();
17818
+ this._matrix = matrix.copy();
17819
+ this.subject.publish(this, {
17820
+ class: "Transformation",
17821
+ method: "applyMatrix",
17822
+ items: [{ id: this.id, matrix: this.getMatrixData() }]
17823
+ });
17824
+ }
17798
17825
  setLocal(xOrData, y, scaleX, scaleY) {
17799
17826
  this.previous = this._matrix.copy();
17800
17827
  if (typeof xOrData === "object") {
@@ -20717,6 +20744,24 @@ class LayeredIndex {
20717
20744
  }
20718
20745
 
20719
20746
  // src/SpatialIndex/SpacialIndex.ts
20747
+ function worldBoundsToLocal(container, left, top, right, bottom) {
20748
+ const inv = container.getWorldMatrix().getInverse();
20749
+ const corners = [
20750
+ new Point(left, top),
20751
+ new Point(right, top),
20752
+ new Point(right, bottom),
20753
+ new Point(left, bottom)
20754
+ ];
20755
+ for (const c of corners)
20756
+ inv.apply(c);
20757
+ return {
20758
+ left: Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20759
+ top: Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y),
20760
+ right: Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20761
+ bottom: Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y)
20762
+ };
20763
+ }
20764
+
20720
20765
  class SpatialIndex {
20721
20766
  subject = new Subject;
20722
20767
  itemsArray = [];
@@ -20768,6 +20813,8 @@ class SpatialIndex {
20768
20813
  if (item.parent !== "Board") {
20769
20814
  const parentFrame = this.items.getById(item.parent);
20770
20815
  parentFrame?.removeChildItems(item);
20816
+ this.subject.publish(this.items);
20817
+ return;
20771
20818
  }
20772
20819
  this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
20773
20820
  this.itemsIndex.remove(item);
@@ -20782,10 +20829,20 @@ class SpatialIndex {
20782
20829
  this.subject.publish(this.items);
20783
20830
  }
20784
20831
  copy() {
20785
- return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => ({
20786
- ...item.serialize(true),
20787
- id: item.getId()
20788
- }));
20832
+ return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => {
20833
+ const serialized = { ...item.serialize(true), id: item.getId() };
20834
+ if (item.parent !== "Board" && item.getWorldMatrix) {
20835
+ const worldMatrix = item.getWorldMatrix();
20836
+ serialized.transformation = {
20837
+ ...serialized.transformation,
20838
+ translateX: worldMatrix.translateX,
20839
+ translateY: worldMatrix.translateY,
20840
+ scaleX: worldMatrix.scaleX,
20841
+ scaleY: worldMatrix.scaleY
20842
+ };
20843
+ }
20844
+ return serialized;
20845
+ });
20789
20846
  }
20790
20847
  getItemsWithIncludedChildren(items) {
20791
20848
  return items.flatMap((item) => {
@@ -20951,7 +21008,8 @@ class SpatialIndex {
20951
21008
  const children = [];
20952
21009
  const clearItems = items.filter((item) => {
20953
21010
  if ("index" in item && item.index) {
20954
- children.push(...item.index.getEnclosed(left, top, right, bottom));
21011
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21012
+ children.push(...item.index.getEnclosed(local.left, local.top, local.right, local.bottom));
20955
21013
  if (!item.getMbr().isEnclosedBy(mbr)) {
20956
21014
  return false;
20957
21015
  }
@@ -20966,7 +21024,8 @@ class SpatialIndex {
20966
21024
  const children = [];
20967
21025
  const clearItems = items.filter((item) => {
20968
21026
  if ("index" in item && item.index) {
20969
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21027
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21028
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
20970
21029
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
20971
21030
  return false;
20972
21031
  }
@@ -20980,7 +21039,9 @@ class SpatialIndex {
20980
21039
  const children = [];
20981
21040
  const clearItems = items.filter((item) => {
20982
21041
  if ("index" in item && item.index) {
20983
- children.push(...item.index.getUnderPoint(point3, tolerance));
21042
+ const localPt = new Point(point3.x, point3.y);
21043
+ item.getWorldMatrix().getInverse().apply(localPt);
21044
+ children.push(...item.index.getUnderPoint(localPt, tolerance));
20984
21045
  if (!item.getMbr().isUnderPoint(point3)) {
20985
21046
  return false;
20986
21047
  }
@@ -20995,7 +21056,8 @@ class SpatialIndex {
20995
21056
  const children = [];
20996
21057
  const clearItems = items.filter((item) => {
20997
21058
  if ("index" in item && item.index) {
20998
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21059
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21060
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
20999
21061
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
21000
21062
  return false;
21001
21063
  }
@@ -21458,6 +21520,49 @@ class SimpleSpatialIndex {
21458
21520
  }
21459
21521
 
21460
21522
  // src/Items/BaseItem/BaseItem.ts
21523
+ function toLocalTransformOp(op, containerMatrix, itemId) {
21524
+ switch (op.method) {
21525
+ case "applyMatrix": {
21526
+ const converted = op.items.map((item) => {
21527
+ const local = containerMatrix.applyInverseLinear(item.matrix.translateX, item.matrix.translateY);
21528
+ return { ...item, matrix: { ...item.matrix, translateX: local.x, translateY: local.y } };
21529
+ });
21530
+ return { ...op, items: converted };
21531
+ }
21532
+ case "translateBy": {
21533
+ const local = containerMatrix.applyInverseLinear(op.x, op.y);
21534
+ return { ...op, x: local.x, y: local.y };
21535
+ }
21536
+ case "translateTo": {
21537
+ const pt = new Point(op.x, op.y);
21538
+ containerMatrix.getInverse().apply(pt);
21539
+ return { ...op, x: pt.x, y: pt.y };
21540
+ }
21541
+ case "scaleTo": {
21542
+ return { ...op, x: op.x / containerMatrix.scaleX, y: op.y / containerMatrix.scaleY };
21543
+ }
21544
+ case "scaleByTranslateBy": {
21545
+ const local = containerMatrix.applyInverseLinear(op.translate.x, op.translate.y);
21546
+ return { ...op, translate: { x: local.x, y: local.y } };
21547
+ }
21548
+ case "scaleByRelativeTo":
21549
+ case "scaleToRelativeTo": {
21550
+ const pt = new Point(op.point.x, op.point.y);
21551
+ containerMatrix.getInverse().apply(pt);
21552
+ return { ...op, point: pt };
21553
+ }
21554
+ case "transformMany": {
21555
+ if (!itemId || !op.items[itemId])
21556
+ return op;
21557
+ const subOp = op.items[itemId];
21558
+ const localSubOp = toLocalTransformOp(subOp, containerMatrix);
21559
+ return { ...op, items: { ...op.items, [itemId]: localSubOp } };
21560
+ }
21561
+ default:
21562
+ return op;
21563
+ }
21564
+ }
21565
+
21461
21566
  class BaseItem extends Mbr {
21462
21567
  defaultItemData;
21463
21568
  transformation;
@@ -21502,6 +21607,16 @@ class BaseItem extends Mbr {
21502
21607
  getId() {
21503
21608
  return this.id;
21504
21609
  }
21610
+ getWorldMatrix() {
21611
+ if (this.parent === "Board") {
21612
+ return this.transformation.toMatrix();
21613
+ }
21614
+ const container = this.board.items.getById(this.parent);
21615
+ if (!container) {
21616
+ return this.transformation.toMatrix();
21617
+ }
21618
+ return this.transformation.toMatrix().composeWith(container.getWorldMatrix());
21619
+ }
21505
21620
  setId(id) {
21506
21621
  this.id = id;
21507
21622
  this.transformation.setId(id);
@@ -21576,16 +21691,39 @@ class BaseItem extends Mbr {
21576
21691
  getMbr() {
21577
21692
  return new Mbr(this.left, this.top, this.right, this.bottom);
21578
21693
  }
21694
+ getWorldMbr() {
21695
+ if (this.parent === "Board" || !this.parent || !this.board?.items) {
21696
+ return this.getMbr();
21697
+ }
21698
+ const container = this.board.items.getById(this.parent);
21699
+ if (!container) {
21700
+ return this.getMbr();
21701
+ }
21702
+ const containerWorldMatrix = container.getWorldMatrix();
21703
+ const local = this.getMbr();
21704
+ const corners = [
21705
+ new Point(local.left, local.top),
21706
+ new Point(local.right, local.top),
21707
+ new Point(local.right, local.bottom),
21708
+ new Point(local.left, local.bottom)
21709
+ ];
21710
+ for (const c of corners)
21711
+ containerWorldMatrix.apply(c);
21712
+ return new Mbr(Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x), Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y), Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x), Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y));
21713
+ }
21579
21714
  applyAddChildren(childIds) {
21580
21715
  if (!this.index) {
21581
21716
  return;
21582
21717
  }
21718
+ const containerWorldMatrix = this.getWorldMatrix();
21583
21719
  childIds.forEach((childId) => {
21584
21720
  const foundItem = this.board.items.getById(childId);
21585
21721
  if (this.parent !== childId && this.getId() !== childId) {
21586
21722
  if (!this.index?.getById(childId) && foundItem) {
21723
+ const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerWorldMatrix);
21587
21724
  this.board.items.index.remove(foundItem);
21588
21725
  foundItem.parent = this.getId();
21726
+ foundItem.transformation.setLocalMatrix(localMatrix);
21589
21727
  this.index?.insert(foundItem);
21590
21728
  }
21591
21729
  }
@@ -21598,12 +21736,15 @@ class BaseItem extends Mbr {
21598
21736
  if (!this.index) {
21599
21737
  return;
21600
21738
  }
21739
+ const containerWorldMatrix = this.getWorldMatrix();
21601
21740
  childIds.forEach((childId) => {
21602
21741
  const foundItem = this.index?.getById(childId);
21603
21742
  if (this.parent !== childId && this.getId() !== childId) {
21604
21743
  if (foundItem) {
21744
+ const worldMatrix = foundItem.transformation.toMatrix().composeWith(containerWorldMatrix);
21605
21745
  this.index?.remove(foundItem);
21606
21746
  foundItem.parent = "Board";
21747
+ foundItem.transformation.setLocalMatrix(worldMatrix);
21607
21748
  this.board.items.index.insert(foundItem);
21608
21749
  }
21609
21750
  }
@@ -21715,9 +21856,17 @@ class BaseItem extends Mbr {
21715
21856
  apply(op) {
21716
21857
  op = op;
21717
21858
  switch (op.class) {
21718
- case "Transformation":
21719
- this.transformation.apply(op);
21859
+ case "Transformation": {
21860
+ let transformOp = op;
21861
+ if (this.parent !== "Board") {
21862
+ const container = this.board.items.getById(this.parent);
21863
+ if (container?.transformation) {
21864
+ transformOp = toLocalTransformOp(transformOp, container.getWorldMatrix(), this.id);
21865
+ }
21866
+ }
21867
+ this.transformation.apply(transformOp);
21720
21868
  break;
21869
+ }
21721
21870
  case "LinkTo":
21722
21871
  this.linkTo.apply(op);
21723
21872
  break;
@@ -21838,6 +21987,7 @@ class RichText extends BaseItem {
21838
21987
  _onLimitReached = () => {};
21839
21988
  shrinkWidth = false;
21840
21989
  prevMbr = null;
21990
+ worldMatrixGetter;
21841
21991
  rtCounter = 0;
21842
21992
  constructor(board, container, id = "", transformation = new Transformation(id, board.events), linkTo, placeholderText = conf.i18n?.t("board.textPlaceholder"), isInShape = false, autoSize = false, insideOf, initialTextStyles = conf.DEFAULT_TEXT_STYLES) {
21843
21993
  super(board, id);
@@ -22007,7 +22157,7 @@ class RichText extends BaseItem {
22007
22157
  };
22008
22158
  calcAutoSize(blockNodes) {
22009
22159
  const nodes = blockNodes ? blockNodes : this.getBlockNodes();
22010
- const container = this.getTransformedContainer();
22160
+ const container = this.getLayoutContainer();
22011
22161
  const containerWidth = container.getWidth();
22012
22162
  const containerHeight = container.getHeight();
22013
22163
  const optimal = findOptimalMaxWidthForTextAutoSize(nodes, containerWidth, containerHeight, containerWidth);
@@ -22015,7 +22165,7 @@ class RichText extends BaseItem {
22015
22165
  }
22016
22166
  applyAutoSizeScale(textScale, blockNodes) {
22017
22167
  const nodes = blockNodes ? blockNodes : this.getBlockNodes();
22018
- const container = this.getTransformedContainer();
22168
+ const container = this.getLayoutContainer();
22019
22169
  const containerWidth = container.getWidth();
22020
22170
  const containerHeight = container.getHeight();
22021
22171
  this.layoutNodes = getBlockNodes(nodes, containerWidth / textScale);
@@ -22137,6 +22287,13 @@ class RichText extends BaseItem {
22137
22287
  }
22138
22288
  return this.container.getTransformed(this.transformation.toMatrix());
22139
22289
  }
22290
+ getLayoutContainer() {
22291
+ if (this.insideOf === "Frame") {
22292
+ return this.getTransformedContainer();
22293
+ }
22294
+ const matrix = this.worldMatrixGetter ? this.worldMatrixGetter() : this.transformation.toMatrix();
22295
+ return this.container.getTransformed(matrix);
22296
+ }
22140
22297
  emitWithoutApplying = (op) => {
22141
22298
  if (this.board.events) {
22142
22299
  this.board.events.emit(op);
@@ -36103,6 +36260,7 @@ class AINode extends BaseItem {
36103
36260
  this.subject.publish(this);
36104
36261
  });
36105
36262
  this.text.insideOf = "AINode";
36263
+ this.text.worldMatrixGetter = () => this.getWorldMatrix();
36106
36264
  this.transformPath();
36107
36265
  }
36108
36266
  transformPath() {
@@ -36194,7 +36352,7 @@ class AINode extends BaseItem {
36194
36352
  this.text.apply(op);
36195
36353
  break;
36196
36354
  case "Transformation":
36197
- this.text.transformation.apply(op);
36355
+ super.apply(op);
36198
36356
  break;
36199
36357
  case "LinkTo":
36200
36358
  this.linkTo.apply(op);
@@ -36522,14 +36680,20 @@ function getControlPoint(data, findItem2) {
36522
36680
  }
36523
36681
  }
36524
36682
  }
36683
+ function getItemWorldMatrix(item) {
36684
+ if (item instanceof BaseItem && item.parent !== "Board") {
36685
+ return item.getWorldMatrix();
36686
+ }
36687
+ return item.transformation?.toMatrix() ?? new Matrix;
36688
+ }
36525
36689
  function toRelativePoint(point5, item) {
36526
- const inverse = item.transformation ? item.transformation.getInverse().toMatrix() : new Matrix;
36690
+ const inverse = getItemWorldMatrix(item).getInverse();
36527
36691
  point5 = point5.copy();
36528
36692
  point5.transform(inverse);
36529
36693
  return point5;
36530
36694
  }
36531
36695
  function fromRelativePoint(relativePoint, item, edge) {
36532
- const matrix = item.transformation?.toMatrix() ?? new Matrix;
36696
+ const matrix = getItemWorldMatrix(item);
36533
36697
  const point5 = relativePoint.copy();
36534
36698
  point5.transform(matrix);
36535
36699
  if (item instanceof RichText || item instanceof AINode) {
@@ -40118,6 +40282,7 @@ class Sticker extends BaseItem {
40118
40282
  this.linkTo = new LinkTo(this.id, this.board.events);
40119
40283
  this.transformation = new Transformation(this.id, this.board.events);
40120
40284
  this.text = new RichText(board, this.textContainer, this.id, this.transformation, this.linkTo, " ", false, true, this.itemType);
40285
+ this.text.worldMatrixGetter = () => this.getWorldMatrix();
40121
40286
  this.transformation.subject.subscribe((_subject, op) => {
40122
40287
  this.transformPath();
40123
40288
  if (op.method === "applyMatrix") {
@@ -40221,7 +40386,7 @@ class Sticker extends BaseItem {
40221
40386
  this.text.apply(op);
40222
40387
  break;
40223
40388
  case "Transformation":
40224
- this.transformation.apply(op);
40389
+ super.apply(op);
40225
40390
  break;
40226
40391
  case "LinkTo":
40227
40392
  this.linkTo.apply(op);
@@ -41004,7 +41169,13 @@ class Frame2 extends BaseItem {
41004
41169
  return;
41005
41170
  }
41006
41171
  this.renderPath(context);
41007
- super.render(context);
41172
+ const ctx = context.ctx;
41173
+ ctx.save();
41174
+ this.transformation.applyToContext(ctx);
41175
+ for (const child of this.index.list()) {
41176
+ child.render(context);
41177
+ }
41178
+ ctx.restore();
41008
41179
  this.renderBorders(context);
41009
41180
  this.renderName(context);
41010
41181
  }
@@ -43112,25 +43283,24 @@ function douglasPeucker(points, epsilon2) {
43112
43283
  // src/Items/Group/Group.ts
43113
43284
  class Group extends BaseItem {
43114
43285
  events;
43115
- children;
43116
43286
  linkTo;
43117
43287
  itemType = "Group";
43118
43288
  parent = "Board";
43119
43289
  transformation;
43120
43290
  subject = new Subject;
43121
- mbr = new Mbr;
43122
43291
  transformationRenderBlock = undefined;
43123
43292
  constructor(board, events, children = [], id = "") {
43124
- super(board, id);
43293
+ super(board, id, undefined, true);
43125
43294
  this.events = events;
43126
- this.children = children;
43127
43295
  this.linkTo = new LinkTo(this.id, this.events);
43128
43296
  this.transformation = new Transformation(this.id, this.events);
43129
- this.children = children;
43130
43297
  this.transformation.subject.subscribe(() => {
43131
43298
  this.updateMbr();
43132
43299
  this.subject.publish(this);
43133
43300
  });
43301
+ if (children.length > 0) {
43302
+ this.applyAddChildren(children);
43303
+ }
43134
43304
  }
43135
43305
  isClosed() {
43136
43306
  return false;
@@ -43138,45 +43308,17 @@ class Group extends BaseItem {
43138
43308
  getRichText() {
43139
43309
  return null;
43140
43310
  }
43141
- addChild(childId) {
43142
- this.emit({
43143
- class: "Group",
43144
- method: "addChild",
43145
- item: [this.getId()],
43146
- childId
43147
- });
43148
- }
43149
- applyAddChild(childId) {
43150
- if (!this.children.includes(childId)) {
43151
- this.children.push(childId);
43152
- this.updateMbr();
43153
- this.subject.publish(this);
43154
- }
43155
- }
43156
- applyRemoveChild(childId) {
43157
- this.children = this.children.filter((currChild) => currChild !== childId);
43158
- this.updateMbr();
43159
- this.subject.publish(this);
43160
- }
43161
- removeChild(childId) {
43162
- this.emit({
43163
- class: "Group",
43164
- method: "removeChild",
43165
- item: [this.getId()],
43166
- childId
43167
- });
43168
- }
43169
- emitRemoveChild(child) {
43170
- this.removeChild(child.getId());
43171
- child.parent = "Board";
43172
- }
43173
43311
  apply(op) {
43174
43312
  switch (op.class) {
43175
43313
  case "Group":
43176
43314
  if (op.method === "addChild") {
43177
- this.applyAddChild(op.childId);
43315
+ this.applyAddChildren([op.childId]);
43178
43316
  } else if (op.method === "removeChild") {
43179
- this.applyRemoveChild(op.childId);
43317
+ this.applyRemoveChildren([op.childId]);
43318
+ } else if (op.method === "addChildren") {
43319
+ this.applyAddChildren(op.newData.childIds);
43320
+ } else if (op.method === "removeChildren") {
43321
+ this.applyRemoveChildren(op.newData.childIds);
43180
43322
  }
43181
43323
  break;
43182
43324
  case "Transformation":
@@ -43201,24 +43343,69 @@ class Group extends BaseItem {
43201
43343
  this.transformation.setId(id);
43202
43344
  return this;
43203
43345
  }
43346
+ getMbr() {
43347
+ const children = this.index.list();
43348
+ if (children.length === 0) {
43349
+ return new Mbr(this.left, this.top, this.right, this.bottom);
43350
+ }
43351
+ const groupWorldMatrix = this.getWorldMatrix();
43352
+ let left = Number.MAX_SAFE_INTEGER;
43353
+ let top = Number.MAX_SAFE_INTEGER;
43354
+ let right = Number.MIN_SAFE_INTEGER;
43355
+ let bottom = Number.MIN_SAFE_INTEGER;
43356
+ for (const child of children) {
43357
+ const childLocalMbr = child.getMbr();
43358
+ const corners = [
43359
+ { x: childLocalMbr.left, y: childLocalMbr.top },
43360
+ { x: childLocalMbr.right, y: childLocalMbr.top },
43361
+ { x: childLocalMbr.right, y: childLocalMbr.bottom },
43362
+ { x: childLocalMbr.left, y: childLocalMbr.bottom }
43363
+ ];
43364
+ for (const corner of corners) {
43365
+ groupWorldMatrix.apply(corner);
43366
+ if (corner.x < left)
43367
+ left = corner.x;
43368
+ if (corner.y < top)
43369
+ top = corner.y;
43370
+ if (corner.x > right)
43371
+ right = corner.x;
43372
+ if (corner.y > bottom)
43373
+ bottom = corner.y;
43374
+ }
43375
+ }
43376
+ const mbr = new Mbr(left, top, right, bottom);
43377
+ this.left = left;
43378
+ this.top = top;
43379
+ this.right = right;
43380
+ this.bottom = bottom;
43381
+ return mbr;
43382
+ }
43383
+ updateMbr() {
43384
+ this.getMbr();
43385
+ }
43386
+ getChildrenIds() {
43387
+ return this.index.list().map((item) => item.getId());
43388
+ }
43389
+ getChildren() {
43390
+ return this.index.list();
43391
+ }
43392
+ getLinkTo() {
43393
+ return this.linkTo.link;
43394
+ }
43204
43395
  serialize() {
43205
43396
  return {
43206
43397
  itemType: "Group",
43207
- children: this.children,
43398
+ children: this.getChildrenIds(),
43208
43399
  transformation: this.transformation.serialize()
43209
43400
  };
43210
43401
  }
43211
43402
  deserialize(data) {
43212
- if (data.children) {
43213
- data.children.forEach((childId) => {
43214
- this.applyAddChild(childId);
43215
- const item = this.board.items.getById(childId);
43216
- if (item) {
43217
- item.parent = this.getId();
43218
- }
43219
- });
43403
+ if (data.transformation) {
43404
+ this.transformation.deserialize(data.transformation);
43405
+ }
43406
+ if (data.children && data.children.length > 0) {
43407
+ this.applyAddChildren(data.children);
43220
43408
  }
43221
- this.transformation.deserialize(data.transformation);
43222
43409
  this.subject.publish(this);
43223
43410
  return this;
43224
43411
  }
@@ -43228,99 +43415,25 @@ class Group extends BaseItem {
43228
43415
  getIntersectionPoints(segment) {
43229
43416
  const lines = this.getMbr().getLines();
43230
43417
  const initPoints = [];
43231
- const points = lines.reduce((acc, line) => {
43418
+ return lines.reduce((acc, line) => {
43232
43419
  const intersections = line.getIntersectionPoints(segment);
43233
43420
  if (intersections.length > 0) {
43234
43421
  acc.push(...intersections);
43235
43422
  }
43236
43423
  return acc;
43237
43424
  }, initPoints);
43238
- return points;
43239
- }
43240
- getMbr() {
43241
- const mbr = new Mbr;
43242
- let left = Number.MAX_SAFE_INTEGER;
43243
- let top = Number.MAX_SAFE_INTEGER;
43244
- let right = Number.MIN_SAFE_INTEGER;
43245
- let bottom = Number.MIN_SAFE_INTEGER;
43246
- const mbrs = this.children.flatMap((childId) => {
43247
- const item = this.board.items.getById(childId);
43248
- if (!item) {
43249
- return [];
43250
- }
43251
- const mbr2 = item.getMbr();
43252
- if (!mbr2) {
43253
- return [];
43254
- }
43255
- if (left > mbr2.left) {
43256
- left = mbr2.left;
43257
- }
43258
- if (top > mbr2.top) {
43259
- top = mbr2.top;
43260
- }
43261
- if (right < mbr2.right) {
43262
- right = mbr2.right;
43263
- }
43264
- if (bottom < mbr2.bottom) {
43265
- bottom = mbr2.bottom;
43266
- }
43267
- return [mbr2];
43268
- });
43269
- if (mbrs.length) {
43270
- mbr.combine(mbrs);
43271
- mbr.left = left !== Number.MAX_SAFE_INTEGER ? left : 0;
43272
- mbr.top = top !== Number.MAX_SAFE_INTEGER ? top : 0;
43273
- mbr.right = right !== Number.MIN_SAFE_INTEGER ? right : 0;
43274
- mbr.bottom = bottom !== Number.MIN_SAFE_INTEGER ? bottom : 0;
43275
- this.left = mbr.left;
43276
- this.bottom = mbr.bottom;
43277
- this.right = mbr.right;
43278
- this.top = mbr.top;
43279
- }
43280
- return mbr;
43281
- }
43282
- getChildrenIds() {
43283
- return this.children;
43284
- }
43285
- getChildren() {
43286
- return this.children.map((itemId) => this.board.items.getById(itemId)).filter((item) => item !== undefined);
43287
- }
43288
- updateMbr() {
43289
- const rect = this.getMbr();
43290
- this.mbr = rect;
43291
- this.mbr.borderColor = "transparent";
43292
- }
43293
- setBoard(board) {
43294
- this.board = board;
43295
- }
43296
- setChildren(items) {
43297
- items.forEach((itemId) => {
43298
- this.addChild(itemId);
43299
- const item = this.board.items.getById(itemId);
43300
- if (item) {
43301
- item.parent = this.getId();
43302
- }
43303
- });
43304
- this.updateMbr();
43305
- }
43306
- removeChildren() {
43307
- this.children.forEach((itemId) => {
43308
- this.removeChild(itemId);
43309
- const item = this.board.items.getById(itemId);
43310
- if (item) {
43311
- item.parent = this.parent;
43312
- }
43313
- });
43314
- this.updateMbr();
43315
- }
43316
- getLinkTo() {
43317
- return this.linkTo.link;
43318
43425
  }
43319
43426
  render(context) {
43320
43427
  if (this.transformationRenderBlock) {
43321
43428
  return;
43322
43429
  }
43323
- this.mbr.render(context);
43430
+ const ctx = context.ctx;
43431
+ ctx.save();
43432
+ this.transformation.applyToContext(ctx);
43433
+ for (const child of this.index.list()) {
43434
+ child.render(context);
43435
+ }
43436
+ ctx.restore();
43324
43437
  }
43325
43438
  renderHTML(documentFactory) {
43326
43439
  return documentFactory.createElement("div");
@@ -46037,13 +46150,13 @@ class AlignmentHelper {
46037
46150
  return baseThickness / (zoom / 100);
46038
46151
  }
46039
46152
  combineMBRs(items) {
46153
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
46040
46154
  return items.reduce((acc, item, i) => {
46041
46155
  if (i === 0) {
46042
46156
  return acc;
46043
46157
  }
46044
- const itemMbr = item.getPathMbr();
46045
- return acc.combine(itemMbr);
46046
- }, items[0].getMbr());
46158
+ return acc.combine(worldMbr(item));
46159
+ }, worldMbr(items[0]));
46047
46160
  }
46048
46161
  checkAlignment(movingItem, excludeItems = []) {
46049
46162
  if (!Array.isArray(movingItem) && movingItem.itemType === "Comment") {
@@ -51737,8 +51850,9 @@ class SelectionItems {
51737
51850
  if (items.length === 0) {
51738
51851
  return;
51739
51852
  }
51740
- const mbr = items[0].getMbr();
51741
- items.slice(1).forEach((item) => mbr.combine(item.getMbr()));
51853
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
51854
+ const mbr = worldMbr(items[0]);
51855
+ items.slice(1).forEach((item) => mbr.combine(worldMbr(item)));
51742
51856
  return mbr;
51743
51857
  }
51744
51858
  }
@@ -51947,18 +52061,27 @@ function handleMultipleItemsResize({
51947
52061
  }) {
51948
52062
  const { matrix } = resize;
51949
52063
  const result = [];
51950
- const items = itemsToResize ? itemsToResize : board.selection.items.list();
52064
+ const rawItems = itemsToResize ? itemsToResize : board.selection.items.list();
51951
52065
  board.items.getComments().forEach((comment2) => {
51952
- if (items.some((item) => item.getId() === comment2.getItemToFollow())) {
51953
- items.push(comment2);
52066
+ if (rawItems.some((item) => item.getId() === comment2.getItemToFollow())) {
52067
+ rawItems.push(comment2);
51954
52068
  }
51955
52069
  });
52070
+ const selectedIds = new Set(rawItems.map((i) => i.getId()));
52071
+ const items = rawItems.filter((item) => item.parent === "Board" || !selectedIds.has(item.parent));
51956
52072
  for (const item of items) {
51957
- let itemX = item.getMbr().left;
51958
- let itemY = item.getMbr().top;
52073
+ const worldMbr = item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
52074
+ let itemX = worldMbr.left;
52075
+ let itemY = worldMbr.top;
51959
52076
  if (item.itemType === "Drawing") {
51960
- itemX = item.transformation.getMatrixData().translateX;
51961
- itemY = item.transformation.getMatrixData().translateY;
52077
+ if (item instanceof BaseItem && item.parent !== "Board") {
52078
+ const worldMatrix = item.getWorldMatrix();
52079
+ itemX = worldMatrix.translateX;
52080
+ itemY = worldMatrix.translateY;
52081
+ } else {
52082
+ itemX = item.transformation.getMatrixData().translateX;
52083
+ itemY = item.transformation.getMatrixData().translateY;
52084
+ }
51962
52085
  }
51963
52086
  const deltaX = itemX - initMbr.left;
51964
52087
  const translateX = deltaX * matrix.scaleX - deltaX + matrix.translateX;
@@ -52882,10 +53005,6 @@ class BoardSelection {
52882
53005
  if (!this.board.events) {
52883
53006
  return;
52884
53007
  }
52885
- if (operation.method === "transformMany") {
52886
- console.error("[DEBUG] transformMany emitted!", JSON.stringify(operation));
52887
- console.trace("[DEBUG] transformMany stack trace");
52888
- }
52889
53008
  const command = createCommand(this.board, operation);
52890
53009
  command.apply();
52891
53010
  this.board.events.emit(operation, command);
@@ -53428,17 +53547,12 @@ class BoardSelection {
53428
53547
  const addItem = (itemId) => {
53429
53548
  items.push({ id: itemId, matrix: { translateX: x, translateY: y, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } });
53430
53549
  };
53431
- const tryToAddFrameChildren = (selectedItem) => {
53432
- if (!("index" in selectedItem) || !selectedItem.index) {
53550
+ const selectedIds = new Set(unselectedItem ? [unselectedItem.getId()] : this.board.selection.list().map((i) => i.getId()));
53551
+ const addWithComments = (item) => {
53552
+ if (item.parent !== "Board" && selectedIds.has(item.parent)) {
53433
53553
  return;
53434
53554
  }
53435
- for (const childId of selectedItem.getChildrenIds()) {
53436
- addItem(childId);
53437
- }
53438
- };
53439
- const addWithComments = (item) => {
53440
53555
  addItem(item.getId());
53441
- tryToAddFrameChildren(item);
53442
53556
  const followedComments = this.board.items.getComments().filter((comment2) => comment2.getItemToFollow() === item.getId());
53443
53557
  for (const comment2 of followedComments) {
53444
53558
  addItem(comment2.getId());
@@ -54270,6 +54384,28 @@ class Board {
54270
54384
  item: [item.getId()]
54271
54385
  });
54272
54386
  }
54387
+ group(items) {
54388
+ const id = this.getNewItemId();
54389
+ const groupData = {
54390
+ itemType: "Group",
54391
+ children: items.map((i) => i.getId()),
54392
+ transformation: { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 }
54393
+ };
54394
+ this.emit({
54395
+ class: "Board",
54396
+ method: "addLockedGroup",
54397
+ item: id,
54398
+ data: groupData
54399
+ });
54400
+ return this.items.getById(id);
54401
+ }
54402
+ ungroup(group) {
54403
+ this.emit({
54404
+ class: "Board",
54405
+ method: "removeLockedGroup",
54406
+ item: [group.getId()]
54407
+ });
54408
+ }
54273
54409
  getByZIndex(index2) {
54274
54410
  return this.index.getByZIndex(index2);
54275
54411
  }