@blorkfield/overlay-core 0.11.5 → 0.11.7
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 +5 -3
- package/dist/index.cjs +26 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -215,9 +215,11 @@ scene.spawnObject({
|
|
|
215
215
|
});
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
+
**Positioning convention:** overlay-core sets `position: absolute` on the element and owns `left`, `top`, and `transform` entirely via inline styles. Position is expressed as `left: x - width/2; top: y - height/2` (body centre → top-left corner). Rotation is applied via `transform: rotate(angle)`. Do not set `left`, `top`, or `transform` on the element yourself — they will be overwritten. To place the element before spawn, set it off-screen or hidden; overlay-core writes the correct position on `spawnObject` for both static and dynamic elements, so it is visible and correctly placed immediately after the call returns.
|
|
219
|
+
|
|
218
220
|
When a DOM element collapses:
|
|
219
|
-
- The element
|
|
220
|
-
-
|
|
221
|
+
- The element follows its physics body each frame via `left`/`top` updates
|
|
222
|
+
- If `shadow` is configured, a cloned DOM element is left at the original spawn position
|
|
221
223
|
|
|
222
224
|
```typescript
|
|
223
225
|
// Get the shadow element after collapse (if shadow was configured)
|
|
@@ -555,7 +557,7 @@ const scene = new OverlayScene(canvas, {
|
|
|
555
557
|
| `floorConfig.minIntegrity` | none | Minimum segments required, otherwise all collapse |
|
|
556
558
|
| `floorConfig.segmentWidths` | none | Proportional widths for each segment (array that sums to 1.0) |
|
|
557
559
|
| `despawnBelowFloor` | 1.0 | Distance below floor to despawn objects (as fraction of height) |
|
|
558
|
-
| `recenterOnResize` | false | Translate all objects to stay centred when canvas dimensions change — useful for phone rotation and responsive layouts |
|
|
560
|
+
| `recenterOnResize` | false | Translate all objects to stay centred when canvas dimensions change — useful for phone rotation and responsive layouts. Applies to all object types including static DOM obstacles (their CSS `left`/`top` is updated immediately at resize time, not deferred to the next frame). |
|
|
559
561
|
|
|
560
562
|
### Background Configuration
|
|
561
563
|
|
package/dist/index.cjs
CHANGED
|
@@ -1498,6 +1498,8 @@ var OverlayScene = class {
|
|
|
1498
1498
|
this.pressureObstacleIds = /* @__PURE__ */ new Set();
|
|
1499
1499
|
// Active collision pairs: id -> Set of ids currently colliding with it
|
|
1500
1500
|
this.activeCollisions = /* @__PURE__ */ new Map();
|
|
1501
|
+
// DOM shadow elements whose parent entry has been removed (live body despawned after collapse)
|
|
1502
|
+
this.orphanedDOMShadows = /* @__PURE__ */ new Set();
|
|
1501
1503
|
/** Handle mouse down - start grab via programmatic API */
|
|
1502
1504
|
this.handleMouseDown = (event) => {
|
|
1503
1505
|
const rect = this.canvas.getBoundingClientRect();
|
|
@@ -2052,9 +2054,9 @@ var OverlayScene = class {
|
|
|
2052
2054
|
transform: entry.domElement.style.transform
|
|
2053
2055
|
}
|
|
2054
2056
|
});
|
|
2055
|
-
shadowElement.style.
|
|
2056
|
-
shadowElement.style.
|
|
2057
|
-
shadowElement.style.
|
|
2057
|
+
shadowElement.style.left = `${computedLeft}px`;
|
|
2058
|
+
shadowElement.style.top = `${computedTop}px`;
|
|
2059
|
+
shadowElement.style.transform = "rotate(0deg)";
|
|
2058
2060
|
entry.domElement.parentNode?.insertBefore(shadowElement, entry.domElement);
|
|
2059
2061
|
entry.domShadowElement = shadowElement;
|
|
2060
2062
|
return;
|
|
@@ -2169,6 +2171,7 @@ var OverlayScene = class {
|
|
|
2169
2171
|
import_matter_js5.default.Events.off(this.engine, "collisionEnd", this.handleCollisionEnd);
|
|
2170
2172
|
import_matter_js5.default.Engine.clear(this.engine);
|
|
2171
2173
|
this.objects.clear();
|
|
2174
|
+
this.orphanedDOMShadows.clear();
|
|
2172
2175
|
this.gravityOverrideEntries.clear();
|
|
2173
2176
|
this.followWindowEntries.clear();
|
|
2174
2177
|
this.pressureObstacleIds.clear();
|
|
@@ -2318,13 +2321,25 @@ var OverlayScene = class {
|
|
|
2318
2321
|
y: entry.originalPosition.y + dy
|
|
2319
2322
|
};
|
|
2320
2323
|
}
|
|
2324
|
+
if (entry.domElement && entry.tags.includes("static")) {
|
|
2325
|
+
const currentLeft = parseFloat(entry.domElement.style.left) || 0;
|
|
2326
|
+
const currentTop = parseFloat(entry.domElement.style.top) || 0;
|
|
2327
|
+
entry.domElement.style.left = `${currentLeft + dx}px`;
|
|
2328
|
+
entry.domElement.style.top = `${currentTop + dy}px`;
|
|
2329
|
+
}
|
|
2321
2330
|
if (entry.domShadowElement) {
|
|
2322
2331
|
const currentLeft = parseFloat(entry.domShadowElement.style.left) || 0;
|
|
2323
2332
|
const currentTop = parseFloat(entry.domShadowElement.style.top) || 0;
|
|
2324
|
-
entry.domShadowElement.style.
|
|
2325
|
-
entry.domShadowElement.style.
|
|
2333
|
+
entry.domShadowElement.style.left = `${currentLeft + dx}px`;
|
|
2334
|
+
entry.domShadowElement.style.top = `${currentTop + dy}px`;
|
|
2326
2335
|
}
|
|
2327
2336
|
}
|
|
2337
|
+
for (const shadowEl of this.orphanedDOMShadows) {
|
|
2338
|
+
const currentLeft = parseFloat(shadowEl.style.left) || 0;
|
|
2339
|
+
const currentTop = parseFloat(shadowEl.style.top) || 0;
|
|
2340
|
+
shadowEl.style.left = `${currentLeft + dx}px`;
|
|
2341
|
+
shadowEl.style.top = `${currentTop + dy}px`;
|
|
2342
|
+
}
|
|
2328
2343
|
}
|
|
2329
2344
|
this.canvas.width = width;
|
|
2330
2345
|
this.canvas.height = height;
|
|
@@ -2656,6 +2671,9 @@ var OverlayScene = class {
|
|
|
2656
2671
|
}
|
|
2657
2672
|
this.activeCollisions.delete(id);
|
|
2658
2673
|
}
|
|
2674
|
+
if (entry.domShadowElement) {
|
|
2675
|
+
this.orphanedDOMShadows.add(entry.domShadowElement);
|
|
2676
|
+
}
|
|
2659
2677
|
this.objects.delete(id);
|
|
2660
2678
|
}
|
|
2661
2679
|
removeObjects(ids) {
|
|
@@ -3785,9 +3803,9 @@ var OverlayScene = class {
|
|
|
3785
3803
|
const angleDeg = angle * (180 / Math.PI);
|
|
3786
3804
|
const width = entry.domElement.offsetWidth;
|
|
3787
3805
|
const height = entry.domElement.offsetHeight;
|
|
3788
|
-
entry.domElement.style.
|
|
3789
|
-
entry.domElement.style.
|
|
3790
|
-
entry.domElement.style.
|
|
3806
|
+
entry.domElement.style.left = `${x - width / 2}px`;
|
|
3807
|
+
entry.domElement.style.top = `${y - height / 2}px`;
|
|
3808
|
+
entry.domElement.style.transform = `rotate(${angleDeg}deg)`;
|
|
3791
3809
|
}
|
|
3792
3810
|
/** TTL expiration + below-floor despawn in a single O(N) pass */
|
|
3793
3811
|
checkExpiration() {
|