microboard-temp 0.13.31 → 0.13.33

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/node.js CHANGED
@@ -5272,11 +5272,12 @@ var conf = {
5272
5272
  DEFAULT_GAME_ITEM_DIMENSIONS: { width: 200, height: 200 },
5273
5273
  MAX_CARD_SIZE: 500,
5274
5274
  CONNECTOR_ITEM_OFFSET: 20,
5275
- FG_SPRING_K: 3,
5275
+ FG_SPRING_K: 0.2,
5276
5276
  FG_TARGET_GAP: 20,
5277
- FG_REPULSION: 400000,
5278
- FG_DAMPING: 0.9,
5279
- FG_SLEEP_THRESHOLD: 10,
5277
+ FG_REPULSION: 100,
5278
+ FG_MIN_DIST_SQ: 100,
5279
+ FG_DAMPING: 0.6,
5280
+ FG_SLEEP_THRESHOLD: 0.5,
5280
5281
  GRAVITY_G: 80,
5281
5282
  GRAVITY_G_CENTER: 120,
5282
5283
  GRAVITY_DAMPING: 0.96,
@@ -8052,11 +8053,11 @@ class SessionStorage {
8052
8053
  getFontHighlight(itemType) {
8053
8054
  return this.get(`fontHighlightColor_${itemType}`);
8054
8055
  }
8055
- setHorizontalAlignment(itemType, horizontalAlignment) {
8056
- this.set(`fontHorizontalAlignment_${itemType}`, horizontalAlignment);
8056
+ setHorisontalAlignment(itemType, horisontalAlignment) {
8057
+ this.set(`fontHorisontalAlignment_${itemType}`, horisontalAlignment);
8057
8058
  }
8058
- getHorizontalAlignment(itemType) {
8059
- return this.get(`fontHorizontalAlignment_${itemType}`);
8059
+ getHorisontalAlignment(itemType) {
8060
+ return this.get(`fontHorisontalAlignment_${itemType}`);
8060
8061
  }
8061
8062
  setVerticalAlignment(itemType, verticalAlignment) {
8062
8063
  this.set(`fontVerticalAlignment_${itemType}`, verticalAlignment);
@@ -19746,7 +19747,7 @@ class EditorContainer {
19746
19747
  break;
19747
19748
  case "setSelectionFontHighlight":
19748
19749
  case "setSelectionFontStyle":
19749
- case "setSelectionHorizontalAlignment":
19750
+ case "setSelectionHorisontalAlignment":
19750
19751
  this.applySelectionOp(op);
19751
19752
  break;
19752
19753
  case "setFontStyle":
@@ -23365,14 +23366,14 @@ class SpatialIndex {
23365
23366
  if ("index" in item && item.index) {
23366
23367
  item.removeChildItems(item.index.list());
23367
23368
  }
23369
+ this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
23370
+ this.itemsIndex.remove(item);
23368
23371
  if (item.parent !== "Board") {
23369
23372
  const parentFrame = this.items.getById(item.parent);
23370
23373
  parentFrame?.removeChildItems(item);
23371
23374
  this.subject.publish(this.items);
23372
23375
  return;
23373
23376
  }
23374
- this.itemsArray.splice(this.itemsArray.indexOf(item), 1);
23375
- this.itemsIndex.remove(item);
23376
23377
  if (this.itemsArray.length === 0) {
23377
23378
  this.Mbr = new Mbr;
23378
23379
  } else {
@@ -23393,7 +23394,8 @@ class SpatialIndex {
23393
23394
  translateX: worldMatrix.translateX,
23394
23395
  translateY: worldMatrix.translateY,
23395
23396
  scaleX: worldMatrix.scaleX,
23396
- scaleY: worldMatrix.scaleY
23397
+ scaleY: worldMatrix.scaleY,
23398
+ isLocked: false
23397
23399
  };
23398
23400
  }
23399
23401
  return serialized;
@@ -23740,10 +23742,6 @@ class Items {
23740
23742
  const unmodifiedSize = size;
23741
23743
  size = 16;
23742
23744
  const tolerated = this.index.getEnclosedOrCrossed(x - size, y - size, x + size, y + size);
23743
- const groups = tolerated.filter((item) => item.itemType === "Group");
23744
- if (groups.length > 0) {
23745
- return groups;
23746
- }
23747
23745
  let enclosed = tolerated.some((item) => item instanceof Connector2) ? tolerated : this.index.getEnclosedOrCrossed(x, y, x, y);
23748
23746
  const underPointer = this.getUnderPoint(new Point(x, y), size);
23749
23747
  if (enclosed.length === 0) {
@@ -23757,7 +23755,7 @@ class Items {
23757
23755
  if (item.itemType === "Drawing" && !item.isPointNearLine(this.pointer.point)) {
23758
23756
  return acc;
23759
23757
  }
23760
- const isItemTransparent = item instanceof Shape && item?.getBackgroundColor() === "none";
23758
+ const isItemTransparent = item instanceof Shape && item.getBackgroundColor() === "none";
23761
23759
  const itemZIndex = this.getZIndex(item);
23762
23760
  const accZIndex = this.getZIndex(acc.nearest);
23763
23761
  if (itemZIndex > accZIndex && (!isItemTransparent || area === acc.area) || area < acc.area) {
@@ -23853,7 +23851,7 @@ class Items {
23853
23851
  });
23854
23852
  const childrenMap = new Map;
23855
23853
  const GroupsHTML = groups.map((group) => {
23856
- group.getChildrenIds().forEach((childId) => childrenMap.set(childId, group.getId()));
23854
+ group.getChildrenIds()?.forEach((childId) => childrenMap.set(childId, group.getId()));
23857
23855
  const html = group.renderHTML(documentFactory);
23858
23856
  translateElementBy(html, -lowestCoordinates.left, -lowestCoordinates.top);
23859
23857
  return html;
@@ -23869,7 +23867,10 @@ class Items {
23869
23867
  item.setAttribute("data-end-point-x", (endX - lowestCoordinates.left).toString());
23870
23868
  item.setAttribute("data-end-point-y", (endY - lowestCoordinates.top).toString());
23871
23869
  }
23872
- return translateElementBy(item, -lowestCoordinates.left, -lowestCoordinates.top);
23870
+ if (!childrenMap.get(item.id)) {
23871
+ return translateElementBy(item, -lowestCoordinates.left, -lowestCoordinates.top);
23872
+ }
23873
+ return item;
23873
23874
  });
23874
23875
  for (const item of restHTML) {
23875
23876
  const parentFrameId = childrenMap.get(item.id);
@@ -24283,6 +24284,20 @@ class BaseItem extends Mbr {
24283
24284
  parentMatrix.apply(c);
24284
24285
  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));
24285
24286
  }
24287
+ hasAncestor(itemId) {
24288
+ let parentId = this.parent;
24289
+ while (parentId && parentId !== "Board") {
24290
+ if (parentId === itemId) {
24291
+ return true;
24292
+ }
24293
+ const parent = this.board.items.getById(parentId);
24294
+ if (!parent || parent.parent === parentId) {
24295
+ break;
24296
+ }
24297
+ parentId = parent.parent;
24298
+ }
24299
+ return false;
24300
+ }
24286
24301
  applyAddChildren(childIds) {
24287
24302
  if (!this.index) {
24288
24303
  return;
@@ -24290,7 +24305,7 @@ class BaseItem extends Mbr {
24290
24305
  const containerNestingMatrix = this.getNestingMatrix();
24291
24306
  childIds.forEach((childId) => {
24292
24307
  const foundItem = this.board.items.getById(childId);
24293
- if (this.parent !== childId && this.getId() !== childId) {
24308
+ if (this.parent !== childId && this.getId() !== childId && !this.hasAncestor(childId)) {
24294
24309
  if (!this.index?.getById(childId) && foundItem) {
24295
24310
  const localMatrix = foundItem.transformation.toMatrix().toLocalOf(containerNestingMatrix);
24296
24311
  this.board.items.index.remove(foundItem);
@@ -24513,8 +24528,8 @@ class BaseItem extends Mbr {
24513
24528
  }
24514
24529
  renderHTML(documentFactory) {
24515
24530
  const div = documentFactory.createElement("base-item");
24516
- const { translateX, translateY } = this.transformation.getMatrixData();
24517
- const transform = `translate(${translateX}px, ${translateY}px) scale(1, 1)`;
24531
+ const { translateX, translateY, scaleX, scaleY } = this.transformation.getMatrixData();
24532
+ const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
24518
24533
  div.style.backgroundColor = "#b2b0c3";
24519
24534
  div.id = this.getId();
24520
24535
  div.style.width = `${this.getWidth()}px`;
@@ -24785,12 +24800,14 @@ class RichText extends BaseItem {
24785
24800
  top = container.top;
24786
24801
  }
24787
24802
  const point3 = new Point(left, top);
24788
- this.getParentWorldMatrix().apply(point3);
24803
+ if (!this.isInShape || this.autoSize) {
24804
+ this.getParentWorldMatrix().apply(point3);
24805
+ }
24789
24806
  return {
24790
24807
  point: point3,
24791
24808
  width,
24792
24809
  height,
24793
- maxWidth: maxWidth ? maxWidth + 1 : undefined,
24810
+ maxWidth: maxWidth ? maxWidth : undefined,
24794
24811
  maxHeight,
24795
24812
  textScale: this.isInShape && !this.autoSize ? 1 : this.getScale()
24796
24813
  };
@@ -42479,6 +42496,7 @@ class Shape extends BaseItem {
42479
42496
  this.text.deserialize(data.text);
42480
42497
  }
42481
42498
  this.transformPath();
42499
+ this.text.updateElement();
42482
42500
  this.subject.publish(this);
42483
42501
  return this;
42484
42502
  }
@@ -42696,7 +42714,7 @@ class Shape extends BaseItem {
42696
42714
  if (Shapes[this.shapeType].useMbrUnderPointer) {
42697
42715
  return this.mbr.isUnderPoint(point5);
42698
42716
  }
42699
- if (this.text.isEmpty() && (this.backgroundOpacity === 0 || this.backgroundColor === "none" || this.backgroundColor === "")) {
42717
+ if (this.text.isEmpty() && (this.backgroundOpacity === 0 || this.backgroundColor === "none" || this.backgroundColor === "transparent" || this.backgroundColor === "")) {
42700
42718
  return this.path.isPointOverEdges(point5, tolerance);
42701
42719
  } else {
42702
42720
  return this.textContainer.isUnderPoint(point5) || this.path.isUnderPoint(point5);
@@ -42748,8 +42766,8 @@ class Shape extends BaseItem {
42748
42766
  const pathElement = Shapes[this.shapeType].path.copy().renderHTML(documentFactory);
42749
42767
  const paths = Array.isArray(pathElement) ? pathElement : [pathElement];
42750
42768
  paths.forEach((element3) => {
42751
- element3.setAttribute("fill", this.backgroundColor);
42752
- element3.setAttribute("stroke", this.borderColor);
42769
+ element3.setAttribute("fill", resolveColor(this.backgroundColor, conf.theme, "background"));
42770
+ element3.setAttribute("stroke", resolveColor(this.borderColor, conf.theme, "foreground"));
42753
42771
  element3.setAttribute("stroke-dasharray", LinePatterns[this.borderStyle].join(", "));
42754
42772
  element3.setAttribute("stroke-width", this.borderWidth.toString());
42755
42773
  element3.setAttribute("transform-origin", "0 0");
@@ -42764,8 +42782,8 @@ class Shape extends BaseItem {
42764
42782
  div.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
42765
42783
  div.style.position = "absolute";
42766
42784
  div.setAttribute("data-shape-type", this.shapeType);
42767
- div.setAttribute("fill", this.backgroundColor);
42768
- div.setAttribute("stroke", this.borderColor);
42785
+ div.setAttribute("fill", resolveColor(this.backgroundColor, conf.theme, "background"));
42786
+ div.setAttribute("stroke", resolveColor(this.borderColor, conf.theme, "foreground"));
42769
42787
  div.setAttribute("data-border-style", this.borderStyle);
42770
42788
  div.setAttribute("stroke-dasharray", LinePatterns[this.borderStyle].join(", "));
42771
42789
  div.setAttribute("stroke-width", this.borderWidth.toString());
@@ -42809,9 +42827,6 @@ class Shape extends BaseItem {
42809
42827
  this.text.updateElement();
42810
42828
  }
42811
42829
  transformPath() {
42812
- if (conf.isNode()) {
42813
- return;
42814
- }
42815
42830
  this.path = Shapes[this.shapeType].createPath(this.mbr);
42816
42831
  this.textContainer = Shapes[this.shapeType].textBounds.copy();
42817
42832
  this.text.setContainer(this.textContainer.copy());
@@ -45976,6 +45991,7 @@ class Group extends BaseItem {
45976
45991
  constructor(board, events, children = [], id = "") {
45977
45992
  super(board, id, undefined, true);
45978
45993
  this.events = events;
45994
+ this.canBeNested = true;
45979
45995
  this.linkTo = new LinkTo(this.id, this.events);
45980
45996
  this.transformation = new Transformation(this.id, this.events);
45981
45997
  this.transformation.subject.subscribe(() => {
@@ -46118,7 +46134,13 @@ class Group extends BaseItem {
46118
46134
  ctx.restore();
46119
46135
  }
46120
46136
  renderHTML(documentFactory) {
46121
- return documentFactory.createElement("div");
46137
+ const div = documentFactory.createElement("div");
46138
+ div.id = this.id;
46139
+ const { translateX, translateY, scaleX, scaleY } = this.transformation.getMatrixData();
46140
+ div.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
46141
+ div.style.position = "absolute";
46142
+ div.style.transformOrigin = "0 0";
46143
+ return div;
46122
46144
  }
46123
46145
  }
46124
46146
  // src/itemFactories.ts
@@ -49404,7 +49426,8 @@ class Select extends Tool {
49404
49426
  this.beginTimeStamp = Date.now();
49405
49427
  const selectionMbr = selection.getMbr();
49406
49428
  const selectionItems = selection.list();
49407
- this.isDownOnSelection = selectionMbr !== undefined && selectionMbr.isUnderPoint(pointer.point) && hover.every((hovered) => selectionItems.some((selected) => selected.getId() === hovered.getId()));
49429
+ const selectableHover = hover.map((item) => this.board.selection.getSelectableItem(item));
49430
+ this.isDownOnSelection = selectionMbr !== undefined && selectionMbr.isUnderPoint(pointer.point) && selectableHover.every((hovered) => hovered && selectionItems.some((selected) => selected.getId() === hovered.getId()));
49408
49431
  this.isDraggingSelection = this.isDownOnSelection;
49409
49432
  if (this.isDraggingSelection) {
49410
49433
  this.board.selection.transformationRenderBlock = true;
@@ -49730,7 +49753,7 @@ class Select extends Tool {
49730
49753
  const hovered = this.board.items.getUnderPointer();
49731
49754
  this.board.pointer.subject.publish(this.board.pointer);
49732
49755
  if (isCtrl || isShift) {
49733
- const underPointer = hovered[0];
49756
+ const underPointer = this.board.selection.getSelectableItem(hovered[0]);
49734
49757
  const isEmptySelection = this.board.selection.items.list().length === 0;
49735
49758
  if (!underPointer && !isEmptySelection && isShift) {
49736
49759
  this.board.selection.add(this.board.selection.items.list());
@@ -49746,14 +49769,6 @@ class Select extends Tool {
49746
49769
  const isNotInSelection = this.board.selection.items.findById(underPointer.getId()) === null;
49747
49770
  if (isNotInSelection) {
49748
49771
  this.board.selection.add(underPointer);
49749
- if ("index" in underPointer && underPointer.index) {
49750
- const { left, right, top, bottom } = underPointer.getMbr();
49751
- const childrenIds = underPointer.getChildrenIds();
49752
- console.log("UNDERPOINTER", underPointer);
49753
- console.log("CHILDREN", childrenIds);
49754
- const itemsInFrame = this.board.items.getEnclosedOrCrossed(left, top, right, bottom).filter((item) => childrenIds && childrenIds.includes(item.getId()));
49755
- this.board.selection.add(itemsInFrame);
49756
- }
49757
49772
  this.board.selection.setContext("EditUnderPointer");
49758
49773
  } else {
49759
49774
  this.board.selection.remove(underPointer);
@@ -49770,10 +49785,6 @@ class Select extends Tool {
49770
49785
  } else {
49771
49786
  this.board.selection.editUnderPointer();
49772
49787
  }
49773
- if (topItem2 instanceof Group) {
49774
- const groupChildren = topItem2.getChildren();
49775
- this.board.selection.add(groupChildren);
49776
- }
49777
49788
  this.board.tools.publish();
49778
49789
  this.clear();
49779
49790
  return false;
@@ -55809,10 +55820,23 @@ class BoardSelection {
55809
55820
  getMbr() {
55810
55821
  return this.items.getMbr();
55811
55822
  }
55823
+ getSelectableItem(item) {
55824
+ if (!item) {
55825
+ return null;
55826
+ }
55827
+ if (!(item instanceof BaseItem) || item.parent === "Board") {
55828
+ return item;
55829
+ }
55830
+ const parent = this.board.items.getById(item.parent);
55831
+ if (parent instanceof Group) {
55832
+ return parent;
55833
+ }
55834
+ return item;
55835
+ }
55812
55836
  selectUnderPointer() {
55813
55837
  this.removeAll();
55814
55838
  const stack = this.board.items.getUnderPointer();
55815
- const top = stack.pop();
55839
+ const top = this.getSelectableItem(stack.pop());
55816
55840
  if (top) {
55817
55841
  this.add(top);
55818
55842
  this.setTextToEdit(undefined);
@@ -55866,7 +55890,7 @@ class BoardSelection {
55866
55890
  editUnderPointer() {
55867
55891
  this.removeAll();
55868
55892
  const stack = this.board.items.getUnderPointer();
55869
- const item = stack.pop();
55893
+ const item = this.getSelectableItem(stack.pop());
55870
55894
  if (item) {
55871
55895
  this.add(item);
55872
55896
  this.setTextToEdit(undefined);
@@ -55900,7 +55924,7 @@ class BoardSelection {
55900
55924
  const textSize = tempStorage.getFontSize(item.itemType);
55901
55925
  const highlightColor = tempStorage.getFontHighlight(item.itemType);
55902
55926
  const styles = tempStorage.getFontStyles(item.itemType);
55903
- const horizontalAlignment = tempStorage.getHorizontalAlignment(item.itemType);
55927
+ const horisontalAlignment = tempStorage.getHorisontalAlignment(item.itemType);
55904
55928
  const verticalAlignment = tempStorage.getVerticalAlignment(item.itemType);
55905
55929
  if (textColor) {
55906
55930
  text5.setSelectionFontColor(textColor, "None");
@@ -55921,8 +55945,8 @@ class BoardSelection {
55921
55945
  const stylesArr = styles;
55922
55946
  text5.setSelectionFontStyle(stylesArr, "None");
55923
55947
  }
55924
- if (horizontalAlignment && !(item instanceof Sticker)) {
55925
- text5.setSelectionHorisontalAlignment(horizontalAlignment);
55948
+ if (horisontalAlignment && !(item instanceof Sticker)) {
55949
+ text5.setSelectionHorisontalAlignment(horisontalAlignment);
55926
55950
  }
55927
55951
  if (verticalAlignment && !(item instanceof Sticker)) {
55928
55952
  this.setVerticalAlignment(verticalAlignment);
@@ -55935,7 +55959,7 @@ class BoardSelection {
55935
55959
  editTextUnderPointer() {
55936
55960
  this.removeAll();
55937
55961
  const stack = this.board.items.getUnderPointer();
55938
- const top = stack.pop();
55962
+ const top = this.getSelectableItem(stack.pop());
55939
55963
  if (top) {
55940
55964
  this.add(top);
55941
55965
  this.setContext("EditTextUnderPointer");
@@ -56545,7 +56569,7 @@ class BoardSelection {
56545
56569
  selection: text5.editor.getSelection(),
56546
56570
  ops
56547
56571
  });
56548
- tempStorage.setHorizontalAlignment(item.itemType, horisontalAlignment);
56572
+ tempStorage.setHorisontalAlignment(item.itemType, horisontalAlignment);
56549
56573
  }
56550
56574
  this.emitApplied({
56551
56575
  class: "RichText",
@@ -56970,7 +56994,6 @@ class ForceGraphEngine {
56970
56994
  activeComponents = new Map;
56971
56995
  TICK_MS = 33;
56972
56996
  SYNC_MS = 300;
56973
- SOFTENING_SQ = 100 * 100;
56974
56997
  MIN_MOVE_PX = 0.05;
56975
56998
  constructor(board) {
56976
56999
  this.board = board;
@@ -57119,42 +57142,27 @@ class ForceGraphEngine {
57119
57142
  return this.board.items.listAll().filter((item) => item.itemType === "Connector");
57120
57143
  }
57121
57144
  tick() {
57122
- const dt = this.TICK_MS / 1000;
57123
57145
  const activeIds = this.getActiveNodeIds();
57124
57146
  const draggedIds = this.board.getDraggedItemIds();
57125
57147
  const allNodes = this.getNodes();
57126
- const nodes = allNodes.filter((item) => {
57127
- if (!activeIds.has(item.getId()))
57128
- return false;
57129
- if (draggedIds.has(item.getId()))
57130
- return false;
57131
- if (item.parent !== "Board" && draggedIds.has(item.parent))
57132
- return false;
57133
- return true;
57134
- });
57135
- if (nodes.length < 1)
57136
- return;
57137
57148
  const snapMap = new Map;
57138
- for (const item of nodes) {
57149
+ for (const item of allNodes) {
57150
+ if (!activeIds.has(item.getId()))
57151
+ continue;
57139
57152
  const pos = item.transformation.getTranslation();
57140
57153
  const mbr = item.getMbr();
57141
57154
  const w = Math.max(mbr.getWidth(), 1);
57142
57155
  const h2 = Math.max(mbr.getHeight(), 1);
57143
- snapMap.set(item.getId(), {
57144
- id: item.getId(),
57145
- cx: pos.x + w * 0.5,
57146
- cy: pos.y + h2 * 0.5,
57147
- w,
57148
- h: h2
57149
- });
57156
+ snapMap.set(item.getId(), { id: item.getId(), cx: pos.x + w * 0.5, cy: pos.y + h2 * 0.5, w, h: h2 });
57150
57157
  }
57151
57158
  const snap = Array.from(snapMap.values());
57159
+ if (snap.length < 1)
57160
+ return;
57152
57161
  const uf = new UnionFind;
57153
57162
  for (const connector of this.getConnectors()) {
57154
57163
  const { startItem, endItem } = connector.getConnectedItems();
57155
- if (startItem && endItem) {
57164
+ if (startItem && endItem)
57156
57165
  uf.union(startItem.getId(), endItem.getId());
57157
- }
57158
57166
  }
57159
57167
  const ax = new Map;
57160
57168
  const ay = new Map;
@@ -57172,14 +57180,13 @@ class ForceGraphEngine {
57172
57180
  continue;
57173
57181
  const dx = s2.cx - s1.cx;
57174
57182
  const dy = s2.cy - s1.cy;
57175
- const dist = Math.sqrt(dx * dx + dy * dy) + 0.001;
57183
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
57176
57184
  const compId = this.findComponentId(s1.id);
57177
57185
  const targetGap = compId ? this.activeComponents.get(compId)?.targetGap ?? conf.FG_TARGET_GAP : conf.FG_TARGET_GAP;
57178
57186
  const targetDist = (Math.max(s1.w, s1.h) + Math.max(s2.w, s2.h)) * 0.5 + targetGap;
57179
- const stretch = dist - targetDist;
57180
- const forceMag = stretch * conf.FG_SPRING_K;
57181
- const fx = dx / dist * forceMag;
57182
- const fy = dy / dist * forceMag;
57187
+ const force = (dist - targetDist) * conf.FG_SPRING_K;
57188
+ const fx = dx / dist * force;
57189
+ const fy = dy / dist * force;
57183
57190
  ax.set(s1.id, (ax.get(s1.id) ?? 0) + fx);
57184
57191
  ay.set(s1.id, (ay.get(s1.id) ?? 0) + fy);
57185
57192
  ax.set(s2.id, (ax.get(s2.id) ?? 0) - fx);
@@ -57193,35 +57200,35 @@ class ForceGraphEngine {
57193
57200
  continue;
57194
57201
  const dx = s2.cx - s1.cx;
57195
57202
  const dy = s2.cy - s1.cy;
57196
- const centerDist = Math.sqrt(dx * dx + dy * dy) + 0.001;
57197
- const r1 = Math.max(s1.w, s1.h) * 0.5;
57198
- const r2 = Math.max(s2.w, s2.h) * 0.5;
57199
- const edgeDist = Math.max(centerDist - r1 - r2, 1);
57200
- const repMag = conf.FG_REPULSION / (edgeDist * edgeDist + this.SOFTENING_SQ);
57201
- const fx = dx / centerDist * repMag;
57202
- const fy = dy / centerDist * repMag;
57203
- ax.set(s1.id, (ax.get(s1.id) ?? 0) - fx);
57204
- ay.set(s1.id, (ay.get(s1.id) ?? 0) - fy);
57205
- ax.set(s2.id, (ax.get(s2.id) ?? 0) + fx);
57206
- ay.set(s2.id, (ay.get(s2.id) ?? 0) + fy);
57203
+ const distSq = Math.max(dx * dx + dy * dy, conf.FG_MIN_DIST_SQ);
57204
+ const force = conf.FG_REPULSION / distSq;
57205
+ ax.set(s1.id, (ax.get(s1.id) ?? 0) - dx * force);
57206
+ ay.set(s1.id, (ay.get(s1.id) ?? 0) - dy * force);
57207
+ ax.set(s2.id, (ax.get(s2.id) ?? 0) + dx * force);
57208
+ ay.set(s2.id, (ay.get(s2.id) ?? 0) + dy * force);
57207
57209
  }
57208
57210
  }
57209
57211
  let totalEnergy = 0;
57210
- for (const item of nodes) {
57212
+ for (const item of allNodes) {
57211
57213
  const id = item.getId();
57212
- if (!this.velocities.has(id)) {
57214
+ if (!activeIds.has(id))
57215
+ continue;
57216
+ if (!this.velocities.has(id))
57213
57217
  this.velocities.set(id, { vx: 0, vy: 0 });
57214
- }
57215
57218
  const vel = this.velocities.get(id);
57216
- vel.vx = (vel.vx + (ax.get(id) ?? 0) * dt) * conf.FG_DAMPING;
57217
- vel.vy = (vel.vy + (ay.get(id) ?? 0) * dt) * conf.FG_DAMPING;
57218
- totalEnergy += vel.vx * vel.vx + vel.vy * vel.vy;
57219
- const moveX = vel.vx * dt;
57220
- const moveY = vel.vy * dt;
57221
- if (Math.abs(moveX) >= this.MIN_MOVE_PX || Math.abs(moveY) >= this.MIN_MOVE_PX) {
57219
+ const isDragged = draggedIds.has(id) || item.parent !== "Board" && draggedIds.has(item.parent);
57220
+ if (isDragged) {
57221
+ vel.vx = 0;
57222
+ vel.vy = 0;
57223
+ continue;
57224
+ }
57225
+ vel.vx = (vel.vx + (ax.get(id) ?? 0)) * conf.FG_DAMPING;
57226
+ vel.vy = (vel.vy + (ay.get(id) ?? 0)) * conf.FG_DAMPING;
57227
+ totalEnergy += Math.abs(vel.vx) + Math.abs(vel.vy);
57228
+ if (Math.abs(vel.vx) >= this.MIN_MOVE_PX || Math.abs(vel.vy) >= this.MIN_MOVE_PX) {
57222
57229
  item.transformation.applyMatrixSilent({
57223
- translateX: moveX,
57224
- translateY: moveY,
57230
+ translateX: vel.vx,
57231
+ translateY: vel.vy,
57225
57232
  scaleX: 1,
57226
57233
  scaleY: 1,
57227
57234
  shearX: 0,
@@ -57482,9 +57489,10 @@ class Board {
57482
57489
  if (!item || !(item instanceof Group)) {
57483
57490
  return;
57484
57491
  }
57485
- item.getChildren().forEach((item2) => {
57486
- item2.transformation.isLocked = false;
57487
- item2.parent = "Board";
57492
+ const children = [...item.getChildren()];
57493
+ item.applyRemoveChildren(children.map((child) => child.getId()));
57494
+ children.forEach((child) => {
57495
+ child.transformation.isLocked = false;
57488
57496
  });
57489
57497
  item.transformation.isLocked = false;
57490
57498
  const removedItems = [];
@@ -57499,9 +57507,7 @@ class Board {
57499
57507
  if (!item || !(item instanceof Group)) {
57500
57508
  return;
57501
57509
  }
57502
- item.getChildren().forEach((item2) => {
57503
- item2.parent = "Board";
57504
- });
57510
+ item.applyRemoveChildren(item.getChildrenIds());
57505
57511
  const removedItems = [];
57506
57512
  this.findItemAndApply(op.item, (item2) => {
57507
57513
  this.index.remove(item2);
@@ -10,7 +10,6 @@ export declare class ForceGraphEngine {
10
10
  private activeComponents;
11
11
  private readonly TICK_MS;
12
12
  private readonly SYNC_MS;
13
- private readonly SOFTENING_SQ;
14
13
  private readonly MIN_MOVE_PX;
15
14
  constructor(board: Board);
16
15
  /**
@@ -88,6 +88,7 @@ export declare class BaseItem extends Mbr implements Geometry {
88
88
  * through the world matrix to produce the correct world-space bounds.
89
89
  */
90
90
  getWorldMbr(): Mbr;
91
+ private hasAncestor;
91
92
  applyAddChildren(childIds: string[]): void;
92
93
  applyRemoveChildren(childIds: string[]): void;
93
94
  updateMbr(): void;
@@ -39,7 +39,7 @@ interface SetMaxWidth extends RichTextBaseOp {
39
39
  method: 'setMaxWidth';
40
40
  maxWidth: number | undefined;
41
41
  }
42
- export type SelectionMethod = 'setSelectionHorizontalAlignment' | 'setSelectionFontHighlight' | 'setSelectionFontSize' | 'setSelectionFontFamily' | 'setSelectionFontStyle' | 'setSelectionFontColor' | 'setSelectionBlockType' | 'edit';
42
+ export type SelectionMethod = 'setSelectionHorisontalAlignment' | 'setSelectionFontHighlight' | 'setSelectionFontSize' | 'setSelectionFontFamily' | 'setSelectionFontStyle' | 'setSelectionFontColor' | 'setSelectionBlockType' | 'edit';
43
43
  export interface SelectionOp extends RichTextBaseOp {
44
44
  method: SelectionMethod;
45
45
  selection: BaseSelection;
@@ -66,6 +66,7 @@ export declare class BoardSelection {
66
66
  disable(): void;
67
67
  setContext(context: SelectionContext): void;
68
68
  getMbr(): Mbr | undefined;
69
+ getSelectableItem(item: Item | null | undefined): Item | null;
69
70
  selectUnderPointer(): void;
70
71
  editSelected(): void;
71
72
  editText(shouldReplace?: string, moveCursorToEnd?: boolean, shouldSelect?: boolean): void;
@@ -44,8 +44,8 @@ export declare class SessionStorage {
44
44
  getFontColor(itemType: string): string | undefined;
45
45
  setFontHighlight(itemType: string, highlightColor: string): void;
46
46
  getFontHighlight(itemType: string): string | undefined;
47
- setHorizontalAlignment(itemType: string, horizontalAlignment: 'left' | 'center' | 'right'): void;
48
- getHorizontalAlignment(itemType: string): 'left' | 'center' | 'right' | undefined;
47
+ setHorisontalAlignment(itemType: string, horisontalAlignment: 'left' | 'center' | 'right'): void;
48
+ getHorisontalAlignment(itemType: string): 'left' | 'center' | 'right' | undefined;
49
49
  setVerticalAlignment(itemType: string, verticalAlignment: 'top' | 'center' | 'bottom'): void;
50
50
  getVerticalAlignment(itemType: string): 'top' | 'center' | 'bottom' | undefined;
51
51
  setLastAIRequest(request: string): void;
@@ -250,6 +250,7 @@ export declare const conf: {
250
250
  FG_SPRING_K: number;
251
251
  FG_TARGET_GAP: number;
252
252
  FG_REPULSION: number;
253
+ FG_MIN_DIST_SQ: number;
253
254
  FG_DAMPING: number;
254
255
  FG_SLEEP_THRESHOLD: number;
255
256
  GRAVITY_G: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "microboard-temp",
3
- "version": "0.13.31",
3
+ "version": "0.13.33",
4
4
  "description": "A flexible interactive whiteboard library",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",