microboard-temp 0.10.1 → 0.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/esm/index.js CHANGED
@@ -1043,6 +1043,24 @@ class Matrix {
1043
1043
  const { translateX, translateY, scaleX, scaleY, shearX, shearY } = matrix;
1044
1044
  return this.translateX === translateX && this.translateY === translateY && this.scaleX === scaleX && this.scaleY === scaleY && this.shearX === shearX && this.shearY === shearY;
1045
1045
  }
1046
+ composeWith(parent) {
1047
+ const result = parent.copy();
1048
+ result.multiplyByMatrix(this);
1049
+ return result;
1050
+ }
1051
+ toLocalOf(parent) {
1052
+ const result = parent.getInverse();
1053
+ result.multiplyByMatrix(this);
1054
+ return result;
1055
+ }
1056
+ applyInverseLinear(dx, dy) {
1057
+ const { scaleX, scaleY, shearX, shearY } = this;
1058
+ const denom = scaleX * scaleY - shearX * shearY;
1059
+ return {
1060
+ x: (scaleY * dx - shearX * dy) / denom,
1061
+ y: (-shearY * dx + scaleX * dy) / denom
1062
+ };
1063
+ }
1046
1064
  }
1047
1065
 
1048
1066
  // src/Subject.ts
@@ -17788,6 +17806,15 @@ class Transformation {
17788
17806
  getRotation() {
17789
17807
  return this.rotate;
17790
17808
  }
17809
+ setLocalMatrix(matrix) {
17810
+ this.previous = this._matrix.copy();
17811
+ this._matrix = matrix.copy();
17812
+ this.subject.publish(this, {
17813
+ class: "Transformation",
17814
+ method: "applyMatrix",
17815
+ items: [{ id: this.id, matrix: this.getMatrixData() }]
17816
+ });
17817
+ }
17791
17818
  setLocal(xOrData, y, scaleX, scaleY) {
17792
17819
  this.previous = this._matrix.copy();
17793
17820
  if (typeof xOrData === "object") {
@@ -20710,6 +20737,24 @@ class LayeredIndex {
20710
20737
  }
20711
20738
 
20712
20739
  // src/SpatialIndex/SpacialIndex.ts
20740
+ function worldBoundsToLocal(container, left, top, right, bottom) {
20741
+ const inv = container.getWorldMatrix().getInverse();
20742
+ const corners = [
20743
+ new Point(left, top),
20744
+ new Point(right, top),
20745
+ new Point(right, bottom),
20746
+ new Point(left, bottom)
20747
+ ];
20748
+ for (const c of corners)
20749
+ inv.apply(c);
20750
+ return {
20751
+ left: Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20752
+ top: Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y),
20753
+ right: Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20754
+ bottom: Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y)
20755
+ };
20756
+ }
20757
+
20713
20758
  class SpatialIndex {
20714
20759
  subject = new Subject;
20715
20760
  itemsArray = [];
@@ -20761,6 +20806,8 @@ class SpatialIndex {
20761
20806
  if (item.parent !== "Board") {
20762
20807
  const parentFrame = this.items.getById(item.parent);
20763
20808
  parentFrame?.removeChildItems(item);
20809
+ this.subject.publish(this.items);
20810
+ return;
20764
20811
  }
20765
20812
  this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
20766
20813
  this.itemsIndex.remove(item);
@@ -20775,10 +20822,20 @@ class SpatialIndex {
20775
20822
  this.subject.publish(this.items);
20776
20823
  }
20777
20824
  copy() {
20778
- return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => ({
20779
- ...item.serialize(true),
20780
- id: item.getId()
20781
- }));
20825
+ return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => {
20826
+ const serialized = { ...item.serialize(true), id: item.getId() };
20827
+ if (item.parent !== "Board" && item.getWorldMatrix) {
20828
+ const worldMatrix = item.getWorldMatrix();
20829
+ serialized.transformation = {
20830
+ ...serialized.transformation,
20831
+ translateX: worldMatrix.translateX,
20832
+ translateY: worldMatrix.translateY,
20833
+ scaleX: worldMatrix.scaleX,
20834
+ scaleY: worldMatrix.scaleY
20835
+ };
20836
+ }
20837
+ return serialized;
20838
+ });
20782
20839
  }
20783
20840
  getItemsWithIncludedChildren(items) {
20784
20841
  return items.flatMap((item) => {
@@ -20944,7 +21001,8 @@ class SpatialIndex {
20944
21001
  const children = [];
20945
21002
  const clearItems = items.filter((item) => {
20946
21003
  if ("index" in item && item.index) {
20947
- children.push(...item.index.getEnclosed(left, top, right, bottom));
21004
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21005
+ children.push(...item.index.getEnclosed(local.left, local.top, local.right, local.bottom));
20948
21006
  if (!item.getMbr().isEnclosedBy(mbr)) {
20949
21007
  return false;
20950
21008
  }
@@ -20959,7 +21017,8 @@ class SpatialIndex {
20959
21017
  const children = [];
20960
21018
  const clearItems = items.filter((item) => {
20961
21019
  if ("index" in item && item.index) {
20962
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21020
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21021
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
20963
21022
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
20964
21023
  return false;
20965
21024
  }
@@ -20973,7 +21032,9 @@ class SpatialIndex {
20973
21032
  const children = [];
20974
21033
  const clearItems = items.filter((item) => {
20975
21034
  if ("index" in item && item.index) {
20976
- children.push(...item.index.getUnderPoint(point3, tolerance));
21035
+ const localPt = new Point(point3.x, point3.y);
21036
+ item.getWorldMatrix().getInverse().apply(localPt);
21037
+ children.push(...item.index.getUnderPoint(localPt, tolerance));
20977
21038
  if (!item.getMbr().isUnderPoint(point3)) {
20978
21039
  return false;
20979
21040
  }
@@ -20988,7 +21049,8 @@ class SpatialIndex {
20988
21049
  const children = [];
20989
21050
  const clearItems = items.filter((item) => {
20990
21051
  if ("index" in item && item.index) {
20991
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21052
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21053
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
20992
21054
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
20993
21055
  return false;
20994
21056
  }
@@ -21451,6 +21513,49 @@ class SimpleSpatialIndex {
21451
21513
  }
21452
21514
 
21453
21515
  // src/Items/BaseItem/BaseItem.ts
21516
+ function toLocalTransformOp(op, containerMatrix, itemId) {
21517
+ switch (op.method) {
21518
+ case "applyMatrix": {
21519
+ const converted = op.items.map((item) => {
21520
+ const local = containerMatrix.applyInverseLinear(item.matrix.translateX, item.matrix.translateY);
21521
+ return { ...item, matrix: { ...item.matrix, translateX: local.x, translateY: local.y } };
21522
+ });
21523
+ return { ...op, items: converted };
21524
+ }
21525
+ case "translateBy": {
21526
+ const local = containerMatrix.applyInverseLinear(op.x, op.y);
21527
+ return { ...op, x: local.x, y: local.y };
21528
+ }
21529
+ case "translateTo": {
21530
+ const pt = new Point(op.x, op.y);
21531
+ containerMatrix.getInverse().apply(pt);
21532
+ return { ...op, x: pt.x, y: pt.y };
21533
+ }
21534
+ case "scaleTo": {
21535
+ return { ...op, x: op.x / containerMatrix.scaleX, y: op.y / containerMatrix.scaleY };
21536
+ }
21537
+ case "scaleByTranslateBy": {
21538
+ const local = containerMatrix.applyInverseLinear(op.translate.x, op.translate.y);
21539
+ return { ...op, translate: { x: local.x, y: local.y } };
21540
+ }
21541
+ case "scaleByRelativeTo":
21542
+ case "scaleToRelativeTo": {
21543
+ const pt = new Point(op.point.x, op.point.y);
21544
+ containerMatrix.getInverse().apply(pt);
21545
+ return { ...op, point: pt };
21546
+ }
21547
+ case "transformMany": {
21548
+ if (!itemId || !op.items[itemId])
21549
+ return op;
21550
+ const subOp = op.items[itemId];
21551
+ const localSubOp = toLocalTransformOp(subOp, containerMatrix);
21552
+ return { ...op, items: { ...op.items, [itemId]: localSubOp } };
21553
+ }
21554
+ default:
21555
+ return op;
21556
+ }
21557
+ }
21558
+
21454
21559
  class BaseItem extends Mbr {
21455
21560
  defaultItemData;
21456
21561
  transformation;
@@ -21495,6 +21600,16 @@ class BaseItem extends Mbr {
21495
21600
  getId() {
21496
21601
  return this.id;
21497
21602
  }
21603
+ getWorldMatrix() {
21604
+ if (this.parent === "Board") {
21605
+ return this.transformation.toMatrix();
21606
+ }
21607
+ const container = this.board.items.getById(this.parent);
21608
+ if (!container) {
21609
+ return this.transformation.toMatrix();
21610
+ }
21611
+ return this.transformation.toMatrix().composeWith(container.getWorldMatrix());
21612
+ }
21498
21613
  setId(id) {
21499
21614
  this.id = id;
21500
21615
  this.transformation.setId(id);
@@ -21569,16 +21684,35 @@ class BaseItem extends Mbr {
21569
21684
  getMbr() {
21570
21685
  return new Mbr(this.left, this.top, this.right, this.bottom);
21571
21686
  }
21687
+ getWorldMbr() {
21688
+ if (this.parent === "Board" || !this.parent || !this.board?.items) {
21689
+ return this.getMbr();
21690
+ }
21691
+ const worldMatrix = this.getWorldMatrix();
21692
+ const local = this.getMbr();
21693
+ const corners = [
21694
+ new Point(local.left, local.top),
21695
+ new Point(local.right, local.top),
21696
+ new Point(local.right, local.bottom),
21697
+ new Point(local.left, local.bottom)
21698
+ ];
21699
+ for (const c of corners)
21700
+ worldMatrix.apply(c);
21701
+ 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));
21702
+ }
21572
21703
  applyAddChildren(childIds) {
21573
21704
  if (!this.index) {
21574
21705
  return;
21575
21706
  }
21707
+ const containerWorldMatrix = this.getWorldMatrix();
21576
21708
  childIds.forEach((childId) => {
21577
21709
  const foundItem = this.board.items.getById(childId);
21578
21710
  if (this.parent !== childId && this.getId() !== childId) {
21579
21711
  if (!this.index?.getById(childId) && foundItem) {
21712
+ const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerWorldMatrix);
21580
21713
  this.board.items.index.remove(foundItem);
21581
21714
  foundItem.parent = this.getId();
21715
+ foundItem.transformation.setLocalMatrix(localMatrix);
21582
21716
  this.index?.insert(foundItem);
21583
21717
  }
21584
21718
  }
@@ -21591,12 +21725,15 @@ class BaseItem extends Mbr {
21591
21725
  if (!this.index) {
21592
21726
  return;
21593
21727
  }
21728
+ const containerWorldMatrix = this.getWorldMatrix();
21594
21729
  childIds.forEach((childId) => {
21595
21730
  const foundItem = this.index?.getById(childId);
21596
21731
  if (this.parent !== childId && this.getId() !== childId) {
21597
21732
  if (foundItem) {
21733
+ const worldMatrix = foundItem.transformation.toMatrix().composeWith(containerWorldMatrix);
21598
21734
  this.index?.remove(foundItem);
21599
21735
  foundItem.parent = "Board";
21736
+ foundItem.transformation.setLocalMatrix(worldMatrix);
21600
21737
  this.board.items.index.insert(foundItem);
21601
21738
  }
21602
21739
  }
@@ -21708,9 +21845,17 @@ class BaseItem extends Mbr {
21708
21845
  apply(op) {
21709
21846
  op = op;
21710
21847
  switch (op.class) {
21711
- case "Transformation":
21712
- this.transformation.apply(op);
21848
+ case "Transformation": {
21849
+ let transformOp = op;
21850
+ if (this.parent !== "Board") {
21851
+ const container = this.board.items.getById(this.parent);
21852
+ if (container?.transformation) {
21853
+ transformOp = toLocalTransformOp(transformOp, container.getWorldMatrix(), this.id);
21854
+ }
21855
+ }
21856
+ this.transformation.apply(transformOp);
21713
21857
  break;
21858
+ }
21714
21859
  case "LinkTo":
21715
21860
  this.linkTo.apply(op);
21716
21861
  break;
@@ -36515,14 +36660,20 @@ function getControlPoint(data, findItem2) {
36515
36660
  }
36516
36661
  }
36517
36662
  }
36663
+ function getItemWorldMatrix(item) {
36664
+ if (item instanceof BaseItem && item.parent !== "Board") {
36665
+ return item.getWorldMatrix();
36666
+ }
36667
+ return item.transformation?.toMatrix() ?? new Matrix;
36668
+ }
36518
36669
  function toRelativePoint(point5, item) {
36519
- const inverse = item.transformation ? item.transformation.getInverse().toMatrix() : new Matrix;
36670
+ const inverse = getItemWorldMatrix(item).getInverse();
36520
36671
  point5 = point5.copy();
36521
36672
  point5.transform(inverse);
36522
36673
  return point5;
36523
36674
  }
36524
36675
  function fromRelativePoint(relativePoint, item, edge) {
36525
- const matrix = item.transformation?.toMatrix() ?? new Matrix;
36676
+ const matrix = getItemWorldMatrix(item);
36526
36677
  const point5 = relativePoint.copy();
36527
36678
  point5.transform(matrix);
36528
36679
  if (item instanceof RichText || item instanceof AINode) {
@@ -40997,7 +41148,13 @@ class Frame2 extends BaseItem {
40997
41148
  return;
40998
41149
  }
40999
41150
  this.renderPath(context);
41000
- super.render(context);
41151
+ const ctx = context.ctx;
41152
+ ctx.save();
41153
+ this.transformation.applyToContext(ctx);
41154
+ for (const child of this.index.list()) {
41155
+ child.render(context);
41156
+ }
41157
+ ctx.restore();
41001
41158
  this.renderBorders(context);
41002
41159
  this.renderName(context);
41003
41160
  }
@@ -43105,25 +43262,24 @@ function douglasPeucker(points, epsilon2) {
43105
43262
  // src/Items/Group/Group.ts
43106
43263
  class Group extends BaseItem {
43107
43264
  events;
43108
- children;
43109
43265
  linkTo;
43110
43266
  itemType = "Group";
43111
43267
  parent = "Board";
43112
43268
  transformation;
43113
43269
  subject = new Subject;
43114
- mbr = new Mbr;
43115
43270
  transformationRenderBlock = undefined;
43116
43271
  constructor(board, events, children = [], id = "") {
43117
- super(board, id);
43272
+ super(board, id, undefined, true);
43118
43273
  this.events = events;
43119
- this.children = children;
43120
43274
  this.linkTo = new LinkTo(this.id, this.events);
43121
43275
  this.transformation = new Transformation(this.id, this.events);
43122
- this.children = children;
43123
43276
  this.transformation.subject.subscribe(() => {
43124
43277
  this.updateMbr();
43125
43278
  this.subject.publish(this);
43126
43279
  });
43280
+ if (children.length > 0) {
43281
+ this.applyAddChildren(children);
43282
+ }
43127
43283
  }
43128
43284
  isClosed() {
43129
43285
  return false;
@@ -43131,45 +43287,17 @@ class Group extends BaseItem {
43131
43287
  getRichText() {
43132
43288
  return null;
43133
43289
  }
43134
- addChild(childId) {
43135
- this.emit({
43136
- class: "Group",
43137
- method: "addChild",
43138
- item: [this.getId()],
43139
- childId
43140
- });
43141
- }
43142
- applyAddChild(childId) {
43143
- if (!this.children.includes(childId)) {
43144
- this.children.push(childId);
43145
- this.updateMbr();
43146
- this.subject.publish(this);
43147
- }
43148
- }
43149
- applyRemoveChild(childId) {
43150
- this.children = this.children.filter((currChild) => currChild !== childId);
43151
- this.updateMbr();
43152
- this.subject.publish(this);
43153
- }
43154
- removeChild(childId) {
43155
- this.emit({
43156
- class: "Group",
43157
- method: "removeChild",
43158
- item: [this.getId()],
43159
- childId
43160
- });
43161
- }
43162
- emitRemoveChild(child) {
43163
- this.removeChild(child.getId());
43164
- child.parent = "Board";
43165
- }
43166
43290
  apply(op) {
43167
43291
  switch (op.class) {
43168
43292
  case "Group":
43169
43293
  if (op.method === "addChild") {
43170
- this.applyAddChild(op.childId);
43294
+ this.applyAddChildren([op.childId]);
43171
43295
  } else if (op.method === "removeChild") {
43172
- this.applyRemoveChild(op.childId);
43296
+ this.applyRemoveChildren([op.childId]);
43297
+ } else if (op.method === "addChildren") {
43298
+ this.applyAddChildren(op.newData.childIds);
43299
+ } else if (op.method === "removeChildren") {
43300
+ this.applyRemoveChildren(op.newData.childIds);
43173
43301
  }
43174
43302
  break;
43175
43303
  case "Transformation":
@@ -43194,24 +43322,69 @@ class Group extends BaseItem {
43194
43322
  this.transformation.setId(id);
43195
43323
  return this;
43196
43324
  }
43325
+ getMbr() {
43326
+ const children = this.index.list();
43327
+ if (children.length === 0) {
43328
+ return new Mbr(this.left, this.top, this.right, this.bottom);
43329
+ }
43330
+ const groupWorldMatrix = this.getWorldMatrix();
43331
+ let left = Number.MAX_SAFE_INTEGER;
43332
+ let top = Number.MAX_SAFE_INTEGER;
43333
+ let right = Number.MIN_SAFE_INTEGER;
43334
+ let bottom = Number.MIN_SAFE_INTEGER;
43335
+ for (const child of children) {
43336
+ const childLocalMbr = child.getMbr();
43337
+ const corners = [
43338
+ { x: childLocalMbr.left, y: childLocalMbr.top },
43339
+ { x: childLocalMbr.right, y: childLocalMbr.top },
43340
+ { x: childLocalMbr.right, y: childLocalMbr.bottom },
43341
+ { x: childLocalMbr.left, y: childLocalMbr.bottom }
43342
+ ];
43343
+ for (const corner of corners) {
43344
+ groupWorldMatrix.apply(corner);
43345
+ if (corner.x < left)
43346
+ left = corner.x;
43347
+ if (corner.y < top)
43348
+ top = corner.y;
43349
+ if (corner.x > right)
43350
+ right = corner.x;
43351
+ if (corner.y > bottom)
43352
+ bottom = corner.y;
43353
+ }
43354
+ }
43355
+ const mbr = new Mbr(left, top, right, bottom);
43356
+ this.left = left;
43357
+ this.top = top;
43358
+ this.right = right;
43359
+ this.bottom = bottom;
43360
+ return mbr;
43361
+ }
43362
+ updateMbr() {
43363
+ this.getMbr();
43364
+ }
43365
+ getChildrenIds() {
43366
+ return this.index.list().map((item) => item.getId());
43367
+ }
43368
+ getChildren() {
43369
+ return this.index.list();
43370
+ }
43371
+ getLinkTo() {
43372
+ return this.linkTo.link;
43373
+ }
43197
43374
  serialize() {
43198
43375
  return {
43199
43376
  itemType: "Group",
43200
- children: this.children,
43377
+ children: this.getChildrenIds(),
43201
43378
  transformation: this.transformation.serialize()
43202
43379
  };
43203
43380
  }
43204
43381
  deserialize(data) {
43205
- if (data.children) {
43206
- data.children.forEach((childId) => {
43207
- this.applyAddChild(childId);
43208
- const item = this.board.items.getById(childId);
43209
- if (item) {
43210
- item.parent = this.getId();
43211
- }
43212
- });
43382
+ if (data.transformation) {
43383
+ this.transformation.deserialize(data.transformation);
43384
+ }
43385
+ if (data.children && data.children.length > 0) {
43386
+ this.applyAddChildren(data.children);
43213
43387
  }
43214
- this.transformation.deserialize(data.transformation);
43215
43388
  this.subject.publish(this);
43216
43389
  return this;
43217
43390
  }
@@ -43221,99 +43394,25 @@ class Group extends BaseItem {
43221
43394
  getIntersectionPoints(segment) {
43222
43395
  const lines = this.getMbr().getLines();
43223
43396
  const initPoints = [];
43224
- const points = lines.reduce((acc, line) => {
43397
+ return lines.reduce((acc, line) => {
43225
43398
  const intersections = line.getIntersectionPoints(segment);
43226
43399
  if (intersections.length > 0) {
43227
43400
  acc.push(...intersections);
43228
43401
  }
43229
43402
  return acc;
43230
43403
  }, initPoints);
43231
- return points;
43232
- }
43233
- getMbr() {
43234
- const mbr = new Mbr;
43235
- let left = Number.MAX_SAFE_INTEGER;
43236
- let top = Number.MAX_SAFE_INTEGER;
43237
- let right = Number.MIN_SAFE_INTEGER;
43238
- let bottom = Number.MIN_SAFE_INTEGER;
43239
- const mbrs = this.children.flatMap((childId) => {
43240
- const item = this.board.items.getById(childId);
43241
- if (!item) {
43242
- return [];
43243
- }
43244
- const mbr2 = item.getMbr();
43245
- if (!mbr2) {
43246
- return [];
43247
- }
43248
- if (left > mbr2.left) {
43249
- left = mbr2.left;
43250
- }
43251
- if (top > mbr2.top) {
43252
- top = mbr2.top;
43253
- }
43254
- if (right < mbr2.right) {
43255
- right = mbr2.right;
43256
- }
43257
- if (bottom < mbr2.bottom) {
43258
- bottom = mbr2.bottom;
43259
- }
43260
- return [mbr2];
43261
- });
43262
- if (mbrs.length) {
43263
- mbr.combine(mbrs);
43264
- mbr.left = left !== Number.MAX_SAFE_INTEGER ? left : 0;
43265
- mbr.top = top !== Number.MAX_SAFE_INTEGER ? top : 0;
43266
- mbr.right = right !== Number.MIN_SAFE_INTEGER ? right : 0;
43267
- mbr.bottom = bottom !== Number.MIN_SAFE_INTEGER ? bottom : 0;
43268
- this.left = mbr.left;
43269
- this.bottom = mbr.bottom;
43270
- this.right = mbr.right;
43271
- this.top = mbr.top;
43272
- }
43273
- return mbr;
43274
- }
43275
- getChildrenIds() {
43276
- return this.children;
43277
- }
43278
- getChildren() {
43279
- return this.children.map((itemId) => this.board.items.getById(itemId)).filter((item) => item !== undefined);
43280
- }
43281
- updateMbr() {
43282
- const rect = this.getMbr();
43283
- this.mbr = rect;
43284
- this.mbr.borderColor = "transparent";
43285
- }
43286
- setBoard(board) {
43287
- this.board = board;
43288
- }
43289
- setChildren(items) {
43290
- items.forEach((itemId) => {
43291
- this.addChild(itemId);
43292
- const item = this.board.items.getById(itemId);
43293
- if (item) {
43294
- item.parent = this.getId();
43295
- }
43296
- });
43297
- this.updateMbr();
43298
- }
43299
- removeChildren() {
43300
- this.children.forEach((itemId) => {
43301
- this.removeChild(itemId);
43302
- const item = this.board.items.getById(itemId);
43303
- if (item) {
43304
- item.parent = this.parent;
43305
- }
43306
- });
43307
- this.updateMbr();
43308
- }
43309
- getLinkTo() {
43310
- return this.linkTo.link;
43311
43404
  }
43312
43405
  render(context) {
43313
43406
  if (this.transformationRenderBlock) {
43314
43407
  return;
43315
43408
  }
43316
- this.mbr.render(context);
43409
+ const ctx = context.ctx;
43410
+ ctx.save();
43411
+ this.transformation.applyToContext(ctx);
43412
+ for (const child of this.index.list()) {
43413
+ child.render(context);
43414
+ }
43415
+ ctx.restore();
43317
43416
  }
43318
43417
  renderHTML(documentFactory) {
43319
43418
  return documentFactory.createElement("div");
@@ -43745,7 +43844,7 @@ class ConnectorSnap {
43745
43844
  }
43746
43845
  }
43747
43846
  getNearest() {
43748
- const neighbors = this.board.items.getNearPointer(this.distance.neighbor / this.board.camera.getScale(), this.maxNeighbors);
43847
+ const neighbors = this.board.items.getNearPointer(this.distance.border / this.board.camera.getScale(), this.maxNeighbors);
43749
43848
  const pointer = this.board.pointer.point;
43750
43849
  let nearest = null;
43751
43850
  let nearestDistance = Number.MAX_VALUE;
@@ -46030,13 +46129,13 @@ class AlignmentHelper {
46030
46129
  return baseThickness / (zoom / 100);
46031
46130
  }
46032
46131
  combineMBRs(items) {
46132
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
46033
46133
  return items.reduce((acc, item, i) => {
46034
46134
  if (i === 0) {
46035
46135
  return acc;
46036
46136
  }
46037
- const itemMbr = item.getPathMbr();
46038
- return acc.combine(itemMbr);
46039
- }, items[0].getMbr());
46137
+ return acc.combine(worldMbr(item));
46138
+ }, worldMbr(items[0]));
46040
46139
  }
46041
46140
  checkAlignment(movingItem, excludeItems = []) {
46042
46141
  if (!Array.isArray(movingItem) && movingItem.itemType === "Comment") {
@@ -51730,8 +51829,9 @@ class SelectionItems {
51730
51829
  if (items.length === 0) {
51731
51830
  return;
51732
51831
  }
51733
- const mbr = items[0].getMbr();
51734
- items.slice(1).forEach((item) => mbr.combine(item.getMbr()));
51832
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
51833
+ const mbr = worldMbr(items[0]);
51834
+ items.slice(1).forEach((item) => mbr.combine(worldMbr(item)));
51735
51835
  return mbr;
51736
51836
  }
51737
51837
  }
@@ -51940,18 +52040,27 @@ function handleMultipleItemsResize({
51940
52040
  }) {
51941
52041
  const { matrix } = resize;
51942
52042
  const result = [];
51943
- const items = itemsToResize ? itemsToResize : board.selection.items.list();
52043
+ const rawItems = itemsToResize ? itemsToResize : board.selection.items.list();
51944
52044
  board.items.getComments().forEach((comment2) => {
51945
- if (items.some((item) => item.getId() === comment2.getItemToFollow())) {
51946
- items.push(comment2);
52045
+ if (rawItems.some((item) => item.getId() === comment2.getItemToFollow())) {
52046
+ rawItems.push(comment2);
51947
52047
  }
51948
52048
  });
52049
+ const selectedIds = new Set(rawItems.map((i) => i.getId()));
52050
+ const items = rawItems.filter((item) => item.parent === "Board" || !selectedIds.has(item.parent));
51949
52051
  for (const item of items) {
51950
- let itemX = item.getMbr().left;
51951
- let itemY = item.getMbr().top;
52052
+ const worldMbr = item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
52053
+ let itemX = worldMbr.left;
52054
+ let itemY = worldMbr.top;
51952
52055
  if (item.itemType === "Drawing") {
51953
- itemX = item.transformation.getMatrixData().translateX;
51954
- itemY = item.transformation.getMatrixData().translateY;
52056
+ if (item instanceof BaseItem && item.parent !== "Board") {
52057
+ const worldMatrix = item.getWorldMatrix();
52058
+ itemX = worldMatrix.translateX;
52059
+ itemY = worldMatrix.translateY;
52060
+ } else {
52061
+ itemX = item.transformation.getMatrixData().translateX;
52062
+ itemY = item.transformation.getMatrixData().translateY;
52063
+ }
51955
52064
  }
51956
52065
  const deltaX = itemX - initMbr.left;
51957
52066
  const translateX = deltaX * matrix.scaleX - deltaX + matrix.translateX;
@@ -52875,10 +52984,6 @@ class BoardSelection {
52875
52984
  if (!this.board.events) {
52876
52985
  return;
52877
52986
  }
52878
- if (operation.method === "transformMany") {
52879
- console.error("[DEBUG] transformMany emitted!", JSON.stringify(operation));
52880
- console.trace("[DEBUG] transformMany stack trace");
52881
- }
52882
52987
  const command = createCommand(this.board, operation);
52883
52988
  command.apply();
52884
52989
  this.board.events.emit(operation, command);
@@ -53421,17 +53526,12 @@ class BoardSelection {
53421
53526
  const addItem = (itemId) => {
53422
53527
  items.push({ id: itemId, matrix: { translateX: x, translateY: y, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } });
53423
53528
  };
53424
- const tryToAddFrameChildren = (selectedItem) => {
53425
- if (!("index" in selectedItem) || !selectedItem.index) {
53529
+ const selectedIds = new Set(unselectedItem ? [unselectedItem.getId()] : this.board.selection.list().map((i) => i.getId()));
53530
+ const addWithComments = (item) => {
53531
+ if (item.parent !== "Board" && selectedIds.has(item.parent)) {
53426
53532
  return;
53427
53533
  }
53428
- for (const childId of selectedItem.getChildrenIds()) {
53429
- addItem(childId);
53430
- }
53431
- };
53432
- const addWithComments = (item) => {
53433
53534
  addItem(item.getId());
53434
- tryToAddFrameChildren(item);
53435
53535
  const followedComments = this.board.items.getComments().filter((comment2) => comment2.getItemToFollow() === item.getId());
53436
53536
  for (const comment2 of followedComments) {
53437
53537
  addItem(comment2.getId());
@@ -54263,6 +54363,28 @@ class Board {
54263
54363
  item: [item.getId()]
54264
54364
  });
54265
54365
  }
54366
+ group(items) {
54367
+ const id = this.getNewItemId();
54368
+ const groupData = {
54369
+ itemType: "Group",
54370
+ children: items.map((i) => i.getId()),
54371
+ transformation: { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 }
54372
+ };
54373
+ this.emit({
54374
+ class: "Board",
54375
+ method: "addLockedGroup",
54376
+ item: id,
54377
+ data: groupData
54378
+ });
54379
+ return this.items.getById(id);
54380
+ }
54381
+ ungroup(group) {
54382
+ this.emit({
54383
+ class: "Board",
54384
+ method: "removeLockedGroup",
54385
+ item: [group.getId()]
54386
+ });
54387
+ }
54266
54388
  getByZIndex(index2) {
54267
54389
  return this.index.getByZIndex(index2);
54268
54390
  }