@blorkfield/overlay-core 0.10.0 → 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/README.md +61 -2
- package/dist/index.cjs +52 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -381,6 +381,26 @@ scene.setEffect({
|
|
|
381
381
|
});
|
|
382
382
|
```
|
|
383
383
|
|
|
384
|
+
### Managing Effects
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// Pause/resume an effect without removing it
|
|
388
|
+
scene.setEffectEnabled('my-rain', false); // pause
|
|
389
|
+
scene.setEffectEnabled('my-rain', true); // resume
|
|
390
|
+
|
|
391
|
+
// Check if an effect is enabled
|
|
392
|
+
scene.isEffectEnabled('my-rain'); // → true/false
|
|
393
|
+
|
|
394
|
+
// Get effect config
|
|
395
|
+
const effect = scene.getEffect('my-rain'); // → EffectConfig | undefined
|
|
396
|
+
|
|
397
|
+
// List all effect IDs
|
|
398
|
+
const ids = scene.getEffectIds(); // → string[]
|
|
399
|
+
|
|
400
|
+
// Remove an effect entirely
|
|
401
|
+
scene.removeEffect('my-rain');
|
|
402
|
+
```
|
|
403
|
+
|
|
384
404
|
## Managing Objects
|
|
385
405
|
|
|
386
406
|
```typescript
|
|
@@ -608,7 +628,7 @@ scene.on('objectRemoved', (obj) => {
|
|
|
608
628
|
console.log(`Removed: ${obj.id}`);
|
|
609
629
|
});
|
|
610
630
|
|
|
611
|
-
// Objects collided
|
|
631
|
+
// Objects collided (fires on collision start)
|
|
612
632
|
scene.on('objectCollision', (a, b) => {
|
|
613
633
|
console.log(`Collision: ${a.id} hit ${b.id}`);
|
|
614
634
|
});
|
|
@@ -617,6 +637,23 @@ scene.on('objectCollision', (a, b) => {
|
|
|
617
637
|
scene.off('objectSpawned', myCallback);
|
|
618
638
|
```
|
|
619
639
|
|
|
640
|
+
### Querying Active Collisions
|
|
641
|
+
|
|
642
|
+
The scene tracks which objects are currently in contact, so you can query collision state at any time without maintaining your own bookkeeping:
|
|
643
|
+
|
|
644
|
+
```typescript
|
|
645
|
+
// Get all object IDs currently touching a specific object
|
|
646
|
+
const touching = scene.getCollidingWith('my-object-id'); // string[]
|
|
647
|
+
|
|
648
|
+
// Get all active collision pairs
|
|
649
|
+
const pairs = scene.getActiveCollisions(); // Array<{ a: string, b: string }>
|
|
650
|
+
for (const { a, b } of pairs) {
|
|
651
|
+
console.log(`${a} is touching ${b}`);
|
|
652
|
+
}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
These reflect live physics state — pairs are added on `collisionStart` and removed on `collisionEnd`. Only tracked objects are included (floor, boundaries, and DOM obstacles are excluded).
|
|
656
|
+
|
|
620
657
|
## Font Setup
|
|
621
658
|
|
|
622
659
|
### Bundled Fonts
|
|
@@ -820,6 +857,23 @@ scene.setObjectMassOverride(id, 50); // now heavy
|
|
|
820
857
|
scene.setObjectMassOverride(id, null); // restore natural mass
|
|
821
858
|
```
|
|
822
859
|
|
|
860
|
+
### Scale
|
|
861
|
+
|
|
862
|
+
`setObjectScale(id, x, y)` resizes an object at runtime. Both the physics collision shape and sprite rendering are updated together. Scale is absolute — calling `setObjectScale(id, 2, 2)` always doubles the original size regardless of current scale. Scaling also changes body mass proportionally (area scales by x×y); use `setObjectMassOverride` after if you need a fixed mass.
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
// Uniform scale
|
|
866
|
+
scene.setObjectScale(id, 2, 2); // double size
|
|
867
|
+
scene.setObjectScale(id, 0.5, 0.5); // half size
|
|
868
|
+
|
|
869
|
+
// Non-uniform scale (independent x and y)
|
|
870
|
+
scene.setObjectScale(id, 3, 1); // stretch wide, keep height
|
|
871
|
+
scene.setObjectScale(id, 1, 0.5); // squash vertically
|
|
872
|
+
|
|
873
|
+
// Restore original size
|
|
874
|
+
scene.setObjectScale(id, 1, 1);
|
|
875
|
+
```
|
|
876
|
+
|
|
823
877
|
## Examples
|
|
824
878
|
|
|
825
879
|
Working examples are provided in the `/examples` directory:
|
|
@@ -863,6 +917,11 @@ import type {
|
|
|
863
917
|
TTFTextObstacleConfig,
|
|
864
918
|
TextAlign,
|
|
865
919
|
TextBounds,
|
|
920
|
+
LetterDebugInfo,
|
|
921
|
+
|
|
922
|
+
// DOM obstacle types
|
|
923
|
+
DOMObstacleConfig,
|
|
924
|
+
DOMObstacleResult,
|
|
866
925
|
|
|
867
926
|
// Effect types
|
|
868
927
|
EffectConfig,
|
|
@@ -905,5 +964,5 @@ import type {
|
|
|
905
964
|
} from '@blorkfield/overlay-core';
|
|
906
965
|
|
|
907
966
|
// Tag constants (values, not types)
|
|
908
|
-
import { TAGS,
|
|
967
|
+
import { TAGS, TAG_STATIC, TAG_GRABABLE, TAG_FOLLOW_WINDOW, TAG_GRAVITY_OVERRIDE, TAG_SPEED_OVERRIDE, TAG_MASS_OVERRIDE } from '@blorkfield/overlay-core';
|
|
909
968
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -1466,6 +1466,8 @@ var OverlayScene = class {
|
|
|
1466
1466
|
this.followWindowEntries = /* @__PURE__ */ new Set();
|
|
1467
1467
|
// IDs of static objects that have pressure thresholds — empty = skip updatePressure entirely
|
|
1468
1468
|
this.pressureObstacleIds = /* @__PURE__ */ new Set();
|
|
1469
|
+
// Active collision pairs: id -> Set of ids currently colliding with it
|
|
1470
|
+
this.activeCollisions = /* @__PURE__ */ new Map();
|
|
1469
1471
|
/** Handle mouse down - start grab via programmatic API */
|
|
1470
1472
|
this.handleMouseDown = (event) => {
|
|
1471
1473
|
const rect = this.canvas.getBoundingClientRect();
|
|
@@ -1532,6 +1534,10 @@ var OverlayScene = class {
|
|
|
1532
1534
|
const entryA = this.findObjectByBody(pair.bodyA);
|
|
1533
1535
|
const entryB = this.findObjectByBody(pair.bodyB);
|
|
1534
1536
|
if (entryA && entryB) {
|
|
1537
|
+
if (!this.activeCollisions.has(entryA.id)) this.activeCollisions.set(entryA.id, /* @__PURE__ */ new Set());
|
|
1538
|
+
if (!this.activeCollisions.has(entryB.id)) this.activeCollisions.set(entryB.id, /* @__PURE__ */ new Set());
|
|
1539
|
+
this.activeCollisions.get(entryA.id).add(entryB.id);
|
|
1540
|
+
this.activeCollisions.get(entryB.id).add(entryA.id);
|
|
1535
1541
|
this.emitLifecycleEvent(
|
|
1536
1542
|
"objectCollision",
|
|
1537
1543
|
this.toObjectState(entryA),
|
|
@@ -1540,6 +1546,16 @@ var OverlayScene = class {
|
|
|
1540
1546
|
}
|
|
1541
1547
|
}
|
|
1542
1548
|
};
|
|
1549
|
+
this.handleCollisionEnd = (event) => {
|
|
1550
|
+
for (const pair of event.pairs) {
|
|
1551
|
+
const entryA = this.findObjectByBody(pair.bodyA);
|
|
1552
|
+
const entryB = this.findObjectByBody(pair.bodyB);
|
|
1553
|
+
if (entryA && entryB) {
|
|
1554
|
+
this.activeCollisions.get(entryA.id)?.delete(entryB.id);
|
|
1555
|
+
this.activeCollisions.get(entryB.id)?.delete(entryA.id);
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
};
|
|
1543
1559
|
// ==================== PRIVATE ====================
|
|
1544
1560
|
this.loop = () => {
|
|
1545
1561
|
const substepDelta = 1e3 / 60 / this.substeps;
|
|
@@ -1668,6 +1684,7 @@ var OverlayScene = class {
|
|
|
1668
1684
|
import_matter_js5.default.Events.on(this.render, "beforeRender", this.handleBeforeRender);
|
|
1669
1685
|
import_matter_js5.default.Events.on(this.render, "afterRender", this.handleAfterRender);
|
|
1670
1686
|
import_matter_js5.default.Events.on(this.engine, "collisionStart", this.handleCollisionStart);
|
|
1687
|
+
import_matter_js5.default.Events.on(this.engine, "collisionEnd", this.handleCollisionEnd);
|
|
1671
1688
|
}
|
|
1672
1689
|
static createContainer(parent, options = {}) {
|
|
1673
1690
|
const canvas = document.createElement("canvas");
|
|
@@ -2071,6 +2088,7 @@ var OverlayScene = class {
|
|
|
2071
2088
|
import_matter_js5.default.Events.off(this.render, "beforeRender", this.handleBeforeRender);
|
|
2072
2089
|
import_matter_js5.default.Events.off(this.render, "afterRender", this.handleAfterRender);
|
|
2073
2090
|
import_matter_js5.default.Events.off(this.engine, "collisionStart", this.handleCollisionStart);
|
|
2091
|
+
import_matter_js5.default.Events.off(this.engine, "collisionEnd", this.handleCollisionEnd);
|
|
2074
2092
|
import_matter_js5.default.Engine.clear(this.engine);
|
|
2075
2093
|
this.objects.clear();
|
|
2076
2094
|
this.gravityOverrideEntries.clear();
|
|
@@ -2081,6 +2099,7 @@ var OverlayScene = class {
|
|
|
2081
2099
|
this.pressureLogTimer = 0;
|
|
2082
2100
|
this.floorSegmentPressure.clear();
|
|
2083
2101
|
this.collapsedSegments.clear();
|
|
2102
|
+
this.activeCollisions.clear();
|
|
2084
2103
|
this.updateCallbacks = [];
|
|
2085
2104
|
this.lifecycleCallbacks.objectSpawned = [];
|
|
2086
2105
|
this.lifecycleCallbacks.objectRemoved = [];
|
|
@@ -2532,6 +2551,13 @@ var OverlayScene = class {
|
|
|
2532
2551
|
this.gravityOverrideEntries.delete(entry);
|
|
2533
2552
|
this.followWindowEntries.delete(entry);
|
|
2534
2553
|
this.pressureObstacleIds.delete(id);
|
|
2554
|
+
const colliding = this.activeCollisions.get(id);
|
|
2555
|
+
if (colliding) {
|
|
2556
|
+
for (const otherId of colliding) {
|
|
2557
|
+
this.activeCollisions.get(otherId)?.delete(id);
|
|
2558
|
+
}
|
|
2559
|
+
this.activeCollisions.delete(id);
|
|
2560
|
+
}
|
|
2535
2561
|
this.objects.delete(id);
|
|
2536
2562
|
}
|
|
2537
2563
|
removeObjects(ids) {
|
|
@@ -2781,6 +2807,32 @@ var OverlayScene = class {
|
|
|
2781
2807
|
const idx = arr.indexOf(callback);
|
|
2782
2808
|
if (idx !== -1) arr.splice(idx, 1);
|
|
2783
2809
|
}
|
|
2810
|
+
/**
|
|
2811
|
+
* Get the IDs of all objects currently colliding with a given object.
|
|
2812
|
+
* @param id - The ID of the object to query
|
|
2813
|
+
* @returns Array of IDs of objects currently in contact with it
|
|
2814
|
+
*/
|
|
2815
|
+
getCollidingWith(id) {
|
|
2816
|
+
return Array.from(this.activeCollisions.get(id) ?? []);
|
|
2817
|
+
}
|
|
2818
|
+
/**
|
|
2819
|
+
* Get all currently active collision pairs.
|
|
2820
|
+
* @returns Array of `{ a, b }` pairs where `a` and `b` are colliding object IDs
|
|
2821
|
+
*/
|
|
2822
|
+
getActiveCollisions() {
|
|
2823
|
+
const pairs = [];
|
|
2824
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2825
|
+
for (const [id, others] of this.activeCollisions) {
|
|
2826
|
+
for (const otherId of others) {
|
|
2827
|
+
const key = id < otherId ? `${id}:${otherId}` : `${otherId}:${id}`;
|
|
2828
|
+
if (!seen.has(key)) {
|
|
2829
|
+
seen.add(key);
|
|
2830
|
+
pairs.push({ a: id, b: otherId });
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
return pairs;
|
|
2835
|
+
}
|
|
2784
2836
|
/** Create ObjectState from an ObjectEntry */
|
|
2785
2837
|
toObjectState(entry) {
|
|
2786
2838
|
return {
|