microboard-temp 0.10.2 → 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.
@@ -1230,6 +1230,24 @@ class Matrix {
1230
1230
  const { translateX, translateY, scaleX, scaleY, shearX, shearY } = matrix;
1231
1231
  return this.translateX === translateX && this.translateY === translateY && this.scaleX === scaleX && this.scaleY === scaleY && this.shearX === shearX && this.shearY === shearY;
1232
1232
  }
1233
+ composeWith(parent) {
1234
+ const result = parent.copy();
1235
+ result.multiplyByMatrix(this);
1236
+ return result;
1237
+ }
1238
+ toLocalOf(parent) {
1239
+ const result = parent.getInverse();
1240
+ result.multiplyByMatrix(this);
1241
+ return result;
1242
+ }
1243
+ applyInverseLinear(dx, dy) {
1244
+ const { scaleX, scaleY, shearX, shearY } = this;
1245
+ const denom = scaleX * scaleY - shearX * shearY;
1246
+ return {
1247
+ x: (scaleY * dx - shearX * dy) / denom,
1248
+ y: (-shearY * dx + scaleX * dy) / denom
1249
+ };
1250
+ }
1233
1251
  }
1234
1252
 
1235
1253
  // src/Subject.ts
@@ -17966,6 +17984,15 @@ class Transformation {
17966
17984
  getRotation() {
17967
17985
  return this.rotate;
17968
17986
  }
17987
+ setLocalMatrix(matrix) {
17988
+ this.previous = this._matrix.copy();
17989
+ this._matrix = matrix.copy();
17990
+ this.subject.publish(this, {
17991
+ class: "Transformation",
17992
+ method: "applyMatrix",
17993
+ items: [{ id: this.id, matrix: this.getMatrixData() }]
17994
+ });
17995
+ }
17969
17996
  setLocal(xOrData, y, scaleX, scaleY) {
17970
17997
  this.previous = this._matrix.copy();
17971
17998
  if (typeof xOrData === "object") {
@@ -20888,6 +20915,24 @@ class LayeredIndex {
20888
20915
  }
20889
20916
 
20890
20917
  // src/SpatialIndex/SpacialIndex.ts
20918
+ function worldBoundsToLocal(container, left, top, right, bottom) {
20919
+ const inv = container.getWorldMatrix().getInverse();
20920
+ const corners = [
20921
+ new Point(left, top),
20922
+ new Point(right, top),
20923
+ new Point(right, bottom),
20924
+ new Point(left, bottom)
20925
+ ];
20926
+ for (const c of corners)
20927
+ inv.apply(c);
20928
+ return {
20929
+ left: Math.min(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20930
+ top: Math.min(corners[0].y, corners[1].y, corners[2].y, corners[3].y),
20931
+ right: Math.max(corners[0].x, corners[1].x, corners[2].x, corners[3].x),
20932
+ bottom: Math.max(corners[0].y, corners[1].y, corners[2].y, corners[3].y)
20933
+ };
20934
+ }
20935
+
20891
20936
  class SpatialIndex {
20892
20937
  subject = new Subject;
20893
20938
  itemsArray = [];
@@ -20939,6 +20984,8 @@ class SpatialIndex {
20939
20984
  if (item.parent !== "Board") {
20940
20985
  const parentFrame = this.items.getById(item.parent);
20941
20986
  parentFrame?.removeChildItems(item);
20987
+ this.subject.publish(this.items);
20988
+ return;
20942
20989
  }
20943
20990
  this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
20944
20991
  this.itemsIndex.remove(item);
@@ -20953,10 +21000,20 @@ class SpatialIndex {
20953
21000
  this.subject.publish(this.items);
20954
21001
  }
20955
21002
  copy() {
20956
- return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => ({
20957
- ...item.serialize(true),
20958
- id: item.getId()
20959
- }));
21003
+ return this.getItemsWithIncludedChildren(this.itemsArray).map((item) => {
21004
+ const serialized = { ...item.serialize(true), id: item.getId() };
21005
+ if (item.parent !== "Board" && item.getWorldMatrix) {
21006
+ const worldMatrix = item.getWorldMatrix();
21007
+ serialized.transformation = {
21008
+ ...serialized.transformation,
21009
+ translateX: worldMatrix.translateX,
21010
+ translateY: worldMatrix.translateY,
21011
+ scaleX: worldMatrix.scaleX,
21012
+ scaleY: worldMatrix.scaleY
21013
+ };
21014
+ }
21015
+ return serialized;
21016
+ });
20960
21017
  }
20961
21018
  getItemsWithIncludedChildren(items) {
20962
21019
  return items.flatMap((item) => {
@@ -21122,7 +21179,8 @@ class SpatialIndex {
21122
21179
  const children = [];
21123
21180
  const clearItems = items.filter((item) => {
21124
21181
  if ("index" in item && item.index) {
21125
- children.push(...item.index.getEnclosed(left, top, right, bottom));
21182
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21183
+ children.push(...item.index.getEnclosed(local.left, local.top, local.right, local.bottom));
21126
21184
  if (!item.getMbr().isEnclosedBy(mbr)) {
21127
21185
  return false;
21128
21186
  }
@@ -21137,7 +21195,8 @@ class SpatialIndex {
21137
21195
  const children = [];
21138
21196
  const clearItems = items.filter((item) => {
21139
21197
  if ("index" in item && item.index) {
21140
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21198
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21199
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
21141
21200
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
21142
21201
  return false;
21143
21202
  }
@@ -21151,7 +21210,9 @@ class SpatialIndex {
21151
21210
  const children = [];
21152
21211
  const clearItems = items.filter((item) => {
21153
21212
  if ("index" in item && item.index) {
21154
- children.push(...item.index.getUnderPoint(point3, tolerance));
21213
+ const localPt = new Point(point3.x, point3.y);
21214
+ item.getWorldMatrix().getInverse().apply(localPt);
21215
+ children.push(...item.index.getUnderPoint(localPt, tolerance));
21155
21216
  if (!item.getMbr().isUnderPoint(point3)) {
21156
21217
  return false;
21157
21218
  }
@@ -21166,7 +21227,8 @@ class SpatialIndex {
21166
21227
  const children = [];
21167
21228
  const clearItems = items.filter((item) => {
21168
21229
  if ("index" in item && item.index) {
21169
- children.push(...item.index.getEnclosedOrCrossed(left, top, right, bottom));
21230
+ const local = worldBoundsToLocal(item, left, top, right, bottom);
21231
+ children.push(...item.index.getEnclosedOrCrossed(local.left, local.top, local.right, local.bottom));
21170
21232
  if (!item.getMbr().isEnclosedOrCrossedBy(mbr)) {
21171
21233
  return false;
21172
21234
  }
@@ -21629,6 +21691,49 @@ class SimpleSpatialIndex {
21629
21691
  }
21630
21692
 
21631
21693
  // src/Items/BaseItem/BaseItem.ts
21694
+ function toLocalTransformOp(op, containerMatrix, itemId) {
21695
+ switch (op.method) {
21696
+ case "applyMatrix": {
21697
+ const converted = op.items.map((item) => {
21698
+ const local = containerMatrix.applyInverseLinear(item.matrix.translateX, item.matrix.translateY);
21699
+ return { ...item, matrix: { ...item.matrix, translateX: local.x, translateY: local.y } };
21700
+ });
21701
+ return { ...op, items: converted };
21702
+ }
21703
+ case "translateBy": {
21704
+ const local = containerMatrix.applyInverseLinear(op.x, op.y);
21705
+ return { ...op, x: local.x, y: local.y };
21706
+ }
21707
+ case "translateTo": {
21708
+ const pt = new Point(op.x, op.y);
21709
+ containerMatrix.getInverse().apply(pt);
21710
+ return { ...op, x: pt.x, y: pt.y };
21711
+ }
21712
+ case "scaleTo": {
21713
+ return { ...op, x: op.x / containerMatrix.scaleX, y: op.y / containerMatrix.scaleY };
21714
+ }
21715
+ case "scaleByTranslateBy": {
21716
+ const local = containerMatrix.applyInverseLinear(op.translate.x, op.translate.y);
21717
+ return { ...op, translate: { x: local.x, y: local.y } };
21718
+ }
21719
+ case "scaleByRelativeTo":
21720
+ case "scaleToRelativeTo": {
21721
+ const pt = new Point(op.point.x, op.point.y);
21722
+ containerMatrix.getInverse().apply(pt);
21723
+ return { ...op, point: pt };
21724
+ }
21725
+ case "transformMany": {
21726
+ if (!itemId || !op.items[itemId])
21727
+ return op;
21728
+ const subOp = op.items[itemId];
21729
+ const localSubOp = toLocalTransformOp(subOp, containerMatrix);
21730
+ return { ...op, items: { ...op.items, [itemId]: localSubOp } };
21731
+ }
21732
+ default:
21733
+ return op;
21734
+ }
21735
+ }
21736
+
21632
21737
  class BaseItem extends Mbr {
21633
21738
  defaultItemData;
21634
21739
  transformation;
@@ -21673,6 +21778,16 @@ class BaseItem extends Mbr {
21673
21778
  getId() {
21674
21779
  return this.id;
21675
21780
  }
21781
+ getWorldMatrix() {
21782
+ if (this.parent === "Board") {
21783
+ return this.transformation.toMatrix();
21784
+ }
21785
+ const container = this.board.items.getById(this.parent);
21786
+ if (!container) {
21787
+ return this.transformation.toMatrix();
21788
+ }
21789
+ return this.transformation.toMatrix().composeWith(container.getWorldMatrix());
21790
+ }
21676
21791
  setId(id) {
21677
21792
  this.id = id;
21678
21793
  this.transformation.setId(id);
@@ -21747,16 +21862,35 @@ class BaseItem extends Mbr {
21747
21862
  getMbr() {
21748
21863
  return new Mbr(this.left, this.top, this.right, this.bottom);
21749
21864
  }
21865
+ getWorldMbr() {
21866
+ if (this.parent === "Board" || !this.parent || !this.board?.items) {
21867
+ return this.getMbr();
21868
+ }
21869
+ const worldMatrix = this.getWorldMatrix();
21870
+ const local = this.getMbr();
21871
+ const corners = [
21872
+ new Point(local.left, local.top),
21873
+ new Point(local.right, local.top),
21874
+ new Point(local.right, local.bottom),
21875
+ new Point(local.left, local.bottom)
21876
+ ];
21877
+ for (const c of corners)
21878
+ worldMatrix.apply(c);
21879
+ 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));
21880
+ }
21750
21881
  applyAddChildren(childIds) {
21751
21882
  if (!this.index) {
21752
21883
  return;
21753
21884
  }
21885
+ const containerWorldMatrix = this.getWorldMatrix();
21754
21886
  childIds.forEach((childId) => {
21755
21887
  const foundItem = this.board.items.getById(childId);
21756
21888
  if (this.parent !== childId && this.getId() !== childId) {
21757
21889
  if (!this.index?.getById(childId) && foundItem) {
21890
+ const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerWorldMatrix);
21758
21891
  this.board.items.index.remove(foundItem);
21759
21892
  foundItem.parent = this.getId();
21893
+ foundItem.transformation.setLocalMatrix(localMatrix);
21760
21894
  this.index?.insert(foundItem);
21761
21895
  }
21762
21896
  }
@@ -21769,12 +21903,15 @@ class BaseItem extends Mbr {
21769
21903
  if (!this.index) {
21770
21904
  return;
21771
21905
  }
21906
+ const containerWorldMatrix = this.getWorldMatrix();
21772
21907
  childIds.forEach((childId) => {
21773
21908
  const foundItem = this.index?.getById(childId);
21774
21909
  if (this.parent !== childId && this.getId() !== childId) {
21775
21910
  if (foundItem) {
21911
+ const worldMatrix = foundItem.transformation.toMatrix().composeWith(containerWorldMatrix);
21776
21912
  this.index?.remove(foundItem);
21777
21913
  foundItem.parent = "Board";
21914
+ foundItem.transformation.setLocalMatrix(worldMatrix);
21778
21915
  this.board.items.index.insert(foundItem);
21779
21916
  }
21780
21917
  }
@@ -21886,9 +22023,17 @@ class BaseItem extends Mbr {
21886
22023
  apply(op) {
21887
22024
  op = op;
21888
22025
  switch (op.class) {
21889
- case "Transformation":
21890
- this.transformation.apply(op);
22026
+ case "Transformation": {
22027
+ let transformOp = op;
22028
+ if (this.parent !== "Board") {
22029
+ const container = this.board.items.getById(this.parent);
22030
+ if (container?.transformation) {
22031
+ transformOp = toLocalTransformOp(transformOp, container.getWorldMatrix(), this.id);
22032
+ }
22033
+ }
22034
+ this.transformation.apply(transformOp);
21891
22035
  break;
22036
+ }
21892
22037
  case "LinkTo":
21893
22038
  this.linkTo.apply(op);
21894
22039
  break;
@@ -36693,14 +36838,20 @@ function getControlPoint(data, findItem2) {
36693
36838
  }
36694
36839
  }
36695
36840
  }
36841
+ function getItemWorldMatrix(item) {
36842
+ if (item instanceof BaseItem && item.parent !== "Board") {
36843
+ return item.getWorldMatrix();
36844
+ }
36845
+ return item.transformation?.toMatrix() ?? new Matrix;
36846
+ }
36696
36847
  function toRelativePoint(point5, item) {
36697
- const inverse = item.transformation ? item.transformation.getInverse().toMatrix() : new Matrix;
36848
+ const inverse = getItemWorldMatrix(item).getInverse();
36698
36849
  point5 = point5.copy();
36699
36850
  point5.transform(inverse);
36700
36851
  return point5;
36701
36852
  }
36702
36853
  function fromRelativePoint(relativePoint, item, edge) {
36703
- const matrix = item.transformation?.toMatrix() ?? new Matrix;
36854
+ const matrix = getItemWorldMatrix(item);
36704
36855
  const point5 = relativePoint.copy();
36705
36856
  point5.transform(matrix);
36706
36857
  if (item instanceof RichText || item instanceof AINode) {
@@ -41175,7 +41326,13 @@ class Frame2 extends BaseItem {
41175
41326
  return;
41176
41327
  }
41177
41328
  this.renderPath(context);
41178
- super.render(context);
41329
+ const ctx = context.ctx;
41330
+ ctx.save();
41331
+ this.transformation.applyToContext(ctx);
41332
+ for (const child of this.index.list()) {
41333
+ child.render(context);
41334
+ }
41335
+ ctx.restore();
41179
41336
  this.renderBorders(context);
41180
41337
  this.renderName(context);
41181
41338
  }
@@ -43283,25 +43440,24 @@ function douglasPeucker(points, epsilon2) {
43283
43440
  // src/Items/Group/Group.ts
43284
43441
  class Group extends BaseItem {
43285
43442
  events;
43286
- children;
43287
43443
  linkTo;
43288
43444
  itemType = "Group";
43289
43445
  parent = "Board";
43290
43446
  transformation;
43291
43447
  subject = new Subject;
43292
- mbr = new Mbr;
43293
43448
  transformationRenderBlock = undefined;
43294
43449
  constructor(board, events, children = [], id = "") {
43295
- super(board, id);
43450
+ super(board, id, undefined, true);
43296
43451
  this.events = events;
43297
- this.children = children;
43298
43452
  this.linkTo = new LinkTo(this.id, this.events);
43299
43453
  this.transformation = new Transformation(this.id, this.events);
43300
- this.children = children;
43301
43454
  this.transformation.subject.subscribe(() => {
43302
43455
  this.updateMbr();
43303
43456
  this.subject.publish(this);
43304
43457
  });
43458
+ if (children.length > 0) {
43459
+ this.applyAddChildren(children);
43460
+ }
43305
43461
  }
43306
43462
  isClosed() {
43307
43463
  return false;
@@ -43309,45 +43465,17 @@ class Group extends BaseItem {
43309
43465
  getRichText() {
43310
43466
  return null;
43311
43467
  }
43312
- addChild(childId) {
43313
- this.emit({
43314
- class: "Group",
43315
- method: "addChild",
43316
- item: [this.getId()],
43317
- childId
43318
- });
43319
- }
43320
- applyAddChild(childId) {
43321
- if (!this.children.includes(childId)) {
43322
- this.children.push(childId);
43323
- this.updateMbr();
43324
- this.subject.publish(this);
43325
- }
43326
- }
43327
- applyRemoveChild(childId) {
43328
- this.children = this.children.filter((currChild) => currChild !== childId);
43329
- this.updateMbr();
43330
- this.subject.publish(this);
43331
- }
43332
- removeChild(childId) {
43333
- this.emit({
43334
- class: "Group",
43335
- method: "removeChild",
43336
- item: [this.getId()],
43337
- childId
43338
- });
43339
- }
43340
- emitRemoveChild(child) {
43341
- this.removeChild(child.getId());
43342
- child.parent = "Board";
43343
- }
43344
43468
  apply(op) {
43345
43469
  switch (op.class) {
43346
43470
  case "Group":
43347
43471
  if (op.method === "addChild") {
43348
- this.applyAddChild(op.childId);
43472
+ this.applyAddChildren([op.childId]);
43349
43473
  } else if (op.method === "removeChild") {
43350
- this.applyRemoveChild(op.childId);
43474
+ this.applyRemoveChildren([op.childId]);
43475
+ } else if (op.method === "addChildren") {
43476
+ this.applyAddChildren(op.newData.childIds);
43477
+ } else if (op.method === "removeChildren") {
43478
+ this.applyRemoveChildren(op.newData.childIds);
43351
43479
  }
43352
43480
  break;
43353
43481
  case "Transformation":
@@ -43372,24 +43500,69 @@ class Group extends BaseItem {
43372
43500
  this.transformation.setId(id);
43373
43501
  return this;
43374
43502
  }
43503
+ getMbr() {
43504
+ const children = this.index.list();
43505
+ if (children.length === 0) {
43506
+ return new Mbr(this.left, this.top, this.right, this.bottom);
43507
+ }
43508
+ const groupWorldMatrix = this.getWorldMatrix();
43509
+ let left = Number.MAX_SAFE_INTEGER;
43510
+ let top = Number.MAX_SAFE_INTEGER;
43511
+ let right = Number.MIN_SAFE_INTEGER;
43512
+ let bottom = Number.MIN_SAFE_INTEGER;
43513
+ for (const child of children) {
43514
+ const childLocalMbr = child.getMbr();
43515
+ const corners = [
43516
+ { x: childLocalMbr.left, y: childLocalMbr.top },
43517
+ { x: childLocalMbr.right, y: childLocalMbr.top },
43518
+ { x: childLocalMbr.right, y: childLocalMbr.bottom },
43519
+ { x: childLocalMbr.left, y: childLocalMbr.bottom }
43520
+ ];
43521
+ for (const corner of corners) {
43522
+ groupWorldMatrix.apply(corner);
43523
+ if (corner.x < left)
43524
+ left = corner.x;
43525
+ if (corner.y < top)
43526
+ top = corner.y;
43527
+ if (corner.x > right)
43528
+ right = corner.x;
43529
+ if (corner.y > bottom)
43530
+ bottom = corner.y;
43531
+ }
43532
+ }
43533
+ const mbr = new Mbr(left, top, right, bottom);
43534
+ this.left = left;
43535
+ this.top = top;
43536
+ this.right = right;
43537
+ this.bottom = bottom;
43538
+ return mbr;
43539
+ }
43540
+ updateMbr() {
43541
+ this.getMbr();
43542
+ }
43543
+ getChildrenIds() {
43544
+ return this.index.list().map((item) => item.getId());
43545
+ }
43546
+ getChildren() {
43547
+ return this.index.list();
43548
+ }
43549
+ getLinkTo() {
43550
+ return this.linkTo.link;
43551
+ }
43375
43552
  serialize() {
43376
43553
  return {
43377
43554
  itemType: "Group",
43378
- children: this.children,
43555
+ children: this.getChildrenIds(),
43379
43556
  transformation: this.transformation.serialize()
43380
43557
  };
43381
43558
  }
43382
43559
  deserialize(data) {
43383
- if (data.children) {
43384
- data.children.forEach((childId) => {
43385
- this.applyAddChild(childId);
43386
- const item = this.board.items.getById(childId);
43387
- if (item) {
43388
- item.parent = this.getId();
43389
- }
43390
- });
43560
+ if (data.transformation) {
43561
+ this.transformation.deserialize(data.transformation);
43562
+ }
43563
+ if (data.children && data.children.length > 0) {
43564
+ this.applyAddChildren(data.children);
43391
43565
  }
43392
- this.transformation.deserialize(data.transformation);
43393
43566
  this.subject.publish(this);
43394
43567
  return this;
43395
43568
  }
@@ -43399,99 +43572,25 @@ class Group extends BaseItem {
43399
43572
  getIntersectionPoints(segment) {
43400
43573
  const lines = this.getMbr().getLines();
43401
43574
  const initPoints = [];
43402
- const points = lines.reduce((acc, line) => {
43575
+ return lines.reduce((acc, line) => {
43403
43576
  const intersections = line.getIntersectionPoints(segment);
43404
43577
  if (intersections.length > 0) {
43405
43578
  acc.push(...intersections);
43406
43579
  }
43407
43580
  return acc;
43408
43581
  }, initPoints);
43409
- return points;
43410
- }
43411
- getMbr() {
43412
- const mbr = new Mbr;
43413
- let left = Number.MAX_SAFE_INTEGER;
43414
- let top = Number.MAX_SAFE_INTEGER;
43415
- let right = Number.MIN_SAFE_INTEGER;
43416
- let bottom = Number.MIN_SAFE_INTEGER;
43417
- const mbrs = this.children.flatMap((childId) => {
43418
- const item = this.board.items.getById(childId);
43419
- if (!item) {
43420
- return [];
43421
- }
43422
- const mbr2 = item.getMbr();
43423
- if (!mbr2) {
43424
- return [];
43425
- }
43426
- if (left > mbr2.left) {
43427
- left = mbr2.left;
43428
- }
43429
- if (top > mbr2.top) {
43430
- top = mbr2.top;
43431
- }
43432
- if (right < mbr2.right) {
43433
- right = mbr2.right;
43434
- }
43435
- if (bottom < mbr2.bottom) {
43436
- bottom = mbr2.bottom;
43437
- }
43438
- return [mbr2];
43439
- });
43440
- if (mbrs.length) {
43441
- mbr.combine(mbrs);
43442
- mbr.left = left !== Number.MAX_SAFE_INTEGER ? left : 0;
43443
- mbr.top = top !== Number.MAX_SAFE_INTEGER ? top : 0;
43444
- mbr.right = right !== Number.MIN_SAFE_INTEGER ? right : 0;
43445
- mbr.bottom = bottom !== Number.MIN_SAFE_INTEGER ? bottom : 0;
43446
- this.left = mbr.left;
43447
- this.bottom = mbr.bottom;
43448
- this.right = mbr.right;
43449
- this.top = mbr.top;
43450
- }
43451
- return mbr;
43452
- }
43453
- getChildrenIds() {
43454
- return this.children;
43455
- }
43456
- getChildren() {
43457
- return this.children.map((itemId) => this.board.items.getById(itemId)).filter((item) => item !== undefined);
43458
- }
43459
- updateMbr() {
43460
- const rect = this.getMbr();
43461
- this.mbr = rect;
43462
- this.mbr.borderColor = "transparent";
43463
- }
43464
- setBoard(board) {
43465
- this.board = board;
43466
- }
43467
- setChildren(items) {
43468
- items.forEach((itemId) => {
43469
- this.addChild(itemId);
43470
- const item = this.board.items.getById(itemId);
43471
- if (item) {
43472
- item.parent = this.getId();
43473
- }
43474
- });
43475
- this.updateMbr();
43476
- }
43477
- removeChildren() {
43478
- this.children.forEach((itemId) => {
43479
- this.removeChild(itemId);
43480
- const item = this.board.items.getById(itemId);
43481
- if (item) {
43482
- item.parent = this.parent;
43483
- }
43484
- });
43485
- this.updateMbr();
43486
- }
43487
- getLinkTo() {
43488
- return this.linkTo.link;
43489
43582
  }
43490
43583
  render(context) {
43491
43584
  if (this.transformationRenderBlock) {
43492
43585
  return;
43493
43586
  }
43494
- this.mbr.render(context);
43587
+ const ctx = context.ctx;
43588
+ ctx.save();
43589
+ this.transformation.applyToContext(ctx);
43590
+ for (const child of this.index.list()) {
43591
+ child.render(context);
43592
+ }
43593
+ ctx.restore();
43495
43594
  }
43496
43595
  renderHTML(documentFactory) {
43497
43596
  return documentFactory.createElement("div");
@@ -46208,13 +46307,13 @@ class AlignmentHelper {
46208
46307
  return baseThickness / (zoom / 100);
46209
46308
  }
46210
46309
  combineMBRs(items) {
46310
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
46211
46311
  return items.reduce((acc, item, i) => {
46212
46312
  if (i === 0) {
46213
46313
  return acc;
46214
46314
  }
46215
- const itemMbr = item.getPathMbr();
46216
- return acc.combine(itemMbr);
46217
- }, items[0].getMbr());
46315
+ return acc.combine(worldMbr(item));
46316
+ }, worldMbr(items[0]));
46218
46317
  }
46219
46318
  checkAlignment(movingItem, excludeItems = []) {
46220
46319
  if (!Array.isArray(movingItem) && movingItem.itemType === "Comment") {
@@ -51908,8 +52007,9 @@ class SelectionItems {
51908
52007
  if (items.length === 0) {
51909
52008
  return;
51910
52009
  }
51911
- const mbr = items[0].getMbr();
51912
- items.slice(1).forEach((item) => mbr.combine(item.getMbr()));
52010
+ const worldMbr = (item) => item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
52011
+ const mbr = worldMbr(items[0]);
52012
+ items.slice(1).forEach((item) => mbr.combine(worldMbr(item)));
51913
52013
  return mbr;
51914
52014
  }
51915
52015
  }
@@ -52118,18 +52218,27 @@ function handleMultipleItemsResize({
52118
52218
  }) {
52119
52219
  const { matrix } = resize;
52120
52220
  const result = [];
52121
- const items = itemsToResize ? itemsToResize : board.selection.items.list();
52221
+ const rawItems = itemsToResize ? itemsToResize : board.selection.items.list();
52122
52222
  board.items.getComments().forEach((comment2) => {
52123
- if (items.some((item) => item.getId() === comment2.getItemToFollow())) {
52124
- items.push(comment2);
52223
+ if (rawItems.some((item) => item.getId() === comment2.getItemToFollow())) {
52224
+ rawItems.push(comment2);
52125
52225
  }
52126
52226
  });
52227
+ const selectedIds = new Set(rawItems.map((i) => i.getId()));
52228
+ const items = rawItems.filter((item) => item.parent === "Board" || !selectedIds.has(item.parent));
52127
52229
  for (const item of items) {
52128
- let itemX = item.getMbr().left;
52129
- let itemY = item.getMbr().top;
52230
+ const worldMbr = item instanceof BaseItem ? item.getWorldMbr() : item.getMbr();
52231
+ let itemX = worldMbr.left;
52232
+ let itemY = worldMbr.top;
52130
52233
  if (item.itemType === "Drawing") {
52131
- itemX = item.transformation.getMatrixData().translateX;
52132
- itemY = item.transformation.getMatrixData().translateY;
52234
+ if (item instanceof BaseItem && item.parent !== "Board") {
52235
+ const worldMatrix = item.getWorldMatrix();
52236
+ itemX = worldMatrix.translateX;
52237
+ itemY = worldMatrix.translateY;
52238
+ } else {
52239
+ itemX = item.transformation.getMatrixData().translateX;
52240
+ itemY = item.transformation.getMatrixData().translateY;
52241
+ }
52133
52242
  }
52134
52243
  const deltaX = itemX - initMbr.left;
52135
52244
  const translateX = deltaX * matrix.scaleX - deltaX + matrix.translateX;
@@ -53053,10 +53162,6 @@ class BoardSelection {
53053
53162
  if (!this.board.events) {
53054
53163
  return;
53055
53164
  }
53056
- if (operation.method === "transformMany") {
53057
- console.error("[DEBUG] transformMany emitted!", JSON.stringify(operation));
53058
- console.trace("[DEBUG] transformMany stack trace");
53059
- }
53060
53165
  const command = createCommand(this.board, operation);
53061
53166
  command.apply();
53062
53167
  this.board.events.emit(operation, command);
@@ -53599,17 +53704,12 @@ class BoardSelection {
53599
53704
  const addItem = (itemId) => {
53600
53705
  items.push({ id: itemId, matrix: { translateX: x, translateY: y, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } });
53601
53706
  };
53602
- const tryToAddFrameChildren = (selectedItem) => {
53603
- if (!("index" in selectedItem) || !selectedItem.index) {
53707
+ const selectedIds = new Set(unselectedItem ? [unselectedItem.getId()] : this.board.selection.list().map((i) => i.getId()));
53708
+ const addWithComments = (item) => {
53709
+ if (item.parent !== "Board" && selectedIds.has(item.parent)) {
53604
53710
  return;
53605
53711
  }
53606
- for (const childId of selectedItem.getChildrenIds()) {
53607
- addItem(childId);
53608
- }
53609
- };
53610
- const addWithComments = (item) => {
53611
53712
  addItem(item.getId());
53612
- tryToAddFrameChildren(item);
53613
53713
  const followedComments = this.board.items.getComments().filter((comment2) => comment2.getItemToFollow() === item.getId());
53614
53714
  for (const comment2 of followedComments) {
53615
53715
  addItem(comment2.getId());
@@ -54441,6 +54541,28 @@ class Board {
54441
54541
  item: [item.getId()]
54442
54542
  });
54443
54543
  }
54544
+ group(items) {
54545
+ const id = this.getNewItemId();
54546
+ const groupData = {
54547
+ itemType: "Group",
54548
+ children: items.map((i) => i.getId()),
54549
+ transformation: { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 }
54550
+ };
54551
+ this.emit({
54552
+ class: "Board",
54553
+ method: "addLockedGroup",
54554
+ item: id,
54555
+ data: groupData
54556
+ });
54557
+ return this.items.getById(id);
54558
+ }
54559
+ ungroup(group) {
54560
+ this.emit({
54561
+ class: "Board",
54562
+ method: "removeLockedGroup",
54563
+ item: [group.getId()]
54564
+ });
54565
+ }
54444
54566
  getByZIndex(index2) {
54445
54567
  return this.index.getByZIndex(index2);
54446
54568
  }