@blorkfield/overlay-core 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -595,6 +595,7 @@ declare class OverlayScene {
595
595
  private gravityOverrideEntries;
596
596
  private followWindowEntries;
597
597
  private pressureObstacleIds;
598
+ private activeCollisions;
598
599
  static createContainer(parent: HTMLElement, options?: ContainerOptions): {
599
600
  canvas: HTMLCanvasElement;
600
601
  bounds: Bounds;
@@ -623,6 +624,7 @@ declare class OverlayScene {
623
624
  * Emits objectCollision lifecycle events.
624
625
  */
625
626
  private handleCollisionStart;
627
+ private handleCollisionEnd;
626
628
  /** Get a display name for an obstacle (letter char or short ID) */
627
629
  private getObstacleDisplayName;
628
630
  /** Update pressure tracking - check which dynamic objects rest on static obstacles */
@@ -860,6 +862,20 @@ declare class OverlayScene {
860
862
  * @param callback - The callback to remove
861
863
  */
862
864
  off<T extends LifecycleEvent>(event: T, callback: LifecycleCallback<T>): void;
865
+ /**
866
+ * Get the IDs of all objects currently colliding with a given object.
867
+ * @param id - The ID of the object to query
868
+ * @returns Array of IDs of objects currently in contact with it
869
+ */
870
+ getCollidingWith(id: string): string[];
871
+ /**
872
+ * Get all currently active collision pairs.
873
+ * @returns Array of `{ a, b }` pairs where `a` and `b` are colliding object IDs
874
+ */
875
+ getActiveCollisions(): Array<{
876
+ a: string;
877
+ b: string;
878
+ }>;
863
879
  /** Create ObjectState from an ObjectEntry */
864
880
  private toObjectState;
865
881
  /** Emit a lifecycle event to all registered callbacks */
package/dist/index.d.ts CHANGED
@@ -595,6 +595,7 @@ declare class OverlayScene {
595
595
  private gravityOverrideEntries;
596
596
  private followWindowEntries;
597
597
  private pressureObstacleIds;
598
+ private activeCollisions;
598
599
  static createContainer(parent: HTMLElement, options?: ContainerOptions): {
599
600
  canvas: HTMLCanvasElement;
600
601
  bounds: Bounds;
@@ -623,6 +624,7 @@ declare class OverlayScene {
623
624
  * Emits objectCollision lifecycle events.
624
625
  */
625
626
  private handleCollisionStart;
627
+ private handleCollisionEnd;
626
628
  /** Get a display name for an obstacle (letter char or short ID) */
627
629
  private getObstacleDisplayName;
628
630
  /** Update pressure tracking - check which dynamic objects rest on static obstacles */
@@ -860,6 +862,20 @@ declare class OverlayScene {
860
862
  * @param callback - The callback to remove
861
863
  */
862
864
  off<T extends LifecycleEvent>(event: T, callback: LifecycleCallback<T>): void;
865
+ /**
866
+ * Get the IDs of all objects currently colliding with a given object.
867
+ * @param id - The ID of the object to query
868
+ * @returns Array of IDs of objects currently in contact with it
869
+ */
870
+ getCollidingWith(id: string): string[];
871
+ /**
872
+ * Get all currently active collision pairs.
873
+ * @returns Array of `{ a, b }` pairs where `a` and `b` are colliding object IDs
874
+ */
875
+ getActiveCollisions(): Array<{
876
+ a: string;
877
+ b: string;
878
+ }>;
863
879
  /** Create ObjectState from an ObjectEntry */
864
880
  private toObjectState;
865
881
  /** Emit a lifecycle event to all registered callbacks */
package/dist/index.js CHANGED
@@ -1414,6 +1414,8 @@ var OverlayScene = class {
1414
1414
  this.followWindowEntries = /* @__PURE__ */ new Set();
1415
1415
  // IDs of static objects that have pressure thresholds — empty = skip updatePressure entirely
1416
1416
  this.pressureObstacleIds = /* @__PURE__ */ new Set();
1417
+ // Active collision pairs: id -> Set of ids currently colliding with it
1418
+ this.activeCollisions = /* @__PURE__ */ new Map();
1417
1419
  /** Handle mouse down - start grab via programmatic API */
1418
1420
  this.handleMouseDown = (event) => {
1419
1421
  const rect = this.canvas.getBoundingClientRect();
@@ -1480,6 +1482,10 @@ var OverlayScene = class {
1480
1482
  const entryA = this.findObjectByBody(pair.bodyA);
1481
1483
  const entryB = this.findObjectByBody(pair.bodyB);
1482
1484
  if (entryA && entryB) {
1485
+ if (!this.activeCollisions.has(entryA.id)) this.activeCollisions.set(entryA.id, /* @__PURE__ */ new Set());
1486
+ if (!this.activeCollisions.has(entryB.id)) this.activeCollisions.set(entryB.id, /* @__PURE__ */ new Set());
1487
+ this.activeCollisions.get(entryA.id).add(entryB.id);
1488
+ this.activeCollisions.get(entryB.id).add(entryA.id);
1483
1489
  this.emitLifecycleEvent(
1484
1490
  "objectCollision",
1485
1491
  this.toObjectState(entryA),
@@ -1488,6 +1494,16 @@ var OverlayScene = class {
1488
1494
  }
1489
1495
  }
1490
1496
  };
1497
+ this.handleCollisionEnd = (event) => {
1498
+ for (const pair of event.pairs) {
1499
+ const entryA = this.findObjectByBody(pair.bodyA);
1500
+ const entryB = this.findObjectByBody(pair.bodyB);
1501
+ if (entryA && entryB) {
1502
+ this.activeCollisions.get(entryA.id)?.delete(entryB.id);
1503
+ this.activeCollisions.get(entryB.id)?.delete(entryA.id);
1504
+ }
1505
+ }
1506
+ };
1491
1507
  // ==================== PRIVATE ====================
1492
1508
  this.loop = () => {
1493
1509
  const substepDelta = 1e3 / 60 / this.substeps;
@@ -1616,6 +1632,7 @@ var OverlayScene = class {
1616
1632
  Matter5.Events.on(this.render, "beforeRender", this.handleBeforeRender);
1617
1633
  Matter5.Events.on(this.render, "afterRender", this.handleAfterRender);
1618
1634
  Matter5.Events.on(this.engine, "collisionStart", this.handleCollisionStart);
1635
+ Matter5.Events.on(this.engine, "collisionEnd", this.handleCollisionEnd);
1619
1636
  }
1620
1637
  static createContainer(parent, options = {}) {
1621
1638
  const canvas = document.createElement("canvas");
@@ -2019,6 +2036,7 @@ var OverlayScene = class {
2019
2036
  Matter5.Events.off(this.render, "beforeRender", this.handleBeforeRender);
2020
2037
  Matter5.Events.off(this.render, "afterRender", this.handleAfterRender);
2021
2038
  Matter5.Events.off(this.engine, "collisionStart", this.handleCollisionStart);
2039
+ Matter5.Events.off(this.engine, "collisionEnd", this.handleCollisionEnd);
2022
2040
  Matter5.Engine.clear(this.engine);
2023
2041
  this.objects.clear();
2024
2042
  this.gravityOverrideEntries.clear();
@@ -2029,6 +2047,7 @@ var OverlayScene = class {
2029
2047
  this.pressureLogTimer = 0;
2030
2048
  this.floorSegmentPressure.clear();
2031
2049
  this.collapsedSegments.clear();
2050
+ this.activeCollisions.clear();
2032
2051
  this.updateCallbacks = [];
2033
2052
  this.lifecycleCallbacks.objectSpawned = [];
2034
2053
  this.lifecycleCallbacks.objectRemoved = [];
@@ -2480,6 +2499,13 @@ var OverlayScene = class {
2480
2499
  this.gravityOverrideEntries.delete(entry);
2481
2500
  this.followWindowEntries.delete(entry);
2482
2501
  this.pressureObstacleIds.delete(id);
2502
+ const colliding = this.activeCollisions.get(id);
2503
+ if (colliding) {
2504
+ for (const otherId of colliding) {
2505
+ this.activeCollisions.get(otherId)?.delete(id);
2506
+ }
2507
+ this.activeCollisions.delete(id);
2508
+ }
2483
2509
  this.objects.delete(id);
2484
2510
  }
2485
2511
  removeObjects(ids) {
@@ -2729,6 +2755,32 @@ var OverlayScene = class {
2729
2755
  const idx = arr.indexOf(callback);
2730
2756
  if (idx !== -1) arr.splice(idx, 1);
2731
2757
  }
2758
+ /**
2759
+ * Get the IDs of all objects currently colliding with a given object.
2760
+ * @param id - The ID of the object to query
2761
+ * @returns Array of IDs of objects currently in contact with it
2762
+ */
2763
+ getCollidingWith(id) {
2764
+ return Array.from(this.activeCollisions.get(id) ?? []);
2765
+ }
2766
+ /**
2767
+ * Get all currently active collision pairs.
2768
+ * @returns Array of `{ a, b }` pairs where `a` and `b` are colliding object IDs
2769
+ */
2770
+ getActiveCollisions() {
2771
+ const pairs = [];
2772
+ const seen = /* @__PURE__ */ new Set();
2773
+ for (const [id, others] of this.activeCollisions) {
2774
+ for (const otherId of others) {
2775
+ const key = id < otherId ? `${id}:${otherId}` : `${otherId}:${id}`;
2776
+ if (!seen.has(key)) {
2777
+ seen.add(key);
2778
+ pairs.push({ a: id, b: otherId });
2779
+ }
2780
+ }
2781
+ }
2782
+ return pairs;
2783
+ }
2732
2784
  /** Create ObjectState from an ObjectEntry */
2733
2785
  toObjectState(entry) {
2734
2786
  return {