@blorkfield/overlay-core 0.8.6 → 0.8.8

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
@@ -148,7 +148,7 @@ interface DespawnEffectConfig {
148
148
  * Unified configuration for spawning scene objects.
149
149
  * Objects are configured via tags that define their behavior:
150
150
  * - 'falling': Object is dynamic and affected by gravity (without this tag, object is static)
151
- * - 'follow': Object follows mouse position when grounded
151
+ * - 'window_follow': Object follows mouse position when grounded within the canvas window
152
152
  * - 'grabable': Object can be dragged via mouse constraint
153
153
  */
154
154
  interface ObjectConfig {
@@ -552,11 +552,20 @@ declare class OverlayScene {
552
552
  private followTargets;
553
553
  private grabbedObjectId;
554
554
  private lastGrabMousePosition;
555
+ private grabbedWasDynamic;
556
+ private grabVelocity;
555
557
  static createContainer(parent: HTMLElement, options?: ContainerOptions): {
556
558
  canvas: HTMLCanvasElement;
557
559
  bounds: Bounds;
558
560
  };
559
- constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig); /** Handle canvas clicks for click-to-fall behavior */
561
+ constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig);
562
+ /** Handle mouse down - start grab via programmatic API */
563
+ private handleMouseDown;
564
+ /** Handle mouse move - update follow target for grabbed entity */
565
+ private handleMouseMove;
566
+ /** Handle mouse up - release grab */
567
+ private handleMouseUp;
568
+ /** Handle canvas clicks for click-to-fall behavior */
560
569
  private handleCanvasClick;
561
570
  /**
562
571
  * Handler for Matter.js beforeRender event.
@@ -616,8 +625,8 @@ declare class OverlayScene {
616
625
  * Spawn an object synchronously.
617
626
  * Object behavior is determined by tags:
618
627
  * - 'falling': Object is dynamic (affected by gravity)
619
- * - 'follow': Object follows mouse when grounded
620
- * - 'grabable': Object can be dragged
628
+ * - 'window_follow': Object follows mouse when grounded (walks toward mouse)
629
+ * - 'grabable': Object can be grabbed and moved with mouse
621
630
  * Without 'falling' tag, object is static.
622
631
  */
623
632
  spawnObject(config: ObjectConfig): string;
package/dist/index.d.ts CHANGED
@@ -148,7 +148,7 @@ interface DespawnEffectConfig {
148
148
  * Unified configuration for spawning scene objects.
149
149
  * Objects are configured via tags that define their behavior:
150
150
  * - 'falling': Object is dynamic and affected by gravity (without this tag, object is static)
151
- * - 'follow': Object follows mouse position when grounded
151
+ * - 'window_follow': Object follows mouse position when grounded within the canvas window
152
152
  * - 'grabable': Object can be dragged via mouse constraint
153
153
  */
154
154
  interface ObjectConfig {
@@ -552,11 +552,20 @@ declare class OverlayScene {
552
552
  private followTargets;
553
553
  private grabbedObjectId;
554
554
  private lastGrabMousePosition;
555
+ private grabbedWasDynamic;
556
+ private grabVelocity;
555
557
  static createContainer(parent: HTMLElement, options?: ContainerOptions): {
556
558
  canvas: HTMLCanvasElement;
557
559
  bounds: Bounds;
558
560
  };
559
- constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig); /** Handle canvas clicks for click-to-fall behavior */
561
+ constructor(canvas: HTMLCanvasElement, config: OverlaySceneConfig);
562
+ /** Handle mouse down - start grab via programmatic API */
563
+ private handleMouseDown;
564
+ /** Handle mouse move - update follow target for grabbed entity */
565
+ private handleMouseMove;
566
+ /** Handle mouse up - release grab */
567
+ private handleMouseUp;
568
+ /** Handle canvas clicks for click-to-fall behavior */
560
569
  private handleCanvasClick;
561
570
  /**
562
571
  * Handler for Matter.js beforeRender event.
@@ -616,8 +625,8 @@ declare class OverlayScene {
616
625
  * Spawn an object synchronously.
617
626
  * Object behavior is determined by tags:
618
627
  * - 'falling': Object is dynamic (affected by gravity)
619
- * - 'follow': Object follows mouse when grounded
620
- * - 'grabable': Object can be dragged
628
+ * - 'window_follow': Object follows mouse when grounded (walks toward mouse)
629
+ * - 'grabable': Object can be grabbed and moved with mouse
621
630
  * Without 'falling' tag, object is static.
622
631
  */
623
632
  spawnObject(config: ObjectConfig): string;
package/dist/index.js CHANGED
@@ -1397,9 +1397,30 @@ var OverlayScene = class {
1397
1397
  };
1398
1398
  // Follow targets for follow-{key} tagged objects
1399
1399
  this.followTargets = /* @__PURE__ */ new Map();
1400
- // Delta-based grab tracking (no constraint physics)
1400
+ // Delta-based grab tracking
1401
1401
  this.grabbedObjectId = null;
1402
1402
  this.lastGrabMousePosition = null;
1403
+ this.grabbedWasDynamic = false;
1404
+ this.grabVelocity = { x: 0, y: 0 };
1405
+ /** Handle mouse down - start grab via programmatic API */
1406
+ this.handleMouseDown = (event) => {
1407
+ const rect = this.canvas.getBoundingClientRect();
1408
+ const x = event.clientX - rect.left;
1409
+ const y = event.clientY - rect.top;
1410
+ this.followTargets.set("mouse", { x, y });
1411
+ this.startGrab();
1412
+ };
1413
+ /** Handle mouse move - update follow target for grabbed entity */
1414
+ this.handleMouseMove = (event) => {
1415
+ const rect = this.canvas.getBoundingClientRect();
1416
+ const x = event.clientX - rect.left;
1417
+ const y = event.clientY - rect.top;
1418
+ this.followTargets.set("mouse", { x, y });
1419
+ };
1420
+ /** Handle mouse up - release grab */
1421
+ this.handleMouseUp = () => {
1422
+ this.endGrab();
1423
+ };
1403
1424
  /** Handle canvas clicks for click-to-fall behavior */
1404
1425
  this.handleCanvasClick = (event) => {
1405
1426
  const rect = this.canvas.getBoundingClientRect();
@@ -1473,6 +1494,7 @@ var OverlayScene = class {
1473
1494
  if (dx !== 0 || dy !== 0) {
1474
1495
  Matter5.Body.translate(entry.body, { x: dx, y: dy });
1475
1496
  }
1497
+ this.grabVelocity = { x: dx * 0.5 + this.grabVelocity.x * 0.5, y: dy * 0.5 + this.grabVelocity.y * 0.5 };
1476
1498
  this.lastGrabMousePosition = { x: mouseTarget.x, y: mouseTarget.y };
1477
1499
  }
1478
1500
  }
@@ -1480,7 +1502,7 @@ var OverlayScene = class {
1480
1502
  const isDragging = this.grabbedObjectId === entry.id;
1481
1503
  if (!isDragging) {
1482
1504
  for (const tag of entry.tags) {
1483
- const key = tag === "follow" ? "mouse" : tag.startsWith("follow-") ? tag.slice(7) : null;
1505
+ const key = tag === "window_follow" ? "mouse" : tag.startsWith("follow-") ? tag.slice(7) : null;
1484
1506
  if (key) {
1485
1507
  const target = this.followTargets.get(key);
1486
1508
  if (target) {
@@ -1525,6 +1547,9 @@ var OverlayScene = class {
1525
1547
  Matter5.Composite.add(this.engine.world, this.boundaries);
1526
1548
  this.checkInitialFloorIntegrity();
1527
1549
  this.mouse = Matter5.Mouse.create(canvas);
1550
+ canvas.addEventListener("mousedown", this.handleMouseDown);
1551
+ canvas.addEventListener("mousemove", this.handleMouseMove);
1552
+ canvas.addEventListener("mouseup", this.handleMouseUp);
1528
1553
  canvas.addEventListener("click", this.handleCanvasClick);
1529
1554
  this.effectManager = new EffectManager(
1530
1555
  this.config.bounds,
@@ -1947,6 +1972,9 @@ var OverlayScene = class {
1947
1972
  }
1948
1973
  destroy() {
1949
1974
  this.stop();
1975
+ this.canvas.removeEventListener("mousedown", this.handleMouseDown);
1976
+ this.canvas.removeEventListener("mousemove", this.handleMouseMove);
1977
+ this.canvas.removeEventListener("mouseup", this.handleMouseUp);
1950
1978
  this.canvas.removeEventListener("click", this.handleCanvasClick);
1951
1979
  Matter5.Events.off(this.render, "beforeRender", this.handleBeforeRender);
1952
1980
  Matter5.Events.off(this.render, "afterRender", this.handleAfterRender);
@@ -2009,8 +2037,8 @@ var OverlayScene = class {
2009
2037
  * Spawn an object synchronously.
2010
2038
  * Object behavior is determined by tags:
2011
2039
  * - 'falling': Object is dynamic (affected by gravity)
2012
- * - 'follow': Object follows mouse when grounded
2013
- * - 'grabable': Object can be dragged
2040
+ * - 'window_follow': Object follows mouse when grounded (walks toward mouse)
2041
+ * - 'grabable': Object can be grabbed and moved with mouse
2014
2042
  * Without 'falling' tag, object is static.
2015
2043
  */
2016
2044
  spawnObject(config) {
@@ -2310,6 +2338,9 @@ var OverlayScene = class {
2310
2338
  if (entry && entry.tags.includes("grabable")) {
2311
2339
  this.grabbedObjectId = entry.id;
2312
2340
  this.lastGrabMousePosition = { x: position.x, y: position.y };
2341
+ this.grabVelocity = { x: 0, y: 0 };
2342
+ this.grabbedWasDynamic = !entry.body.isStatic;
2343
+ Matter5.Body.setStatic(entry.body, true);
2313
2344
  return entry.id;
2314
2345
  }
2315
2346
  }
@@ -2319,8 +2350,19 @@ var OverlayScene = class {
2319
2350
  * Release any currently grabbed object.
2320
2351
  */
2321
2352
  endGrab() {
2353
+ if (this.grabbedObjectId && this.grabbedWasDynamic) {
2354
+ const entry = this.objects.get(this.grabbedObjectId);
2355
+ if (entry) {
2356
+ Matter5.Body.setStatic(entry.body, false);
2357
+ Matter5.Sleeping.set(entry.body, false);
2358
+ Matter5.Body.setVelocity(entry.body, this.grabVelocity);
2359
+ Matter5.Body.setAngularVelocity(entry.body, 0);
2360
+ }
2361
+ }
2322
2362
  this.grabbedObjectId = null;
2323
2363
  this.lastGrabMousePosition = null;
2364
+ this.grabbedWasDynamic = false;
2365
+ this.grabVelocity = { x: 0, y: 0 };
2324
2366
  }
2325
2367
  /**
2326
2368
  * Get the ID of the currently grabbed object.