@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/dist/index.d.cts CHANGED
@@ -537,7 +537,6 @@ declare class OverlayScene {
537
537
  private config;
538
538
  private animationFrameId;
539
539
  private mouse;
540
- private mouseConstraint;
541
540
  private effectManager;
542
541
  private fonts;
543
542
  private fontsInitialized;
@@ -551,14 +550,13 @@ declare class OverlayScene {
551
550
  private backgroundManager;
552
551
  private lifecycleCallbacks;
553
552
  private followTargets;
553
+ private grabbedObjectId;
554
+ private lastGrabMousePosition;
554
555
  static createContainer(parent: HTMLElement, options?: ContainerOptions): {
555
556
  canvas: HTMLCanvasElement;
556
557
  bounds: Bounds;
557
558
  };
558
- constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig);
559
- /** Filter drag events - only allow grabbing objects with 'grabable' tag */
560
- private handleStartDrag;
561
- /** Handle canvas clicks for click-to-fall behavior */
559
+ constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig); /** Handle canvas clicks for click-to-fall behavior */
562
560
  private handleCanvasClick;
563
561
  /**
564
562
  * Handler for Matter.js beforeRender event.
package/dist/index.d.ts CHANGED
@@ -537,7 +537,6 @@ declare class OverlayScene {
537
537
  private config;
538
538
  private animationFrameId;
539
539
  private mouse;
540
- private mouseConstraint;
541
540
  private effectManager;
542
541
  private fonts;
543
542
  private fontsInitialized;
@@ -551,14 +550,13 @@ declare class OverlayScene {
551
550
  private backgroundManager;
552
551
  private lifecycleCallbacks;
553
552
  private followTargets;
553
+ private grabbedObjectId;
554
+ private lastGrabMousePosition;
554
555
  static createContainer(parent: HTMLElement, options?: ContainerOptions): {
555
556
  canvas: HTMLCanvasElement;
556
557
  bounds: Bounds;
557
558
  };
558
- constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig);
559
- /** Filter drag events - only allow grabbing objects with 'grabable' tag */
560
- private handleStartDrag;
561
- /** Handle canvas clicks for click-to-fall behavior */
559
+ constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig); /** Handle canvas clicks for click-to-fall behavior */
562
560
  private handleCanvasClick;
563
561
  /**
564
562
  * Handler for Matter.js beforeRender event.
package/dist/index.js CHANGED
@@ -1376,7 +1376,6 @@ var OverlayScene = class {
1376
1376
  this.updateCallbacks = [];
1377
1377
  this.animationFrameId = null;
1378
1378
  this.mouse = null;
1379
- this.mouseConstraint = null;
1380
1379
  this.fonts = [];
1381
1380
  this.fontsInitialized = false;
1382
1381
  this.letterDebugInfo = /* @__PURE__ */ new Map();
@@ -1398,17 +1397,9 @@ var OverlayScene = class {
1398
1397
  };
1399
1398
  // Follow targets for follow-{key} tagged objects
1400
1399
  this.followTargets = /* @__PURE__ */ new Map();
1401
- /** Filter drag events - only allow grabbing objects with 'grabable' tag */
1402
- this.handleStartDrag = (event) => {
1403
- const body = event.body;
1404
- if (!body) return;
1405
- const entry = this.findObjectByBody(body);
1406
- if (!entry || !entry.tags.includes("grabable")) {
1407
- if (this.mouseConstraint) {
1408
- this.mouseConstraint.constraint.bodyB = null;
1409
- }
1410
- }
1411
- };
1400
+ // Delta-based grab tracking (no constraint physics)
1401
+ this.grabbedObjectId = null;
1402
+ this.lastGrabMousePosition = null;
1412
1403
  /** Handle canvas clicks for click-to-fall behavior */
