@blorkfield/overlay-core 0.8.4 → 0.8.6
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 +9 -10
- package/dist/index.cjs +23 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -5
- package/dist/index.d.ts +3 -5
- package/dist/index.js +23 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -323,28 +323,27 @@ For scenarios where mouse input comes from an external source (e.g., system-wide
|
|
|
323
323
|
const canvasX = screenMouseX - canvasOffsetX;
|
|
324
324
|
const canvasY = screenMouseY - canvasOffsetY;
|
|
325
325
|
scene.setFollowTarget('mouse', canvasX, canvasY);
|
|
326
|
-
|
|
327
|
-
// This position is now used for:
|
|
328
|
-
// - Objects with 'follow' tag (they move toward this position)
|
|
329
|
-
// - Programmatic grab detection via startGrab()
|
|
330
|
-
// - MouseConstraint during drag (grabbed objects follow this position)
|
|
331
326
|
```
|
|
332
327
|
|
|
333
328
|
The offset calculation is your responsibility - overlay-core uses whatever position you provide.
|
|
334
329
|
|
|
335
330
|
### Programmatic Grab/Release
|
|
336
331
|
|
|
332
|
+
Grab uses delta-based movement: when grabbed, the entity and mouse become linked. The entity moves BY the same amount as the mouse moves, not TO the mouse position. This ensures the entity stays at its original position on grab and follows mouse movement naturally.
|
|
333
|
+
|
|
337
334
|
```typescript
|
|
338
335
|
// Grab object at current mouse position (only 'grabable' tagged objects)
|
|
339
336
|
const grabbedId = scene.startGrab();
|
|
340
337
|
if (grabbedId) {
|
|
338
|
+
// Entity stays at its current position, now linked to mouse
|
|
341
339
|
console.log(`Grabbed: ${grabbedId}`);
|
|
342
340
|
}
|
|
343
341
|
|
|
344
|
-
//
|
|
342
|
+
// As mouse moves, entity moves by the same delta
|
|
343
|
+
// Mouse moves +50px right → entity moves +50px right
|
|
345
344
|
scene.setFollowTarget('mouse', newX, newY);
|
|
346
345
|
|
|
347
|
-
// Release
|
|
346
|
+
// Release unlinks entity from mouse
|
|
348
347
|
scene.endGrab();
|
|
349
348
|
|
|
350
349
|
// Check what's currently grabbed
|
|
@@ -354,9 +353,9 @@ const currentGrab = scene.getGrabbedObject(); // Returns ID or null
|
|
|
354
353
|
| Method | Returns | Description |
|
|
355
354
|
|--------|---------|-------------|
|
|
356
355
|
| `setFollowTarget('mouse', x, y)` | void | Set mouse position for follow behavior and grab detection |
|
|
357
|
-
| `startGrab()` | string \| null |
|
|
358
|
-
| `endGrab()` | void |
|
|
359
|
-
| `getGrabbedObject()` | string \| null | Get ID of currently grabbed
|
|
356
|
+
| `startGrab()` | string \| null | Link entity at current mouse position to mouse, returns entity ID |
|
|
357
|
+
| `endGrab()` | void | Unlink currently grabbed entity |
|
|
358
|
+
| `getGrabbedObject()` | string \| null | Get ID of currently grabbed entity |
|
|
360
359
|
|
|
361
360
|
## Configuration
|
|
362
361
|
|
package/dist/index.cjs
CHANGED
|
@@ -1421,7 +1421,6 @@ var OverlayScene = class {
|
|
|
1421
1421
|
this.updateCallbacks = [];
|
|
1422
1422
|
this.animationFrameId = null;
|
|
1423
1423
|
this.mouse = null;
|
|
1424
|
-
this.mouseConstraint = null;
|
|
1425
1424
|
this.fonts = [];
|
|
1426
1425
|
this.fontsInitialized = false;
|
|
1427
1426
|
this.letterDebugInfo = /* @__PURE__ */ new Map();
|
|
@@ -1443,17 +1442,9 @@ var OverlayScene = class {
|
|
|
1443
1442
|
};
|
|
1444
1443
|
// Follow targets for follow-{key} tagged objects
|
|
1445
1444
|
this.followTargets = /* @__PURE__ */ new Map();
|
|
1446
|
-
|
|
1447
|
-
this.
|
|
1448
|
-
|
|
1449
|
-
if (!body) return;
|
|
1450
|
-
const entry = this.findObjectByBody(body);
|
|
1451
|
-
if (!entry || !entry.tags.includes("grabable")) {
|
|
1452
|
-
if (this.mouseConstraint) {
|
|
1453
|
-
this.mouseConstraint.constraint.bodyB = null;
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
};
|
|
1445
|
+
// Delta-based grab tracking (no constraint physics)
|
|
1446
|
+
this.grabbedObjectId = null;
|
|
1447
|
+
this.lastGrabMousePosition = null;
|
|
1457
1448
|
/** Handle canvas clicks for click-to-fall behavior */
|
|
1458
1449
|
this.handleCanvasClick = (event) => {
|
|
1459
1450
|
const rect = this.canvas.getBoundingClientRect();
|
|
@@ -1518,8 +1509,20 @@ var OverlayScene = class {
|
|
|
1518
1509
|
if (!this.followTargets.has("mouse") && this.mouse) {
|
|
1519
1510
|
this.followTargets.set("mouse", { x: this.mouse.position.x, y: this.mouse.position.y });
|
|
1520
1511
|
}
|
|
1512
|
+
if (this.grabbedObjectId && this.lastGrabMousePosition) {
|
|
1513
|
+
const entry = this.objects.get(this.grabbedObjectId);
|
|
1514
|
+
const mouseTarget = this.followTargets.get("mouse");
|
|
1515
|
+
if (entry && mouseTarget) {
|
|
1516
|
+
const dx = mouseTarget.x - this.lastGrabMousePosition.x;
|
|
1517
|
+
const dy = mouseTarget.y - this.lastGrabMousePosition.y;
|
|
1518
|
+
if (dx !== 0 || dy !== 0) {
|
|
1519
|
+
import_matter_js5.default.Body.translate(entry.body, { x: dx, y: dy });
|
|
1520
|
+
}
|
|
1521
|
+
this.lastGrabMousePosition = { x: mouseTarget.x, y: mouseTarget.y };
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1521
1524
|
for (const entry of this.objects.values()) {
|
|
1522
|
-
const isDragging = this.
|
|
1525
|
+
const isDragging = this.grabbedObjectId === entry.id;
|
|
1523
1526
|
if (!isDragging) {
|
|
1524
1527
|
for (const tag of entry.tags) {
|
|
1525
1528
|
const key = tag === "follow" ? "mouse" : tag.startsWith("follow-") ? tag.slice(7) : null;
|
|
@@ -1567,24 +1570,7 @@ var OverlayScene = class {
|
|
|
1567
1570
|
import_matter_js5.default.Composite.add(this.engine.world, this.boundaries);
|
|
1568
1571
|
this.checkInitialFloorIntegrity();
|
|
1569
1572
|
this.mouse = import_matter_js5.default.Mouse.create(canvas);
|
|
1570
|
-
this.mouseConstraint = import_matter_js5.default.MouseConstraint.create(this.engine, {
|
|
1571
|
-
mouse: this.mouse,
|
|
1572
|
-
constraint: {
|
|
1573
|
-
stiffness: 0.2,
|
|
1574
|
-
render: { visible: false }
|
|
1575
|
-
}
|
|
1576
|
-
});
|
|
1577
|
-
import_matter_js5.default.Composite.add(this.engine.world, this.mouseConstraint);
|
|
1578
|
-
const wheelHandler = this.mouse.mousewheel;
|
|
1579
|
-
if (wheelHandler) {
|
|
1580
|
-
canvas.removeEventListener("mousewheel", wheelHandler);
|
|
1581
|
-
canvas.removeEventListener("DOMMouseScroll", wheelHandler);
|
|
1582
|
-
canvas.removeEventListener("wheel", wheelHandler);
|
|
1583
|
-
}
|
|
1584
|
-
canvas.style.touchAction = "pan-x pan-y";
|
|
1585
|
-
import_matter_js5.default.Events.on(this.mouseConstraint, "startdrag", this.handleStartDrag);
|
|
1586
1573
|
canvas.addEventListener("click", this.handleCanvasClick);
|
|
1587
|
-
this.render.mouse = this.mouse;
|
|
1588
1574
|
this.effectManager = new EffectManager(
|
|
1589
1575
|
this.config.bounds,
|
|
1590
1576
|
(cfg) => this.spawnObjectAsync(cfg),
|
|
@@ -2006,9 +1992,6 @@ var OverlayScene = class {
|
|
|
2006
1992
|
}
|
|
2007
1993
|
destroy() {
|
|
2008
1994
|
this.stop();
|
|
2009
|
-
if (this.mouseConstraint) {
|
|
2010
|
-
import_matter_js5.default.Events.off(this.mouseConstraint, "startdrag", this.handleStartDrag);
|
|
2011
|
-
}
|
|
2012
1995
|
this.canvas.removeEventListener("click", this.handleCanvasClick);
|
|
2013
1996
|
import_matter_js5.default.Events.off(this.render, "beforeRender", this.handleBeforeRender);
|
|
2014
1997
|
import_matter_js5.default.Events.off(this.render, "afterRender", this.handleAfterRender);
|
|
@@ -2336,12 +2319,6 @@ var OverlayScene = class {
|
|
|
2336
2319
|
*/
|
|
2337
2320
|
setFollowTarget(key, x, y) {
|
|
2338
2321
|
this.followTargets.set(key, { x, y });
|
|
2339
|
-
if (key === "mouse" && this.mouse) {
|
|
2340
|
-
this.mouse.position.x = x;
|
|
2341
|
-
this.mouse.position.y = y;
|
|
2342
|
-
this.mouse.absolute.x = x;
|
|
2343
|
-
this.mouse.absolute.y = y;
|
|
2344
|
-
}
|
|
2345
2322
|
}
|
|
2346
2323
|
/**
|
|
2347
2324
|
* Remove a follow target. Objects with the corresponding tag will stop following.
|
|
@@ -2366,9 +2343,9 @@ var OverlayScene = class {
|
|
|
2366
2343
|
* @returns The ID of the grabbed object, or null if no grabable object at position
|
|
2367
2344
|
*/
|
|
2368
2345
|
startGrab() {
|
|
2369
|
-
if (!this.mouseConstraint || !this.mouse) return null;
|
|
2370
2346
|
const mouseTarget = this.followTargets.get("mouse");
|
|
2371
|
-
const position = mouseTarget ?? { x: this.mouse.position.x, y: this.mouse.position.y };
|
|
2347
|
+
const position = mouseTarget ?? (this.mouse ? { x: this.mouse.position.x, y: this.mouse.position.y } : null);
|
|
2348
|
+
if (!position) return null;
|
|
2372
2349
|
const bodies = import_matter_js5.default.Query.point(
|
|
2373
2350
|
import_matter_js5.default.Composite.allBodies(this.engine.world),
|
|
2374
2351
|
position
|
|
@@ -2376,18 +2353,8 @@ var OverlayScene = class {
|
|
|
2376
2353
|
for (const body of bodies) {
|
|
2377
2354
|
const entry = this.findObjectByBody(body);
|
|
2378
2355
|
if (entry && entry.tags.includes("grabable")) {
|
|
2379
|
-
this.
|
|
2380
|
-
this.
|
|
2381
|
-
this.mouseConstraint.constraint.bodyB = entry.body;
|
|
2382
|
-
this.mouseConstraint.constraint.pointB = { x: 0, y: 0 };
|
|
2383
|
-
console.log("[overlay-core] startGrab success", {
|
|
2384
|
-
entityId: entry.id,
|
|
2385
|
-
mousePosition: position,
|
|
2386
|
-
bodyPosition: { x: entry.body.position.x, y: entry.body.position.y },
|
|
2387
|
-
constraintPointA: this.mouseConstraint.constraint.pointA,
|
|
2388
|
-
constraintPointB: this.mouseConstraint.constraint.pointB,
|
|
2389
|
-
mouseButton: this.mouse.button
|
|
2390
|
-
});
|
|
2356
|
+
this.grabbedObjectId = entry.id;
|
|
2357
|
+
this.lastGrabMousePosition = { x: position.x, y: position.y };
|
|
2391
2358
|
return entry.id;
|
|
2392
2359
|
}
|
|
2393
2360
|
}
|
|
@@ -2397,21 +2364,15 @@ var OverlayScene = class {
|
|
|
2397
2364
|
* Release any currently grabbed object.
|
|
2398
2365
|
*/
|
|
2399
2366
|
endGrab() {
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
}
|
|
2403
|
-
if (this.mouse) {
|
|
2404
|
-
this.mouse.button = -1;
|
|
2405
|
-
}
|
|
2367
|
+
this.grabbedObjectId = null;
|
|
2368
|
+
this.lastGrabMousePosition = null;
|
|
2406
2369
|
}
|
|
2407
2370
|
/**
|
|
2408
2371
|
* Get the ID of the currently grabbed object.
|
|
2409
2372
|
* @returns The ID of the grabbed object, or null if nothing is grabbed
|
|
2410
2373
|
*/
|
|
2411
2374
|
getGrabbedObject() {
|
|
2412
|
-
|
|
2413
|
-
const entry = this.findObjectByBody(this.mouseConstraint.constraint.bodyB);
|
|
2414
|
-
return entry?.id ?? null;
|
|
2375
|
+
return this.grabbedObjectId;
|
|
2415
2376
|
}
|
|
2416
2377
|
// ==================== PHYSICS MANIPULATION METHODS ====================
|
|
2417
2378
|
/**
|