@blorkfield/overlay-core 0.8.7 → 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/README.md CHANGED
@@ -27,7 +27,7 @@ Objects don't have fixed types. Instead, their behavior is determined by string
27
27
  | Tag | Behavior |
28
28
  |-----|----------|
29
29
  | `falling` | Object is dynamic and affected by gravity |
30
- | `follow` | Object follows mouse position when grounded |
30
+ | `window_follow` | Object follows mouse position when grounded |
31
31
  | `grabable` | Object can be dragged via mouse constraint |
32
32
 
33
33
  Without the `falling` tag, objects are static and won't move.
@@ -153,6 +153,11 @@ When a DOM element collapses:
153
153
  - The element's CSS transform is updated each frame to follow physics
154
154
  - Shadow creates a cloned DOM element at the original position
155
155
 
156
+ ```typescript
157
+ // Get the shadow element after collapse (if shadow was configured)
158
+ const shadowEl = scene.getDOMObstacleShadow(id);
159
+ ```
160
+
156
161
  ### Pressure, Shadow, and Click Behavior
157
162
 
158
163
  These options work on any spawned object (shapes, images, or DOM elements):
@@ -225,6 +230,25 @@ const result = await scene.addTTFTextObstacles({
225
230
  });
226
231
  ```
227
232
 
233
+ ### Managing Text Obstacles
234
+
235
+ ```typescript
236
+ // Spawn text that immediately falls (already has 'falling' tag)
237
+ const result = await scene.spawnFallingTextObstacles(config);
238
+ const result = await scene.spawnFallingTTFTextObstacles(config);
239
+
240
+ // Release text obstacles (add 'falling' tag)
241
+ scene.releaseTextObstacles(wordTag);
242
+
243
+ // Release letters one by one with delay
244
+ await scene.releaseTextObstaclesSequentially(wordTag, 100); // 100ms delay
245
+ await scene.releaseTextObstaclesSequentially(wordTag, 100, true); // reverse order
246
+
247
+ // Get debug info for letter positioning
248
+ const debugInfo = scene.getLetterDebugInfo(wordTag);
249
+ const allDebug = scene.getAllLetterDebugInfo();
250
+ ```
251
+
228
252
  ## Effects
229
253
 
230
254
  Effects are persistent spawning mechanisms that create objects over time.
@@ -294,22 +318,45 @@ scene.setEffect({
294
318
  ```typescript
295
319
  // Release objects (make them fall)
296
320
  scene.releaseObject(id);
321
+ scene.releaseObjects([id1, id2]);
297
322
  scene.releaseObjectsByTag('my-text');
298
323
  scene.releaseAllObjects();
299
324
 
300
325
  // Remove objects
301
326
  scene.removeObject(id);
327
+ scene.removeObjects([id1, id2]);
302
328
  scene.removeObjectsByTag('welcome-text');
303
329
  scene.removeAllObjects();
330
+ scene.removeAll(); // Alias for removeAllObjects
331
+ scene.removeAllByTag('tag'); // Alias for removeObjectsByTag
304
332
 
305
333
  // Add or remove tags
306
334
  scene.addTag(id, 'falling');
335
+ scene.addFallingTag(id); // Convenience for adding 'falling' tag
307
336
  scene.removeTag(id, 'grabable');
308
337
 
309
338
  // Get object info
310
339
  const ids = scene.getObjectIds();
311
340
  const tagged = scene.getObjectIdsByTag('falling');
312
341
  const allTags = scene.getAllTags();