1413
1404
  this.handleCanvasClick = (event) => {
1414
1405
  const rect = this.canvas.getBoundingClientRect();
@@ -1473,8 +1464,20 @@ var OverlayScene = class {
1473
1464
  if (!this.followTargets.has("mouse") && this.mouse) {
1474
1465
  this.followTargets.set("mouse", { x: this.mouse.position.x, y: this.mouse.position.y });
1475
1466
  }
1467
+ if (this.grabbedObjectId && this.lastGrabMousePosition) {
1468
+ const entry = this.objects.get(this.grabbedObjectId);
1469
+ const mouseTarget = this.followTargets.get("mouse");
1470
+ if (entry && mouseTarget) {
1471
+ const dx = mouseTarget.x - this.lastGrabMousePosition.x;
1472
+ const dy = mouseTarget.y - this.lastGrabMousePosition.y;
1473
+ if (dx !== 0 || dy !== 0) {
1474
+ Matter5.Body.translate(entry.body, { x: dx, y: dy });
1475
+ }
1476
+ this.lastGrabMousePosition = { x: mouseTarget.x, y: mouseTarget.y };
1477
+ }
1478
+ }
1476
1479
  for (const entry of this.objects.values()) {
1477
- const isDragging = this.mouseConstraint?.body === entry.body;
1480
+ const isDragging = this.grabbedObjectId === entry.id;
1478
1481
  if (!isDragging) {
1479
1482
  for (const tag of entry.tags) {
1480
1483
  const key = tag === "follow" ? "mouse" : tag.startsWith("follow-") ? tag.slice(7) : null;
@@ -1522,24 +1525,7 @@ var OverlayScene = class {
1522
1525
  Matter5.Composite.add(this.engine.world, this.boundaries);
1523
1526
  this.checkInitialFloorIntegrity();
1524
1527
  this.mouse = Matter5.Mouse.create(canvas);
1525
- this.mouseConstraint = Matter5.MouseConstraint.create(this.engine, {
1526
- mouse: this.mouse,
1527
- constraint: {
1528
- stiffness: 0.2,
1529
- render: { visible: false }
1530
- }
1531
- });
1532
- Matter5.Composite.add(this.engine.world, this.mouseConstraint);
1533
- const wheelHandler = this.mouse.mousewheel;
1534
- if (wheelHandler) {
1535
- canvas.removeEventListener("mousewheel", wheelHandler);
1536
- canvas.removeEventListener("DOMMouseScroll", wheelHandler);
1537
- canvas.removeEventListener("wheel", wheelHandler);
1538
- }
1539
- canvas.style.touchAction = "pan-x pan-y";
1540
- Matter5.Events.on(this.mouseConstraint, "startdrag", this.handleStartDrag);
1541
1528
  canvas.addEventListener("click", this.handleCanvasClick);
1542
- this.render.mouse = this.mouse;
1543
1529
  this.effectManager = new EffectManager(
1544
1530
  this.config.bounds,
1545
1531
  (cfg) => this.spawnObjectAsync(cfg),
@@ -1961,9 +1947,6 @@ var OverlayScene = class {
1961
1947
  }
1962
1948
  destroy() {
1963
1949
  this.stop();
1964
- if (this.mouseConstraint) {
1965
- Matter5.Events.off(this.mouseConstraint, "startdrag", this.handleStartDrag);
1966
- }
1967
1950
  this.canvas.removeEventListener("click", this.handleCanvasClick);
1968
1951
  Matter5.Events.off(this.render, "beforeRender", this.handleBeforeRender);
1969
1952
  Matter5.Events.off(this.render, "afterRender", this.handleAfterRender);
@@ -2291,12 +2274,6 @@ var OverlayScene = class {
2291
2274
  */
2292
2275
  setFollowTarget(key, x, y) {
2293
2276
  this.followTargets.set(key, { x, y });
2294
- if (key === "mouse" && this.mouse) {
2295
- this.mouse.position.x = x;
2296
- this.mouse.position.y = y;
2297
- this.mouse.absolute.x = x;
2298
- this.mouse.absolute.y = y;
2299
- }
2300
2277
  }
2301
2278
  /**
2302
2279
  * Remove a follow target. Objects with the corresponding tag will stop following.
@@ -2321,9 +2298,9 @@ var OverlayScene = class {
2321
2298
  * @returns The ID of the grabbed object, or null if no grabable object at position
2322
2299
  */
2323
2300
  startGrab() {
2324
- if (!this.mouseConstraint || !this.mouse) return null;
2325
2301
  const mouseTarget = this.followTargets.get("mouse");
2326
- const position = mouseTarget ?? { x: this.mouse.position.x, y: this.mouse.position.y };
2302
+ const position = mouseTarget ?? (this.mouse ? { x: this.mouse.position.x, y: this.mouse.position.y } : null);
2303
+ if (!position) return null;
2327
2304
  const bodies = Matter5.Query.point(
2328
2305
  Matter5.Composite.allBodies(this.engine.world),
2329
2306
  position
@@ -2331,18 +2308,8 @@ var OverlayScene = class {
2331
2308
  for (const body of bodies) {
2332
2309
  const entry = this.findObjectByBody(body);
2333
2310
  if (entry && entry.tags.includes("grabable")) {
2334
- this.mouse.button = 0;
2335
- this.mouseConstraint.constraint.pointA = { x: position.x, y: position.y };
2336
- this.mouseConstraint.constraint.bodyB = entry.body;
2337
- this.mouseConstraint.constraint.pointB = { x: 0, y: 0 };
2338
- console.log("[overlay-core] startGrab success", {
2339
- entityId: entry.id,
2340
- mousePosition: position,
2341
- bodyPosition: { x: entry.body.position.x, y: entry.body.position.y },
2342
- constraintPointA: this.mouseConstraint.constraint.pointA,
2343
- constraintPointB: this.mouseConstraint.constraint.pointB,
2344
- mouseButton: this.mouse.button
2345
- });
2311
+ this.grabbedObjectId = entry.id;
2312
+ this.lastGrabMousePosition = { x: position.x, y: position.y };
2346
2313
  return entry.id;
2347
2314
  }
2348
2315
  }
@@ -2352,21 +2319,15 @@ var OverlayScene = class {
2352
2319
  * Release any currently grabbed object.
2353
2320
  */
2354
2321
  endGrab() {
2355
- if (this.mouseConstraint) {
2356
- this.mouseConstraint.constraint.bodyB = null;
2357
- }
2358
- if (this.mouse) {
2359
- this.mouse.button = -1;
2360
- }
2322
+ this.grabbedObjectId = null;
2323
+ this.lastGrabMousePosition = null;
2361
2324
  }
2362
2325
  /**
2363
2326
  * Get the ID of the currently grabbed object.
2364
2327
  * @returns The ID of the grabbed object, or null if nothing is grabbed
2365
2328
  */
2366
2329
  getGrabbedObject() {
2367
- if (!this.mouseConstraint?.constraint.bodyB) return null;
2368
- const entry = this.findObjectByBody(this.mouseConstraint.constraint.bodyB);
2369
- return entry?.id ?? null;
2330
+ return this.grabbedObjectId;
2370
2331
  }
2371
2332
  // ==================== PHYSICS MANIPULATION METHODS ====================
2372
2333
  /**