microboard-temp 0.12.1 → 0.12.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.
@@ -19367,13 +19367,18 @@ class Comment {
19367
19367
  userId
19368
19368
  });
19369
19369
  }
19370
+ _syncing = false;
19370
19371
  transform() {
19372
+ if (this._syncing)
19373
+ return;
19374
+ this._syncing = true;
19371
19375
  const { translateX, translateY } = this.transformation.getMatrixData();
19372
19376
  if (translateX && translateY) {
19373
19377
  this.anchor = new Point(translateX, translateY);
19374
19378
  } else {
19375
19379
  this.transformation.setLocal(this.anchor.x, this.anchor.y);
19376
19380
  }
19381
+ this._syncing = false;
19377
19382
  }
19378
19383
  getUnreadMessages(userId = ANONYMOUS_ID) {
19379
19384
  const unreadMessages = this.thread.filter((mes) => mes && !mes.readers.includes(userId));
@@ -22200,7 +22205,6 @@ class RichText extends BaseItem {
22200
22205
  _onLimitReached = () => {};
22201
22206
  shrinkWidth = false;
22202
22207
  prevMbr = null;
22203
- worldMatrixGetter;
22204
22208
  rtCounter = 0;
22205
22209
  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) {
22206
22210
  super(board, id);
@@ -22423,18 +22427,7 @@ class RichText extends BaseItem {
22423
22427
  top = container.top;
22424
22428
  }
22425
22429
  const point3 = new Point(left, top);
22426
- if (this.worldMatrixGetter) {
22427
- this.worldMatrixGetter().apply(point3);
22428
- } else if (this.isInShape) {
22429
- const item = this.board.items.getById(this.id);
22430
- if (item) {
22431
- item.getParentWorldMatrix().apply(point3);
22432
- } else {
22433
- this.getParentWorldMatrix().apply(point3);
22434
- }
22435
- } else {
22436
- this.getParentWorldMatrix().apply(point3);
22437
- }
22430
+ this.getParentWorldMatrix().apply(point3);
22438
22431
  return {
22439
22432
  point: point3,
22440
22433
  width,
@@ -36538,6 +36531,11 @@ class AINode extends BaseItem {
36538
36531
  this.linkTo.setId(id);
36539
36532
  return this;
36540
36533
  }
36534
+ onParentChanged(newParent) {
36535
+ if (this.text) {
36536
+ this.text.parent = newParent;
36537
+ }
36538
+ }
36541
36539
  getId() {
36542
36540
  return this.id;
36543
36541
  }
@@ -40062,6 +40060,11 @@ class Shape extends BaseItem {
40062
40060
  this.linkTo.setId(id);
40063
40061
  return this;
40064
40062
  }
40063
+ onParentChanged(newParent) {
40064
+ if (this.text) {
40065
+ this.text.parent = newParent;
40066
+ }
40067
+ }
40065
40068
  getId() {
40066
40069
  return this.id;
40067
40070
  }
@@ -40594,6 +40597,11 @@ class Sticker extends BaseItem {
40594
40597
  this.transformation.setId(id);
40595
40598
  return this;
40596
40599
  }
40600
+ onParentChanged(newParent) {
40601
+ if (this.text) {
40602
+ this.text.parent = newParent;
40603
+ }
40604
+ }
40597
40605
  getId() {
40598
40606
  return this.id;
40599
40607
  }
@@ -41121,15 +41129,6 @@ class Frame2 extends BaseItem {
41121
41129
  y: translateY
41122
41130
  }, timeStamp);
41123
41131
  const newMatrix = this.transformation.toMatrix();
41124
- if (newMatrix.translateX !== oldMatrix.translateX || newMatrix.translateY !== oldMatrix.translateY) {
41125
- const dx = newMatrix.translateX - oldMatrix.translateX;
41126
- const dy = newMatrix.translateY - oldMatrix.translateY;
41127
- this.index?.list().forEach((child) => {
41128
- if (child instanceof BaseItem) {
41129
- child.transformation.translateBy(-dx, -dy, timeStamp);
41130
- }
41131
- });
41132
- }
41133
41132
  this.setLastFrameScale();
41134
41133
  res.mbr = this.getMbr();
41135
41134
  return res;
@@ -54297,14 +54296,18 @@ class BoardSelection {
54297
54296
  }
54298
54297
  }
54299
54298
  // src/Gravity/GravityEngine.ts
54299
+ var EXCLUDED_ITEM_TYPES = new Set(["Comment", "Connector"]);
54300
+
54300
54301
  class GravityEngine {
54301
54302
  board;
54302
54303
  velocities = new Map;
54303
54304
  tickTimer = null;
54304
54305
  syncTimer = null;
54305
54306
  lastSyncedPositions = new Map;
54306
- G = 500;
54307
- DAMPING = 0.98;
54307
+ G = 80;
54308
+ G_CENTER = 120;
54309
+ DAMPING = 0.92;
54310
+ REPULSION = 60000;
54308
54311
  TICK_MS = 33;
54309
54312
  SYNC_MS = 300;
54310
54313
  MAX_DISTANCE = 3000;
@@ -54336,9 +54339,18 @@ class GravityEngine {
54336
54339
  }
54337
54340
  tick() {
54338
54341
  const dt = this.TICK_MS / 1000;
54339
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54340
- if (items.length < 2)
54342
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54343
+ if (items.length < 1)
54341
54344
  return;
54345
+ let sumX = 0;
54346
+ let sumY = 0;
54347
+ for (const item of items) {
54348
+ const pos = item.transformation.getTranslation();
54349
+ sumX += pos.x;
54350
+ sumY += pos.y;
54351
+ }
54352
+ const centerX = sumX / items.length;
54353
+ const centerY = sumY / items.length;
54342
54354
  for (const item of items) {
54343
54355
  const id = item.getId();
54344
54356
  if (!this.velocities.has(id)) {
@@ -54347,30 +54359,45 @@ class GravityEngine {
54347
54359
  const vel = this.velocities.get(id);
54348
54360
  const pos1 = item.transformation.getTranslation();
54349
54361
  const mbr1 = item.getMbr();
54350
- const mass1 = mbr1.getWidth() * mbr1.getHeight();
54351
- const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id);
54362
+ const w1 = mbr1.getWidth();
54363
+ const h1 = mbr1.getHeight();
54352
54364
  let ax = 0;
54353
54365
  let ay = 0;
54366
+ const dcx = centerX - pos1.x;
54367
+ const dcy = centerY - pos1.y;
54368
+ const distCenter = Math.sqrt(dcx * dcx + dcy * dcy) + 1;
54369
+ ax += this.G_CENTER * dcx / distCenter;
54370
+ ay += this.G_CENTER * dcy / distCenter;
54371
+ const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id && !EXCLUDED_ITEM_TYPES.has(other.itemType));
54354
54372
  for (const other of nearby) {
54355
54373
  const pos2 = other.transformation.getTranslation();
54356
54374
  const mbr2 = other.getMbr();
54357
- const mass2 = mbr2.getWidth() * mbr2.getHeight();
54358
- const dx2 = pos2.x - pos1.x;
54359
- const dy2 = pos2.y - pos1.y;
54360
- const distSq = dx2 * dx2 + dy2 * dy2 + this.SOFTENING_SQ;
54361
- const dist = Math.sqrt(distSq);
54362
- const acc = this.G * mass2 / distSq;
54363
- ax += acc * dx2 / dist;
54364
- ay += acc * dy2 / dist;
54375
+ const w2 = mbr2.getWidth();
54376
+ const h2 = mbr2.getHeight();
54377
+ const mass2 = w2 * h2;
54378
+ const dx = pos2.x - pos1.x;
54379
+ const dy = pos2.y - pos1.y;
54380
+ const distSq = dx * dx + dy * dy;
54381
+ const dist = Math.sqrt(distSq) + 0.001;
54382
+ const minDist = (w1 + w2) * 0.5 + (h1 + h2) * 0.5;
54383
+ if (dist < minDist) {
54384
+ const repAcc = this.REPULSION / (distSq + this.SOFTENING_SQ);
54385
+ ax -= repAcc * dx / dist;
54386
+ ay -= repAcc * dy / dist;
54387
+ } else {
54388
+ const gravAcc = this.G * mass2 / (distSq + this.SOFTENING_SQ);
54389
+ ax += gravAcc * dx / dist;
54390
+ ay += gravAcc * dy / dist;
54391
+ }
54365
54392
  }
54366
54393
  vel.vx = (vel.vx + ax * dt) * this.DAMPING;
54367
54394
  vel.vy = (vel.vy + ay * dt) * this.DAMPING;
54368
- const dx = vel.vx * dt;
54369
- const dy = vel.vy * dt;
54370
- if (Math.abs(dx) >= this.MIN_MOVE_PX || Math.abs(dy) >= this.MIN_MOVE_PX) {
54395
+ const moveX = vel.vx * dt;
54396
+ const moveY = vel.vy * dt;
54397
+ if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
54371
54398
  item.transformation.applyMatrixSilent({
54372
- translateX: dx,
54373
- translateY: dy,
54399
+ translateX: moveX,
54400
+ translateY: moveY,
54374
54401
  scaleX: 1,
54375
54402
  scaleY: 1,
54376
54403
  shearX: 0,
@@ -54380,7 +54407,7 @@ class GravityEngine {
54380
54407
  }
54381
54408
  }
54382
54409
  syncPositions() {
54383
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54410
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54384
54411
  if (items.length === 0)
54385
54412
  return;
54386
54413
  const movedItems = items.map((item) => {
package/dist/cjs/index.js CHANGED
@@ -19367,13 +19367,18 @@ class Comment {
19367
19367
  userId
19368
19368
  });
19369
19369
  }
19370
+ _syncing = false;
19370
19371
  transform() {
19372
+ if (this._syncing)
19373
+ return;
19374
+ this._syncing = true;
19371
19375
  const { translateX, translateY } = this.transformation.getMatrixData();
19372
19376
  if (translateX && translateY) {
19373
19377
  this.anchor = new Point(translateX, translateY);
19374
19378
  } else {
19375
19379
  this.transformation.setLocal(this.anchor.x, this.anchor.y);
19376
19380
  }
19381
+ this._syncing = false;
19377
19382
  }
19378
19383
  getUnreadMessages(userId = ANONYMOUS_ID) {
19379
19384
  const unreadMessages = this.thread.filter((mes) => mes && !mes.readers.includes(userId));
@@ -22200,7 +22205,6 @@ class RichText extends BaseItem {
22200
22205
  _onLimitReached = () => {};
22201
22206
  shrinkWidth = false;
22202
22207
  prevMbr = null;
22203
- worldMatrixGetter;
22204
22208
  rtCounter = 0;
22205
22209
  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) {
22206
22210
  super(board, id);
@@ -22423,18 +22427,7 @@ class RichText extends BaseItem {
22423
22427
  top = container.top;
22424
22428
  }
22425
22429
  const point3 = new Point(left, top);
22426
- if (this.worldMatrixGetter) {
22427
- this.worldMatrixGetter().apply(point3);
22428
- } else if (this.isInShape) {
22429
- const item = this.board.items.getById(this.id);
22430
- if (item) {
22431
- item.getParentWorldMatrix().apply(point3);
22432
- } else {
22433
- this.getParentWorldMatrix().apply(point3);
22434
- }
22435
- } else {
22436
- this.getParentWorldMatrix().apply(point3);
22437
- }
22430
+ this.getParentWorldMatrix().apply(point3);
22438
22431
  return {
22439
22432
  point: point3,
22440
22433
  width,
@@ -36538,6 +36531,11 @@ class AINode extends BaseItem {
36538
36531
  this.linkTo.setId(id);
36539
36532
  return this;
36540
36533
  }
36534
+ onParentChanged(newParent) {
36535
+ if (this.text) {
36536
+ this.text.parent = newParent;
36537
+ }
36538
+ }
36541
36539
  getId() {
36542
36540
  return this.id;
36543
36541
  }
@@ -40062,6 +40060,11 @@ class Shape extends BaseItem {
40062
40060
  this.linkTo.setId(id);
40063
40061
  return this;
40064
40062
  }
40063
+ onParentChanged(newParent) {
40064
+ if (this.text) {
40065
+ this.text.parent = newParent;
40066
+ }
40067
+ }
40065
40068
  getId() {
40066
40069
  return this.id;
40067
40070
  }
@@ -40594,6 +40597,11 @@ class Sticker extends BaseItem {
40594
40597
  this.transformation.setId(id);
40595
40598
  return this;
40596
40599
  }
40600
+ onParentChanged(newParent) {
40601
+ if (this.text) {
40602
+ this.text.parent = newParent;
40603
+ }
40604
+ }
40597
40605
  getId() {
40598
40606
  return this.id;
40599
40607
  }
@@ -41121,15 +41129,6 @@ class Frame2 extends BaseItem {
41121
41129
  y: translateY
41122
41130
  }, timeStamp);
41123
41131
  const newMatrix = this.transformation.toMatrix();
41124
- if (newMatrix.translateX !== oldMatrix.translateX || newMatrix.translateY !== oldMatrix.translateY) {
41125
- const dx = newMatrix.translateX - oldMatrix.translateX;
41126
- const dy = newMatrix.translateY - oldMatrix.translateY;
41127
- this.index?.list().forEach((child) => {
41128
- if (child instanceof BaseItem) {
41129
- child.transformation.translateBy(-dx, -dy, timeStamp);
41130
- }
41131
- });
41132
- }
41133
41132
  this.setLastFrameScale();
41134
41133
  res.mbr = this.getMbr();
41135
41134
  return res;
@@ -54297,14 +54296,18 @@ class BoardSelection {
54297
54296
  }
54298
54297
  }
54299
54298
  // src/Gravity/GravityEngine.ts
54299
+ var EXCLUDED_ITEM_TYPES = new Set(["Comment", "Connector"]);
54300
+
54300
54301
  class GravityEngine {
54301
54302
  board;
54302
54303
  velocities = new Map;
54303
54304
  tickTimer = null;
54304
54305
  syncTimer = null;
54305
54306
  lastSyncedPositions = new Map;
54306
- G = 500;
54307
- DAMPING = 0.98;
54307
+ G = 80;
54308
+ G_CENTER = 120;
54309
+ DAMPING = 0.92;
54310
+ REPULSION = 60000;
54308
54311
  TICK_MS = 33;
54309
54312
  SYNC_MS = 300;
54310
54313
  MAX_DISTANCE = 3000;
@@ -54336,9 +54339,18 @@ class GravityEngine {
54336
54339
  }
54337
54340
  tick() {
54338
54341
  const dt = this.TICK_MS / 1000;
54339
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54340
- if (items.length < 2)
54342
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54343
+ if (items.length < 1)
54341
54344
  return;
54345
+ let sumX = 0;
54346
+ let sumY = 0;
54347
+ for (const item of items) {
54348
+ const pos = item.transformation.getTranslation();
54349
+ sumX += pos.x;
54350
+ sumY += pos.y;
54351
+ }
54352
+ const centerX = sumX / items.length;
54353
+ const centerY = sumY / items.length;
54342
54354
  for (const item of items) {
54343
54355
  const id = item.getId();
54344
54356
  if (!this.velocities.has(id)) {
@@ -54347,30 +54359,45 @@ class GravityEngine {
54347
54359
  const vel = this.velocities.get(id);
54348
54360
  const pos1 = item.transformation.getTranslation();
54349
54361
  const mbr1 = item.getMbr();
54350
- const mass1 = mbr1.getWidth() * mbr1.getHeight();
54351
- const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id);
54362
+ const w1 = mbr1.getWidth();
54363
+ const h1 = mbr1.getHeight();
54352
54364
  let ax = 0;
54353
54365
  let ay = 0;
54366
+ const dcx = centerX - pos1.x;
54367
+ const dcy = centerY - pos1.y;
54368
+ const distCenter = Math.sqrt(dcx * dcx + dcy * dcy) + 1;
54369
+ ax += this.G_CENTER * dcx / distCenter;
54370
+ ay += this.G_CENTER * dcy / distCenter;
54371
+ const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id && !EXCLUDED_ITEM_TYPES.has(other.itemType));
54354
54372
  for (const other of nearby) {
54355
54373
  const pos2 = other.transformation.getTranslation();
54356
54374
  const mbr2 = other.getMbr();
54357
- const mass2 = mbr2.getWidth() * mbr2.getHeight();
54358
- const dx2 = pos2.x - pos1.x;
54359
- const dy2 = pos2.y - pos1.y;
54360
- const distSq = dx2 * dx2 + dy2 * dy2 + this.SOFTENING_SQ;
54361
- const dist = Math.sqrt(distSq);
54362
- const acc = this.G * mass2 / distSq;
54363
- ax += acc * dx2 / dist;
54364
- ay += acc * dy2 / dist;
54375
+ const w2 = mbr2.getWidth();
54376
+ const h2 = mbr2.getHeight();
54377
+ const mass2 = w2 * h2;
54378
+ const dx = pos2.x - pos1.x;
54379
+ const dy = pos2.y - pos1.y;
54380
+ const distSq = dx * dx + dy * dy;
54381
+ const dist = Math.sqrt(distSq) + 0.001;
54382
+ const minDist = (w1 + w2) * 0.5 + (h1 + h2) * 0.5;
54383
+ if (dist < minDist) {
54384
+ const repAcc = this.REPULSION / (distSq + this.SOFTENING_SQ);
54385
+ ax -= repAcc * dx / dist;
54386
+ ay -= repAcc * dy / dist;
54387
+ } else {
54388
+ const gravAcc = this.G * mass2 / (distSq + this.SOFTENING_SQ);
54389
+ ax += gravAcc * dx / dist;
54390
+ ay += gravAcc * dy / dist;
54391
+ }
54365
54392
  }
54366
54393
  vel.vx = (vel.vx + ax * dt) * this.DAMPING;
54367
54394
  vel.vy = (vel.vy + ay * dt) * this.DAMPING;
54368
- const dx = vel.vx * dt;
54369
- const dy = vel.vy * dt;
54370
- if (Math.abs(dx) >= this.MIN_MOVE_PX || Math.abs(dy) >= this.MIN_MOVE_PX) {
54395
+ const moveX = vel.vx * dt;
54396
+ const moveY = vel.vy * dt;
54397
+ if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
54371
54398
  item.transformation.applyMatrixSilent({
54372
- translateX: dx,
54373
- translateY: dy,
54399
+ translateX: moveX,
54400
+ translateY: moveY,
54374
54401
  scaleX: 1,
54375
54402
  scaleY: 1,
54376
54403
  shearX: 0,
@@ -54380,7 +54407,7 @@ class GravityEngine {
54380
54407
  }
54381
54408
  }
54382
54409
  syncPositions() {
54383
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54410
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54384
54411
  if (items.length === 0)
54385
54412
  return;
54386
54413
  const movedItems = items.map((item) => {
package/dist/cjs/node.js CHANGED
@@ -21906,13 +21906,18 @@ class Comment {
21906
21906
  userId
21907
21907
  });
21908
21908
  }
21909
+ _syncing = false;
21909
21910
  transform() {
21911
+ if (this._syncing)
21912
+ return;
21913
+ this._syncing = true;
21910
21914
  const { translateX, translateY } = this.transformation.getMatrixData();
21911
21915
  if (translateX && translateY) {
21912
21916
  this.anchor = new Point(translateX, translateY);
21913
21917
  } else {
21914
21918
  this.transformation.setLocal(this.anchor.x, this.anchor.y);
21915
21919
  }
21920
+ this._syncing = false;
21916
21921
  }
21917
21922
  getUnreadMessages(userId = ANONYMOUS_ID) {
21918
21923
  const unreadMessages = this.thread.filter((mes) => mes && !mes.readers.includes(userId));
@@ -24672,7 +24677,6 @@ class RichText extends BaseItem {
24672
24677
  _onLimitReached = () => {};
24673
24678
  shrinkWidth = false;
24674
24679
  prevMbr = null;
24675
- worldMatrixGetter;
24676
24680
  rtCounter = 0;
24677
24681
  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) {
24678
24682
  super(board, id);
@@ -24895,18 +24899,7 @@ class RichText extends BaseItem {
24895
24899
  top = container.top;
24896
24900
  }
24897
24901
  const point3 = new Point(left, top);
24898
- if (this.worldMatrixGetter) {
24899
- this.worldMatrixGetter().apply(point3);
24900
- } else if (this.isInShape) {
24901
- const item = this.board.items.getById(this.id);
24902
- if (item) {
24903
- item.getParentWorldMatrix().apply(point3);
24904
- } else {
24905
- this.getParentWorldMatrix().apply(point3);
24906
- }
24907
- } else {
24908
- this.getParentWorldMatrix().apply(point3);
24909
- }
24902
+ this.getParentWorldMatrix().apply(point3);
24910
24903
  return {
24911
24904
  point: point3,
24912
24905
  width,
@@ -39011,6 +39004,11 @@ class AINode extends BaseItem {
39011
39004
  this.linkTo.setId(id);
39012
39005
  return this;
39013
39006
  }
39007
+ onParentChanged(newParent) {
39008
+ if (this.text) {
39009
+ this.text.parent = newParent;
39010
+ }
39011
+ }
39014
39012
  getId() {
39015
39013
  return this.id;
39016
39014
  }
@@ -42535,6 +42533,11 @@ class Shape extends BaseItem {
42535
42533
  this.linkTo.setId(id);
42536
42534
  return this;
42537
42535
  }
42536
+ onParentChanged(newParent) {
42537
+ if (this.text) {
42538
+ this.text.parent = newParent;
42539
+ }
42540
+ }
42538
42541
  getId() {
42539
42542
  return this.id;
42540
42543
  }
@@ -43067,6 +43070,11 @@ class Sticker extends BaseItem {
43067
43070
  this.transformation.setId(id);
43068
43071
  return this;
43069
43072
  }
43073
+ onParentChanged(newParent) {
43074
+ if (this.text) {
43075
+ this.text.parent = newParent;
43076
+ }
43077
+ }
43070
43078
  getId() {
43071
43079
  return this.id;
43072
43080
  }
@@ -43594,15 +43602,6 @@ class Frame2 extends BaseItem {
43594
43602
  y: translateY
43595
43603
  }, timeStamp);
43596
43604
  const newMatrix = this.transformation.toMatrix();
43597
- if (newMatrix.translateX !== oldMatrix.translateX || newMatrix.translateY !== oldMatrix.translateY) {
43598
- const dx = newMatrix.translateX - oldMatrix.translateX;
43599
- const dy = newMatrix.translateY - oldMatrix.translateY;
43600
- this.index?.list().forEach((child) => {
43601
- if (child instanceof BaseItem) {
43602
- child.transformation.translateBy(-dx, -dy, timeStamp);
43603
- }
43604
- });
43605
- }
43606
43605
  this.setLastFrameScale();
43607
43606
  res.mbr = this.getMbr();
43608
43607
  return res;
@@ -56770,14 +56769,18 @@ class BoardSelection {
56770
56769
  }
56771
56770
  }
56772
56771
  // src/Gravity/GravityEngine.ts
56772
+ var EXCLUDED_ITEM_TYPES = new Set(["Comment", "Connector"]);
56773
+
56773
56774
  class GravityEngine {
56774
56775
  board;
56775
56776
  velocities = new Map;
56776
56777
  tickTimer = null;
56777
56778
  syncTimer = null;
56778
56779
  lastSyncedPositions = new Map;
56779
- G = 500;
56780
- DAMPING = 0.98;
56780
+ G = 80;
56781
+ G_CENTER = 120;
56782
+ DAMPING = 0.92;
56783
+ REPULSION = 60000;
56781
56784
  TICK_MS = 33;
56782
56785
  SYNC_MS = 300;
56783
56786
  MAX_DISTANCE = 3000;
@@ -56809,9 +56812,18 @@ class GravityEngine {
56809
56812
  }
56810
56813
  tick() {
56811
56814
  const dt = this.TICK_MS / 1000;
56812
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
56813
- if (items.length < 2)
56815
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
56816
+ if (items.length < 1)
56814
56817
  return;
56818
+ let sumX = 0;
56819
+ let sumY = 0;
56820
+ for (const item of items) {
56821
+ const pos = item.transformation.getTranslation();
56822
+ sumX += pos.x;
56823
+ sumY += pos.y;
56824
+ }
56825
+ const centerX = sumX / items.length;
56826
+ const centerY = sumY / items.length;
56815
56827
  for (const item of items) {
56816
56828
  const id = item.getId();
56817
56829
  if (!this.velocities.has(id)) {
@@ -56820,30 +56832,45 @@ class GravityEngine {
56820
56832
  const vel = this.velocities.get(id);
56821
56833
  const pos1 = item.transformation.getTranslation();
56822
56834
  const mbr1 = item.getMbr();
56823
- const mass1 = mbr1.getWidth() * mbr1.getHeight();
56824
- const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id);
56835
+ const w1 = mbr1.getWidth();
56836
+ const h1 = mbr1.getHeight();
56825
56837
  let ax = 0;
56826
56838
  let ay = 0;
56839
+ const dcx = centerX - pos1.x;
56840
+ const dcy = centerY - pos1.y;
56841
+ const distCenter = Math.sqrt(dcx * dcx + dcy * dcy) + 1;
56842
+ ax += this.G_CENTER * dcx / distCenter;
56843
+ ay += this.G_CENTER * dcy / distCenter;
56844
+ const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id && !EXCLUDED_ITEM_TYPES.has(other.itemType));
56827
56845
  for (const other of nearby) {
56828
56846
  const pos2 = other.transformation.getTranslation();
56829
56847
  const mbr2 = other.getMbr();
56830
- const mass2 = mbr2.getWidth() * mbr2.getHeight();
56831
- const dx2 = pos2.x - pos1.x;
56832
- const dy2 = pos2.y - pos1.y;
56833
- const distSq = dx2 * dx2 + dy2 * dy2 + this.SOFTENING_SQ;
56834
- const dist = Math.sqrt(distSq);
56835
- const acc = this.G * mass2 / distSq;
56836
- ax += acc * dx2 / dist;
56837
- ay += acc * dy2 / dist;
56848
+ const w2 = mbr2.getWidth();
56849
+ const h2 = mbr2.getHeight();
56850
+ const mass2 = w2 * h2;
56851
+ const dx = pos2.x - pos1.x;
56852
+ const dy = pos2.y - pos1.y;
56853
+ const distSq = dx * dx + dy * dy;
56854
+ const dist = Math.sqrt(distSq) + 0.001;
56855
+ const minDist = (w1 + w2) * 0.5 + (h1 + h2) * 0.5;
56856
+ if (dist < minDist) {
56857
+ const repAcc = this.REPULSION / (distSq + this.SOFTENING_SQ);
56858
+ ax -= repAcc * dx / dist;
56859
+ ay -= repAcc * dy / dist;
56860
+ } else {
56861
+ const gravAcc = this.G * mass2 / (distSq + this.SOFTENING_SQ);
56862
+ ax += gravAcc * dx / dist;
56863
+ ay += gravAcc * dy / dist;
56864
+ }
56838
56865
  }
56839
56866
  vel.vx = (vel.vx + ax * dt) * this.DAMPING;
56840
56867
  vel.vy = (vel.vy + ay * dt) * this.DAMPING;
56841
- const dx = vel.vx * dt;
56842
- const dy = vel.vy * dt;
56843
- if (Math.abs(dx) >= this.MIN_MOVE_PX || Math.abs(dy) >= this.MIN_MOVE_PX) {
56868
+ const moveX = vel.vx * dt;
56869
+ const moveY = vel.vy * dt;
56870
+ if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
56844
56871
  item.transformation.applyMatrixSilent({
56845
- translateX: dx,
56846
- translateY: dy,
56872
+ translateX: moveX,
56873
+ translateY: moveY,
56847
56874
  scaleX: 1,
56848
56875
  scaleY: 1,
56849
56876
  shearX: 0,
@@ -56853,7 +56880,7 @@ class GravityEngine {
56853
56880
  }
56854
56881
  }
56855
56882
  syncPositions() {
56856
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
56883
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
56857
56884
  if (items.length === 0)
56858
56885
  return;
56859
56886
  const movedItems = items.map((item) => {
@@ -19196,13 +19196,18 @@ class Comment {
19196
19196
  userId
19197
19197
  });
19198
19198
  }
19199
+ _syncing = false;
19199
19200
  transform() {
19201
+ if (this._syncing)
19202
+ return;
19203
+ this._syncing = true;
19200
19204
  const { translateX, translateY } = this.transformation.getMatrixData();
19201
19205
  if (translateX && translateY) {
19202
19206
  this.anchor = new Point(translateX, translateY);
19203
19207
  } else {
19204
19208
  this.transformation.setLocal(this.anchor.x, this.anchor.y);
19205
19209
  }
19210
+ this._syncing = false;
19206
19211
  }
19207
19212
  getUnreadMessages(userId = ANONYMOUS_ID) {
19208
19213
  const unreadMessages = this.thread.filter((mes) => mes && !mes.readers.includes(userId));
@@ -22029,7 +22034,6 @@ class RichText extends BaseItem {
22029
22034
  _onLimitReached = () => {};
22030
22035
  shrinkWidth = false;
22031
22036
  prevMbr = null;
22032
- worldMatrixGetter;
22033
22037
  rtCounter = 0;
22034
22038
  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) {
22035
22039
  super(board, id);
@@ -22252,18 +22256,7 @@ class RichText extends BaseItem {
22252
22256
  top = container.top;
22253
22257
  }
22254
22258
  const point3 = new Point(left, top);
22255
- if (this.worldMatrixGetter) {
22256
- this.worldMatrixGetter().apply(point3);
22257
- } else if (this.isInShape) {
22258
- const item = this.board.items.getById(this.id);
22259
- if (item) {
22260
- item.getParentWorldMatrix().apply(point3);
22261
- } else {
22262
- this.getParentWorldMatrix().apply(point3);
22263
- }
22264
- } else {
22265
- this.getParentWorldMatrix().apply(point3);
22266
- }
22259
+ this.getParentWorldMatrix().apply(point3);
22267
22260
  return {
22268
22261
  point: point3,
22269
22262
  width,
@@ -36367,6 +36360,11 @@ class AINode extends BaseItem {
36367
36360
  this.linkTo.setId(id);
36368
36361
  return this;
36369
36362
  }
36363
+ onParentChanged(newParent) {
36364
+ if (this.text) {
36365
+ this.text.parent = newParent;
36366
+ }
36367
+ }
36370
36368
  getId() {
36371
36369
  return this.id;
36372
36370
  }
@@ -39891,6 +39889,11 @@ class Shape extends BaseItem {
39891
39889
  this.linkTo.setId(id);
39892
39890
  return this;
39893
39891
  }
39892
+ onParentChanged(newParent) {
39893
+ if (this.text) {
39894
+ this.text.parent = newParent;
39895
+ }
39896
+ }
39894
39897
  getId() {
39895
39898
  return this.id;
39896
39899
  }
@@ -40423,6 +40426,11 @@ class Sticker extends BaseItem {
40423
40426
  this.transformation.setId(id);
40424
40427
  return this;
40425
40428
  }
40429
+ onParentChanged(newParent) {
40430
+ if (this.text) {
40431
+ this.text.parent = newParent;
40432
+ }
40433
+ }
40426
40434
  getId() {
40427
40435
  return this.id;
40428
40436
  }
@@ -40950,15 +40958,6 @@ class Frame2 extends BaseItem {
40950
40958
  y: translateY
40951
40959
  }, timeStamp);
40952
40960
  const newMatrix = this.transformation.toMatrix();
40953
- if (newMatrix.translateX !== oldMatrix.translateX || newMatrix.translateY !== oldMatrix.translateY) {
40954
- const dx = newMatrix.translateX - oldMatrix.translateX;
40955
- const dy = newMatrix.translateY - oldMatrix.translateY;
40956
- this.index?.list().forEach((child) => {
40957
- if (child instanceof BaseItem) {
40958
- child.transformation.translateBy(-dx, -dy, timeStamp);
40959
- }
40960
- });
40961
- }
40962
40961
  this.setLastFrameScale();
40963
40962
  res.mbr = this.getMbr();
40964
40963
  return res;
@@ -54126,14 +54125,18 @@ class BoardSelection {
54126
54125
  }
54127
54126
  }
54128
54127
  // src/Gravity/GravityEngine.ts
54128
+ var EXCLUDED_ITEM_TYPES = new Set(["Comment", "Connector"]);
54129
+
54129
54130
  class GravityEngine {
54130
54131
  board;
54131
54132
  velocities = new Map;
54132
54133
  tickTimer = null;
54133
54134
  syncTimer = null;
54134
54135
  lastSyncedPositions = new Map;
54135
- G = 500;
54136
- DAMPING = 0.98;
54136
+ G = 80;
54137
+ G_CENTER = 120;
54138
+ DAMPING = 0.92;
54139
+ REPULSION = 60000;
54137
54140
  TICK_MS = 33;
54138
54141
  SYNC_MS = 300;
54139
54142
  MAX_DISTANCE = 3000;
@@ -54165,9 +54168,18 @@ class GravityEngine {
54165
54168
  }
54166
54169
  tick() {
54167
54170
  const dt = this.TICK_MS / 1000;
54168
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54169
- if (items.length < 2)
54171
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54172
+ if (items.length < 1)
54170
54173
  return;
54174
+ let sumX = 0;
54175
+ let sumY = 0;
54176
+ for (const item of items) {
54177
+ const pos = item.transformation.getTranslation();
54178
+ sumX += pos.x;
54179
+ sumY += pos.y;
54180
+ }
54181
+ const centerX = sumX / items.length;
54182
+ const centerY = sumY / items.length;
54171
54183
  for (const item of items) {
54172
54184
  const id = item.getId();
54173
54185
  if (!this.velocities.has(id)) {
@@ -54176,30 +54188,45 @@ class GravityEngine {
54176
54188
  const vel = this.velocities.get(id);
54177
54189
  const pos1 = item.transformation.getTranslation();
54178
54190
  const mbr1 = item.getMbr();
54179
- const mass1 = mbr1.getWidth() * mbr1.getHeight();
54180
- const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id);
54191
+ const w1 = mbr1.getWidth();
54192
+ const h1 = mbr1.getHeight();
54181
54193
  let ax = 0;
54182
54194
  let ay = 0;
54195
+ const dcx = centerX - pos1.x;
54196
+ const dcy = centerY - pos1.y;
54197
+ const distCenter = Math.sqrt(dcx * dcx + dcy * dcy) + 1;
54198
+ ax += this.G_CENTER * dcx / distCenter;
54199
+ ay += this.G_CENTER * dcy / distCenter;
54200
+ const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id && !EXCLUDED_ITEM_TYPES.has(other.itemType));
54183
54201
  for (const other of nearby) {
54184
54202
  const pos2 = other.transformation.getTranslation();
54185
54203
  const mbr2 = other.getMbr();
54186
- const mass2 = mbr2.getWidth() * mbr2.getHeight();
54187
- const dx2 = pos2.x - pos1.x;
54188
- const dy2 = pos2.y - pos1.y;
54189
- const distSq = dx2 * dx2 + dy2 * dy2 + this.SOFTENING_SQ;
54190
- const dist = Math.sqrt(distSq);
54191
- const acc = this.G * mass2 / distSq;
54192
- ax += acc * dx2 / dist;
54193
- ay += acc * dy2 / dist;
54204
+ const w2 = mbr2.getWidth();
54205
+ const h2 = mbr2.getHeight();
54206
+ const mass2 = w2 * h2;
54207
+ const dx = pos2.x - pos1.x;
54208
+ const dy = pos2.y - pos1.y;
54209
+ const distSq = dx * dx + dy * dy;
54210
+ const dist = Math.sqrt(distSq) + 0.001;
54211
+ const minDist = (w1 + w2) * 0.5 + (h1 + h2) * 0.5;
54212
+ if (dist < minDist) {
54213
+ const repAcc = this.REPULSION / (distSq + this.SOFTENING_SQ);
54214
+ ax -= repAcc * dx / dist;
54215
+ ay -= repAcc * dy / dist;
54216
+ } else {
54217
+ const gravAcc = this.G * mass2 / (distSq + this.SOFTENING_SQ);
54218
+ ax += gravAcc * dx / dist;
54219
+ ay += gravAcc * dy / dist;
54220
+ }
54194
54221
  }
54195
54222
  vel.vx = (vel.vx + ax * dt) * this.DAMPING;
54196
54223
  vel.vy = (vel.vy + ay * dt) * this.DAMPING;
54197
- const dx = vel.vx * dt;
54198
- const dy = vel.vy * dt;
54199
- if (Math.abs(dx) >= this.MIN_MOVE_PX || Math.abs(dy) >= this.MIN_MOVE_PX) {
54224
+ const moveX = vel.vx * dt;
54225
+ const moveY = vel.vy * dt;
54226
+ if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
54200
54227
  item.transformation.applyMatrixSilent({
54201
- translateX: dx,
54202
- translateY: dy,
54228
+ translateX: moveX,
54229
+ translateY: moveY,
54203
54230
  scaleX: 1,
54204
54231
  scaleY: 1,
54205
54232
  shearX: 0,
@@ -54209,7 +54236,7 @@ class GravityEngine {
54209
54236
  }
54210
54237
  }
54211
54238
  syncPositions() {
54212
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54239
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54213
54240
  if (items.length === 0)
54214
54241
  return;
54215
54242
  const movedItems = items.map((item) => {
package/dist/esm/index.js CHANGED
@@ -19189,13 +19189,18 @@ class Comment {
19189
19189
  userId
19190
19190
  });
19191
19191
  }
19192
+ _syncing = false;
19192
19193
  transform() {
19194
+ if (this._syncing)
19195
+ return;
19196
+ this._syncing = true;
19193
19197
  const { translateX, translateY } = this.transformation.getMatrixData();
19194
19198
  if (translateX && translateY) {
19195
19199
  this.anchor = new Point(translateX, translateY);
19196
19200
  } else {
19197
19201
  this.transformation.setLocal(this.anchor.x, this.anchor.y);
19198
19202
  }
19203
+ this._syncing = false;
19199
19204
  }
19200
19205
  getUnreadMessages(userId = ANONYMOUS_ID) {
19201
19206
  const unreadMessages = this.thread.filter((mes) => mes && !mes.readers.includes(userId));
@@ -22022,7 +22027,6 @@ class RichText extends BaseItem {
22022
22027
  _onLimitReached = () => {};
22023
22028
  shrinkWidth = false;
22024
22029
  prevMbr = null;
22025
- worldMatrixGetter;
22026
22030
  rtCounter = 0;
22027
22031
  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) {
22028
22032
  super(board, id);
@@ -22245,18 +22249,7 @@ class RichText extends BaseItem {
22245
22249
  top = container.top;
22246
22250
  }
22247
22251
  const point3 = new Point(left, top);
22248
- if (this.worldMatrixGetter) {
22249
- this.worldMatrixGetter().apply(point3);
22250
- } else if (this.isInShape) {
22251
- const item = this.board.items.getById(this.id);
22252
- if (item) {
22253
- item.getParentWorldMatrix().apply(point3);
22254
- } else {
22255
- this.getParentWorldMatrix().apply(point3);
22256
- }
22257
- } else {
22258
- this.getParentWorldMatrix().apply(point3);
22259
- }
22252
+ this.getParentWorldMatrix().apply(point3);
22260
22253
  return {
22261
22254
  point: point3,
22262
22255
  width,
@@ -36360,6 +36353,11 @@ class AINode extends BaseItem {
36360
36353
  this.linkTo.setId(id);
36361
36354
  return this;
36362
36355
  }
36356
+ onParentChanged(newParent) {
36357
+ if (this.text) {
36358
+ this.text.parent = newParent;
36359
+ }
36360
+ }
36363
36361
  getId() {
36364
36362
  return this.id;
36365
36363
  }
@@ -39884,6 +39882,11 @@ class Shape extends BaseItem {
39884
39882
  this.linkTo.setId(id);
39885
39883
  return this;
39886
39884
  }
39885
+ onParentChanged(newParent) {
39886
+ if (this.text) {
39887
+ this.text.parent = newParent;
39888
+ }
39889
+ }
39887
39890
  getId() {
39888
39891
  return this.id;
39889
39892
  }
@@ -40416,6 +40419,11 @@ class Sticker extends BaseItem {
40416
40419
  this.transformation.setId(id);
40417
40420
  return this;
40418
40421
  }
40422
+ onParentChanged(newParent) {
40423
+ if (this.text) {
40424
+ this.text.parent = newParent;
40425
+ }
40426
+ }
40419
40427
  getId() {
40420
40428
  return this.id;
40421
40429
  }
@@ -40943,15 +40951,6 @@ class Frame2 extends BaseItem {
40943
40951
  y: translateY
40944
40952
  }, timeStamp);
40945
40953
  const newMatrix = this.transformation.toMatrix();
40946
- if (newMatrix.translateX !== oldMatrix.translateX || newMatrix.translateY !== oldMatrix.translateY) {
40947
- const dx = newMatrix.translateX - oldMatrix.translateX;
40948
- const dy = newMatrix.translateY - oldMatrix.translateY;
40949
- this.index?.list().forEach((child) => {
40950
- if (child instanceof BaseItem) {
40951
- child.transformation.translateBy(-dx, -dy, timeStamp);
40952
- }
40953
- });
40954
- }
40955
40954
  this.setLastFrameScale();
40956
40955
  res.mbr = this.getMbr();
40957
40956
  return res;
@@ -54119,14 +54118,18 @@ class BoardSelection {
54119
54118
  }
54120
54119
  }
54121
54120
  // src/Gravity/GravityEngine.ts
54121
+ var EXCLUDED_ITEM_TYPES = new Set(["Comment", "Connector"]);
54122
+
54122
54123
  class GravityEngine {
54123
54124
  board;
54124
54125
  velocities = new Map;
54125
54126
  tickTimer = null;
54126
54127
  syncTimer = null;
54127
54128
  lastSyncedPositions = new Map;
54128
- G = 500;
54129
- DAMPING = 0.98;
54129
+ G = 80;
54130
+ G_CENTER = 120;
54131
+ DAMPING = 0.92;
54132
+ REPULSION = 60000;
54130
54133
  TICK_MS = 33;
54131
54134
  SYNC_MS = 300;
54132
54135
  MAX_DISTANCE = 3000;
@@ -54158,9 +54161,18 @@ class GravityEngine {
54158
54161
  }
54159
54162
  tick() {
54160
54163
  const dt = this.TICK_MS / 1000;
54161
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54162
- if (items.length < 2)
54164
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54165
+ if (items.length < 1)
54163
54166
  return;
54167
+ let sumX = 0;
54168
+ let sumY = 0;
54169
+ for (const item of items) {
54170
+ const pos = item.transformation.getTranslation();
54171
+ sumX += pos.x;
54172
+ sumY += pos.y;
54173
+ }
54174
+ const centerX = sumX / items.length;
54175
+ const centerY = sumY / items.length;
54164
54176
  for (const item of items) {
54165
54177
  const id = item.getId();
54166
54178
  if (!this.velocities.has(id)) {
@@ -54169,30 +54181,45 @@ class GravityEngine {
54169
54181
  const vel = this.velocities.get(id);
54170
54182
  const pos1 = item.transformation.getTranslation();
54171
54183
  const mbr1 = item.getMbr();
54172
- const mass1 = mbr1.getWidth() * mbr1.getHeight();
54173
- const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id);
54184
+ const w1 = mbr1.getWidth();
54185
+ const h1 = mbr1.getHeight();
54174
54186
  let ax = 0;
54175
54187
  let ay = 0;
54188
+ const dcx = centerX - pos1.x;
54189
+ const dcy = centerY - pos1.y;
54190
+ const distCenter = Math.sqrt(dcx * dcx + dcy * dcy) + 1;
54191
+ ax += this.G_CENTER * dcx / distCenter;
54192
+ ay += this.G_CENTER * dcy / distCenter;
54193
+ const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id && !EXCLUDED_ITEM_TYPES.has(other.itemType));
54176
54194
  for (const other of nearby) {
54177
54195
  const pos2 = other.transformation.getTranslation();
54178
54196
  const mbr2 = other.getMbr();
54179
- const mass2 = mbr2.getWidth() * mbr2.getHeight();
54180
- const dx2 = pos2.x - pos1.x;
54181
- const dy2 = pos2.y - pos1.y;
54182
- const distSq = dx2 * dx2 + dy2 * dy2 + this.SOFTENING_SQ;
54183
- const dist = Math.sqrt(distSq);
54184
- const acc = this.G * mass2 / distSq;
54185
- ax += acc * dx2 / dist;
54186
- ay += acc * dy2 / dist;
54197
+ const w2 = mbr2.getWidth();
54198
+ const h2 = mbr2.getHeight();
54199
+ const mass2 = w2 * h2;
54200
+ const dx = pos2.x - pos1.x;
54201
+ const dy = pos2.y - pos1.y;
54202
+ const distSq = dx * dx + dy * dy;
54203
+ const dist = Math.sqrt(distSq) + 0.001;
54204
+ const minDist = (w1 + w2) * 0.5 + (h1 + h2) * 0.5;
54205
+ if (dist < minDist) {
54206
+ const repAcc = this.REPULSION / (distSq + this.SOFTENING_SQ);
54207
+ ax -= repAcc * dx / dist;
54208
+ ay -= repAcc * dy / dist;
54209
+ } else {
54210
+ const gravAcc = this.G * mass2 / (distSq + this.SOFTENING_SQ);
54211
+ ax += gravAcc * dx / dist;
54212
+ ay += gravAcc * dy / dist;
54213
+ }
54187
54214
  }
54188
54215
  vel.vx = (vel.vx + ax * dt) * this.DAMPING;
54189
54216
  vel.vy = (vel.vy + ay * dt) * this.DAMPING;
54190
- const dx = vel.vx * dt;
54191
- const dy = vel.vy * dt;
54192
- if (Math.abs(dx) >= this.MIN_MOVE_PX || Math.abs(dy) >= this.MIN_MOVE_PX) {
54217
+ const moveX = vel.vx * dt;
54218
+ const moveY = vel.vy * dt;
54219
+ if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
54193
54220
  item.transformation.applyMatrixSilent({
54194
- translateX: dx,
54195
- translateY: dy,
54221
+ translateX: moveX,
54222
+ translateY: moveY,
54196
54223
  scaleX: 1,
54197
54224
  scaleY: 1,
54198
54225
  shearX: 0,
@@ -54202,7 +54229,7 @@ class GravityEngine {
54202
54229
  }
54203
54230
  }
54204
54231
  syncPositions() {
54205
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
54232
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
54206
54233
  if (items.length === 0)
54207
54234
  return;
54208
54235
  const movedItems = items.map((item) => {
package/dist/esm/node.js CHANGED
@@ -21723,13 +21723,18 @@ class Comment {
21723
21723
  userId
21724
21724
  });
21725
21725
  }
21726
+ _syncing = false;
21726
21727
  transform() {
21728
+ if (this._syncing)
21729
+ return;
21730
+ this._syncing = true;
21727
21731
  const { translateX, translateY } = this.transformation.getMatrixData();
21728
21732
  if (translateX && translateY) {
21729
21733
  this.anchor = new Point(translateX, translateY);
21730
21734
  } else {
21731
21735
  this.transformation.setLocal(this.anchor.x, this.anchor.y);
21732
21736
  }
21737
+ this._syncing = false;
21733
21738
  }
21734
21739
  getUnreadMessages(userId = ANONYMOUS_ID) {
21735
21740
  const unreadMessages = this.thread.filter((mes) => mes && !mes.readers.includes(userId));
@@ -24489,7 +24494,6 @@ class RichText extends BaseItem {
24489
24494
  _onLimitReached = () => {};
24490
24495
  shrinkWidth = false;
24491
24496
  prevMbr = null;
24492
- worldMatrixGetter;
24493
24497
  rtCounter = 0;
24494
24498
  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) {
24495
24499
  super(board, id);
@@ -24712,18 +24716,7 @@ class RichText extends BaseItem {
24712
24716
  top = container.top;
24713
24717
  }
24714
24718
  const point3 = new Point(left, top);
24715
- if (this.worldMatrixGetter) {
24716
- this.worldMatrixGetter().apply(point3);
24717
- } else if (this.isInShape) {
24718
- const item = this.board.items.getById(this.id);
24719
- if (item) {
24720
- item.getParentWorldMatrix().apply(point3);
24721
- } else {
24722
- this.getParentWorldMatrix().apply(point3);
24723
- }
24724
- } else {
24725
- this.getParentWorldMatrix().apply(point3);
24726
- }
24719
+ this.getParentWorldMatrix().apply(point3);
24727
24720
  return {
24728
24721
  point: point3,
24729
24722
  width,
@@ -38828,6 +38821,11 @@ class AINode extends BaseItem {
38828
38821
  this.linkTo.setId(id);
38829
38822
  return this;
38830
38823
  }
38824
+ onParentChanged(newParent) {
38825
+ if (this.text) {
38826
+ this.text.parent = newParent;
38827
+ }
38828
+ }
38831
38829
  getId() {
38832
38830
  return this.id;
38833
38831
  }
@@ -42352,6 +42350,11 @@ class Shape extends BaseItem {
42352
42350
  this.linkTo.setId(id);
42353
42351
  return this;
42354
42352
  }
42353
+ onParentChanged(newParent) {
42354
+ if (this.text) {
42355
+ this.text.parent = newParent;
42356
+ }
42357
+ }
42355
42358
  getId() {
42356
42359
  return this.id;
42357
42360
  }
@@ -42884,6 +42887,11 @@ class Sticker extends BaseItem {
42884
42887
  this.transformation.setId(id);
42885
42888
  return this;
42886
42889
  }
42890
+ onParentChanged(newParent) {
42891
+ if (this.text) {
42892
+ this.text.parent = newParent;
42893
+ }
42894
+ }
42887
42895
  getId() {
42888
42896
  return this.id;
42889
42897
  }
@@ -43411,15 +43419,6 @@ class Frame2 extends BaseItem {
43411
43419
  y: translateY
43412
43420
  }, timeStamp);
43413
43421
  const newMatrix = this.transformation.toMatrix();
43414
- if (newMatrix.translateX !== oldMatrix.translateX || newMatrix.translateY !== oldMatrix.translateY) {
43415
- const dx = newMatrix.translateX - oldMatrix.translateX;
43416
- const dy = newMatrix.translateY - oldMatrix.translateY;
43417
- this.index?.list().forEach((child) => {
43418
- if (child instanceof BaseItem) {
43419
- child.transformation.translateBy(-dx, -dy, timeStamp);
43420
- }
43421
- });
43422
- }
43423
43422
  this.setLastFrameScale();
43424
43423
  res.mbr = this.getMbr();
43425
43424
  return res;
@@ -56587,14 +56586,18 @@ class BoardSelection {
56587
56586
  }
56588
56587
  }
56589
56588
  // src/Gravity/GravityEngine.ts
56589
+ var EXCLUDED_ITEM_TYPES = new Set(["Comment", "Connector"]);
56590
+
56590
56591
  class GravityEngine {
56591
56592
  board;
56592
56593
  velocities = new Map;
56593
56594
  tickTimer = null;
56594
56595
  syncTimer = null;
56595
56596
  lastSyncedPositions = new Map;
56596
- G = 500;
56597
- DAMPING = 0.98;
56597
+ G = 80;
56598
+ G_CENTER = 120;
56599
+ DAMPING = 0.92;
56600
+ REPULSION = 60000;
56598
56601
  TICK_MS = 33;
56599
56602
  SYNC_MS = 300;
56600
56603
  MAX_DISTANCE = 3000;
@@ -56626,9 +56629,18 @@ class GravityEngine {
56626
56629
  }
56627
56630
  tick() {
56628
56631
  const dt = this.TICK_MS / 1000;
56629
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
56630
- if (items.length < 2)
56632
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
56633
+ if (items.length < 1)
56631
56634
  return;
56635
+ let sumX = 0;
56636
+ let sumY = 0;
56637
+ for (const item of items) {
56638
+ const pos = item.transformation.getTranslation();
56639
+ sumX += pos.x;
56640
+ sumY += pos.y;
56641
+ }
56642
+ const centerX = sumX / items.length;
56643
+ const centerY = sumY / items.length;
56632
56644
  for (const item of items) {
56633
56645
  const id = item.getId();
56634
56646
  if (!this.velocities.has(id)) {
@@ -56637,30 +56649,45 @@ class GravityEngine {
56637
56649
  const vel = this.velocities.get(id);
56638
56650
  const pos1 = item.transformation.getTranslation();
56639
56651
  const mbr1 = item.getMbr();
56640
- const mass1 = mbr1.getWidth() * mbr1.getHeight();
56641
- const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id);
56652
+ const w1 = mbr1.getWidth();
56653
+ const h1 = mbr1.getHeight();
56642
56654
  let ax = 0;
56643
56655
  let ay = 0;
56656
+ const dcx = centerX - pos1.x;
56657
+ const dcy = centerY - pos1.y;
56658
+ const distCenter = Math.sqrt(dcx * dcx + dcy * dcy) + 1;
56659
+ ax += this.G_CENTER * dcx / distCenter;
56660
+ ay += this.G_CENTER * dcy / distCenter;
56661
+ const nearby = this.board.items.getEnclosedOrCrossed(pos1.x - this.MAX_DISTANCE, pos1.y - this.MAX_DISTANCE, pos1.x + this.MAX_DISTANCE * 2, pos1.y + this.MAX_DISTANCE * 2).filter((other) => other.getId() !== id && !EXCLUDED_ITEM_TYPES.has(other.itemType));
56644
56662
  for (const other of nearby) {
56645
56663
  const pos2 = other.transformation.getTranslation();
56646
56664
  const mbr2 = other.getMbr();
56647
- const mass2 = mbr2.getWidth() * mbr2.getHeight();
56648
- const dx2 = pos2.x - pos1.x;
56649
- const dy2 = pos2.y - pos1.y;
56650
- const distSq = dx2 * dx2 + dy2 * dy2 + this.SOFTENING_SQ;
56651
- const dist = Math.sqrt(distSq);
56652
- const acc = this.G * mass2 / distSq;
56653
- ax += acc * dx2 / dist;
56654
- ay += acc * dy2 / dist;
56665
+ const w2 = mbr2.getWidth();
56666
+ const h2 = mbr2.getHeight();
56667
+ const mass2 = w2 * h2;
56668
+ const dx = pos2.x - pos1.x;
56669
+ const dy = pos2.y - pos1.y;
56670
+ const distSq = dx * dx + dy * dy;
56671
+ const dist = Math.sqrt(distSq) + 0.001;
56672
+ const minDist = (w1 + w2) * 0.5 + (h1 + h2) * 0.5;
56673
+ if (dist < minDist) {
56674
+ const repAcc = this.REPULSION / (distSq + this.SOFTENING_SQ);
56675
+ ax -= repAcc * dx / dist;
56676
+ ay -= repAcc * dy / dist;
56677
+ } else {
56678
+ const gravAcc = this.G * mass2 / (distSq + this.SOFTENING_SQ);
56679
+ ax += gravAcc * dx / dist;
56680
+ ay += gravAcc * dy / dist;
56681
+ }
56655
56682
  }
56656
56683
  vel.vx = (vel.vx + ax * dt) * this.DAMPING;
56657
56684
  vel.vy = (vel.vy + ay * dt) * this.DAMPING;
56658
- const dx = vel.vx * dt;
56659
- const dy = vel.vy * dt;
56660
- if (Math.abs(dx) >= this.MIN_MOVE_PX || Math.abs(dy) >= this.MIN_MOVE_PX) {
56685
+ const moveX = vel.vx * dt;
56686
+ const moveY = vel.vy * dt;
56687
+ if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
56661
56688
  item.transformation.applyMatrixSilent({
56662
- translateX: dx,
56663
- translateY: dy,
56689
+ translateX: moveX,
56690
+ translateY: moveY,
56664
56691
  scaleX: 1,
56665
56692
  scaleY: 1,
56666
56693
  shearX: 0,
@@ -56670,7 +56697,7 @@ class GravityEngine {
56670
56697
  }
56671
56698
  }
56672
56699
  syncPositions() {
56673
- const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked);
56700
+ const items = this.board.items.listAll().filter((item) => !item.transformation.isLocked && !EXCLUDED_ITEM_TYPES.has(item.itemType));
56674
56701
  if (items.length === 0)
56675
56702
  return;
56676
56703
  const movedItems = items.map((item) => {
@@ -5,8 +5,10 @@ export declare class GravityEngine {
5
5
  private tickTimer;
6
6
  private syncTimer;
7
7
  private lastSyncedPositions;
8
- readonly G = 500;
9
- readonly DAMPING = 0.98;
8
+ readonly G = 80;
9
+ readonly G_CENTER = 120;
10
+ readonly DAMPING = 0.92;
11
+ readonly REPULSION = 60000;
10
12
  readonly TICK_MS = 33;
11
13
  readonly SYNC_MS = 300;
12
14
  readonly MAX_DISTANCE = 3000;
@@ -40,6 +40,7 @@ export declare class AINode extends BaseItem {
40
40
  serialize(isCopy?: boolean): AINodeData;
41
41
  deserialize(data: Partial<AINodeData>): this;
42
42
  setId(id: string): this;
43
+ protected onParentChanged(newParent: string): void;
43
44
  getId(): string;
44
45
  getContextItems(): string[];
45
46
  getThreadDirection(): ThreadDirection;
@@ -25,6 +25,7 @@ export type SerializedItemData<T extends BaseItemData = BaseItemData> = {
25
25
  } & T;
26
26
  export declare class BaseItem extends Mbr implements Geometry {
27
27
  private defaultItemData?;
28
+ [key: string]: any;
28
29
  readonly transformation: Transformation;
29
30
  readonly linkTo: LinkTo;
30
31
  parent: string;
@@ -70,6 +70,7 @@ export declare class Comment implements Geometry {
70
70
  setResolved(resolved: boolean): void;
71
71
  markThreadAsUnread(userId: number): void;
72
72
  markThreadAsRead(userId: number): void;
73
+ private _syncing;
73
74
  private transform;
74
75
  getUnreadMessages(userId?: number): Message[] | null;
75
76
  getIsThreadMarkedAsUnread(userId: number): boolean;
@@ -6,7 +6,7 @@ import { SelectionContext } from "../../Selection";
6
6
  import { DefaultTextStyles } from "../../Settings";
7
7
  import { Subject } from "../../Subject";
8
8
  import { BaseRange, BaseSelection, Descendant, Operation as SlateOp } from "slate";
9
- import { ItemType, Matrix, Mbr, Point, RichTextData, Transformation } from "..";
9
+ import { ItemType, Mbr, Point, RichTextData, Transformation } from "..";
10
10
  import { HorisontalAlignment, VerticalAlignment } from "../Alignment";
11
11
  import { DrawingContext } from "../DrawingContext";
12
12
  import { LinkTo } from "../LinkTo/LinkTo";
@@ -52,7 +52,6 @@ export declare class RichText extends BaseItem {
52
52
  private _onLimitReached;
53
53
  private shrinkWidth;
54
54
  prevMbr: Mbr | null;
55
- worldMatrixGetter?: () => Matrix;
56
55
  rtCounter: number;
57
56
  constructor(board: Board, container: Mbr, id?: string, transformation?: Transformation, linkTo?: LinkTo, placeholderText?: string, isInShape?: boolean, autoSize?: boolean, insideOf?: ItemType | undefined, initialTextStyles?: DefaultTextStyles);
58
57
  isClosed(): boolean;
@@ -368,6 +368,7 @@ export declare class Shape extends BaseItem {
368
368
  serialize(): ShapeData;
369
369
  deserialize(data: SerializedItemData<ShapeData>): this;
370
370
  setId(id: string): this;
371
+ protected onParentChanged(newParent: string): void;
371
372
  getId(): string;
372
373
  apply(op: Operation): void;
373
374
  private applyShapeOperation;
@@ -43,6 +43,7 @@ export declare class Sticker extends BaseItem {
43
43
  deserialize(data: Partial<StickerData>): this;
44
44
  private transformPath;
45
45
  setId(id: string): this;
46
+ protected onParentChanged(newParent: string): void;
46
47
  getId(): string;
47
48
  apply(op: Operation): void;
48
49
  getBackgroundColor(): ColorValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microboard-temp",
3
- "version": "0.12.1",
3
+ "version": "0.12.2",
4
4
  "description": "A flexible interactive whiteboard library",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",