342
+
343
+ // Get full object state
344
+ const obj = scene.getObject(id); // Returns ObjectState or null
345
+ const objs = scene.getObjectsByTag('tag'); // Returns ObjectState[]
346
+ ```
347
+
348
+ ## Physics Manipulation
349
+
350
+ ```typescript
351
+ // Apply force to objects
352
+ scene.applyForce(id, { x: 0.01, y: -0.02 });
353
+ scene.applyForceToTag('falling', { x: 0.005, y: 0 });
354
+
355
+ // Set velocity directly
356
+ scene.setVelocity(id, { x: 5, y: -10 });
357
+
358
+ // Set position directly
359
+ scene.setPosition(id, { x: 100, y: 200 });
313
360
  ```
314
361
 
315
362
  ## Mouse Position and Grab API
@@ -352,9 +399,11 @@ const currentGrab = scene.getGrabbedObject(); // Returns ID or null
352
399
 
353
400
  | Method | Returns | Description |
354
401
  |--------|---------|-------------|
355
- | `setFollowTarget('mouse', x, y)` | void | Set mouse position for follow behavior and grab detection |
402
+ | `setFollowTarget(key, x, y)` | void | Set a follow target position (e.g., 'mouse' for grab/follow behavior) |
403
+ | `removeFollowTarget(key)` | void | Remove a follow target |
404
+ | `getFollowTargetKeys()` | string[] | Get all active follow target keys |
356
405
  | `startGrab()` | string \| null | Link entity at current mouse position to mouse, returns entity ID |
357
- | `endGrab()` | void | Unlink currently grabbed entity |
406
+ | `endGrab()` | void | Unlink currently grabbed entity (applies release velocity) |
358
407
  | `getGrabbedObject()` | string \| null | Get ID of currently grabbed entity |
359
408
 
360
409
  ## Configuration
@@ -393,6 +442,34 @@ const scene = new OverlayScene(canvas, {
393
442
  | `floorConfig.segmentWidths` | none | Proportional widths for each segment (array that sums to 1.0) |
394
443
  | `despawnBelowFloor` | 1.0 | Distance below floor to despawn objects (as fraction of height) |
395
444
 
445
+ ### Background Configuration
446
+
447
+ The `background` option supports multiple formats:
448
+
449
+ ```typescript
450
+ // Simple color
451
+ background: '#16213e'
452
+ background: 'transparent'
453
+
454
+ // Full configuration with layers
455
+ background: {
456
+ color: '#16213e', // Base color layer
457
+ image: {
458
+ url: '/images/bg.png',
459
+ sizing: 'cover' // 'stretch' | 'center' | 'tile' | 'cover' | 'contain'
460
+ },
461
+ transparency: {
462
+ mode: 'checkerboard', // Visual indicator for transparent areas
463
+ color1: '#ffffff',
464
+ color2: '#cccccc',
465
+ size: 10
466
+ }
467
+ }
468
+
469
+ // Change background at runtime
470
+ await scene.setBackground({ color: '#000000' });
471
+ ```
472
+
396
473
  ## Pressure Tracking
397
474
 
398
475
  ```typescript
@@ -409,7 +486,11 @@ const allPressure = scene.getAllPressure();
409
486
  const summary = scene.getPressureSummary();
410
487
  ```
411
488
 
412
- ## Update Callbacks
489
+ ## Callbacks and Events
490
+
491
+ ### Update Callback
492
+
493
+ Called every frame with all dynamic object states:
413
494
 
414
495
  ```typescript
415
496
  scene.onUpdate((data) => {
@@ -420,6 +501,30 @@ scene.onUpdate((data) => {
420
501
  });
421
502
  ```
422
503
 
504
+ ### Lifecycle Events
505
+
506
+ Subscribe to object lifecycle events:
507
+
508
+ ```typescript
509
+ // Object spawned
510
+ scene.on('objectSpawned', (obj) => {
511
+ console.log(`Spawned: ${obj.id}`, obj.x, obj.y);
512
+ });
513
+
514
+ // Object removed
515
+ scene.on('objectRemoved', (obj) => {
516
+ console.log(`Removed: ${obj.id}`);
517
+ });
518
+
519
+ // Objects collided
520
+ scene.on('objectCollision', (a, b) => {
521
+ console.log(`Collision: ${a.id} hit ${b.id}`);
522
+ });
523
+
524
+ // Unsubscribe
525
+ scene.off('objectSpawned', myCallback);
526
+ ```
527
+
423
528
  ## Font Setup
424
529
 
425
530
  ### Bundled Fonts
@@ -496,6 +601,22 @@ Add the font file and reference it in the manifest:
496
601
  }
497
602
  ```
498
603
 
604
+ ### Font API
605
+
606
+ ```typescript
607
+ // Initialize fonts from a directory
608
+ await scene.initializeFonts('/fonts/');
609
+
610
+ // Check initialization status
611
+ if (scene.areFontsInitialized()) {
612
+ // Get available fonts
613
+ const fonts = scene.getAvailableFonts(); // Returns FontInfo[]
614
+ const font = scene.getFontByName('Roboto'); // Returns FontInfo | undefined
615
+ const font = scene.getFontByIndex(0); // Returns FontInfo | undefined
616
+ const defaultFont = scene.getDefaultFont(); // Returns first font or undefined
617
+ }
618
+ ```
619
+
499
620
  ## Logging
500
621
 
501
622
  ```typescript
@@ -536,18 +657,61 @@ The package is written in TypeScript and ships with full type definitions. All c
536
657
 
537
658
  ```typescript
538
659
  import type {
660
+ // Scene configuration
539
661
  OverlaySceneConfig,
662
+ Bounds,
663
+ ContainerOptions,
664
+ FloorConfig,
665
+
666
+ // Object types
540
667
  ObjectConfig,
668
+ DynamicObject,
669
+ ObjectState,
670
+ ShapeConfig,
671
+ ShapePreset,
672
+ DespawnEffectConfig,
673
+
674
+ // Text obstacle types
541
675
  TextObstacleConfig,
676
+ TextObstacleResult,
542
677
  TTFTextObstacleConfig,
678
+ TextAlign,
679
+ TextBounds,
680
+
681
+ // Effect types
543
682
  EffectConfig,
683
+ EffectType,
684
+ EffectObjectConfig,
685
+ BaseEffectConfig,
544
686
  BurstEffectConfig,
545
687
  RainEffectConfig,
546
688
  StreamEffectConfig,
689
+
690
+ // Pressure, weight, shadow, click types
547
691
  PressureThresholdConfig,
548
692
  WeightConfig,
549
693
  ShadowConfig,
550
694
  ClickToFallConfig,
551
- FloorConfig
695
+
696
+ // Background types
697
+ BackgroundConfig,
698
+ BackgroundImageConfig,
699
+ BackgroundImageSizing,
700
+ BackgroundTransparencyConfig,
701
+
702
+ // Font types
703
+ FontInfo,
704
+ FontManifest,
705
+ LoadedFont,
706
+ GlyphData,
707
+
708
+ // Lifecycle types
709
+ LifecycleEvent,
710
+ LifecycleCallback,
711
+ UpdateCallback,
712
+ UpdateCallbackData,
713
+
714
+ // Logging
715
+ LogLevel
552
716
  } from '@blorkfield/overlay-core';
553
717
  ```
package/dist/index.cjs CHANGED
@@ -1547,7 +1547,7 @@ var OverlayScene = class {
1547
1547
  const isDragging = this.grabbedObjectId === entry.id;
1548
1548
  if (!isDragging) {
1549
1549
  for (const tag of entry.tags) {
1550
- const key = tag === "follow" ? "mouse" : tag.startsWith("follow-") ? tag.slice(7) : null;
1550
+ const key = tag === "window_follow" ? "mouse" : tag.startsWith("follow-") ? tag.slice(7) : null;
1551
1551
  if (key) {
1552
1552
  const target = this.followTargets.get(key);
1553
1553
  if (target) {
@@ -2082,8 +2082,8 @@ var OverlayScene = class {
2082
2082
  * Spawn an object synchronously.
2083
2083
  * Object behavior is determined by tags:
2084
2084
  * - 'falling': Object is dynamic (affected by gravity)
2085
- * - 'follow': Object follows mouse when grounded
2086
- * - 'grabable': Object can be dragged
2085
+ * - 'window_follow': Object follows mouse when grounded (walks toward mouse)
2086
+ * - 'grabable': Object can be grabbed and moved with mouse
2087
2087
  * Without 'falling' tag, object is static.
2088
2088
  */
2089
2089
  spawnObject(config) {