@blorkfield/overlay-core 0.8.11 → 0.10.0
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 +209 -36
- package/dist/index.cjs +350 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -31
- package/dist/index.d.ts +128 -31
- package/dist/index.js +346 -101
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,26 +22,82 @@ pnpm add @blorkfield/overlay-core
|
|
|
22
22
|
|
|
23
23
|
### Tag Based Behavior
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Tags are the source of truth for object behavior. Adding a tag activates the associated effect; removing it deactivates it. There are no separate type systems — the tag array on each object drives everything.
|
|
26
|
+
|
|
27
|
+
Import the tag constants to avoid magic strings:
|
|
26
28
|
|
|
27
29
|
```typescript
|
|
28
|
-
import { TAGS,
|
|
30
|
+
import { TAGS, TAG_STATIC, TAG_GRABABLE, TAG_FOLLOW_WINDOW } from '@blorkfield/overlay-core';
|
|
29
31
|
|
|
30
32
|
// Use individual constants
|
|
31
|
-
scene.spawnObject({ tags: [
|
|
33
|
+
scene.spawnObject({ tags: [TAG_GRABABLE], ... }); // dynamic by default
|
|
34
|
+
scene.spawnObject({ tags: [TAG_STATIC, TAG_GRABABLE], ... }); // static obstacle
|
|
32
35
|
|
|
33
36
|
// Or destructure from TAGS object
|
|
34
|
-
const {
|
|
35
|
-
scene.spawnObject({ tags: [
|
|
37
|
+
const { STATIC, GRABABLE } = TAGS;
|
|
38
|
+
scene.spawnObject({ tags: [STATIC], ... });
|
|
36
39
|
```
|
|
37
40
|
|
|
38
41
|
| Constant | Value | Behavior |
|
|
39
42
|
|----------|-------|----------|
|
|
40
|
-
| `
|
|
41
|
-
| `TAG_FOLLOW_WINDOW` / `TAGS.FOLLOW_WINDOW` | `'follow_window'` | Object
|
|
43
|
+
| `TAG_STATIC` / `TAGS.STATIC` | `'static'` | Object is a static obstacle, not affected by gravity. Without this tag, objects are dynamic by default. |
|
|
44
|
+
| `TAG_FOLLOW_WINDOW` / `TAGS.FOLLOW_WINDOW` | `'follow_window'` | Object walks toward a target when grounded (default: mouse) |
|
|
42
45
|
| `TAG_GRABABLE` / `TAGS.GRABABLE` | `'grabable'` | Object can be grabbed and moved with mouse |
|
|
46
|
+
| `TAG_GRAVITY_OVERRIDE` / `TAGS.GRAVITY_OVERRIDE` | `'gravity_override'` | Object uses its own gravity vector instead of scene gravity |
|
|
47
|
+
| `TAG_SPEED_OVERRIDE` / `TAGS.SPEED_OVERRIDE` | `'speed_override'` | Multiplies movement speed for `follow_window` and future movement behaviors. Negative = run away from target. |
|
|
48
|
+
| `TAG_MASS_OVERRIDE` / `TAGS.MASS_OVERRIDE` | `'mass_override'` | Overrides the physics mass. Higher mass resists follow forces more; lower mass allows the follow force to overcome gravity. |
|
|
49
|
+
|
|
50
|
+
Tags can be added and removed at runtime to change behavior dynamically:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
scene.addTag(id, 'static'); // freeze an object in place
|
|
54
|
+
scene.removeTag(id, 'static'); // release it to fall
|
|
55
|
+
scene.addTag(id, 'grabable'); // make it grabbable
|
|
56
|
+
scene.removeTag(id, 'grabable'); // prevent grabbing
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The `gravity_override` tag carries a value (a Vector2). Use `setObjectGravityOverride` to set the value and activate the tag, or pass it via `gravityOverride` in spawn config. Removing the tag restores scene gravity.
|
|
60
|
+
|
|
61
|
+
The `speed_override` tag carries a numeric multiplier. Use `setObjectSpeedOverride` to set the value and activate the tag, or pass it via `speedOverride` in spawn config. Removing the tag restores default speed.
|
|
62
|
+
|
|
63
|
+
The `mass_override` tag carries a numeric mass value. Use `setObjectMassOverride` to set the value and activate the tag, or pass it via `massOverride` in spawn config. Removing the tag restores the natural density-based mass.
|
|
64
|
+
|
|
65
|
+
### Entity Tags
|
|
66
|
+
|
|
67
|
+
Every spawned object is automatically assigned a permanent, human-readable **entity tag** that serves as its stable identity. The format is derived from the object's shape or image:
|
|
68
|
+
|
|
69
|
+
| Object type | Entity tag format | Example |
|
|
70
|
+
|-------------|-------------------|---------|
|
|
71
|
+
| Circle | `circle-<4hex>` | `circle-a3f2` |
|
|
72
|
+
| Rectangle | `rect-<4hex>` | `rect-b1c4` |
|
|
73
|
+
| Image-based | `<filename>-<4hex>` | `cat-e9d2` |
|
|
74
|
+
| Text letter | `letter-<char>-<4hex>` | `letter-h-7a3f` |
|
|
75
|
+
| DOM element | `dom-<4hex>` | `dom-5c21` |
|
|
76
|
+
|
|
77
|
+
Entity tags appear in `getAllTags()` alongside all other tags, making them usable as follow targets or for runtime queries. They **cannot be removed** — calling `removeTag(id, entityTag)` will log a warning and return without effect. This ensures every object always has a stable, identifiable tag.
|
|
78
|
+
|
|
79
|
+
### `follow_window` Tag Target
|
|
80
|
+
|
|
81
|
+
The `follow_window` tag walks an object toward a target when grounded. The default target is `'mouse'`. You can change it at any time:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// Follow the mouse (default)
|
|
85
|
+
scene.addTag(id, 'follow_window');
|
|
43
86
|
|
|
44
|
-
|
|
87
|
+
// Follow a named target (e.g., another entity's tag)
|
|
88
|
+
scene.setFollowWindowTarget(id, 'circle-a3f2');
|
|
89
|
+
|
|
90
|
+
// Follow any entity that has a given tag
|
|
91
|
+
scene.setFollowWindowTarget(id, 'letter-h-7a3f');
|
|
92
|
+
|
|
93
|
+
// Follow a string/word group tag
|
|
94
|
+
scene.setFollowWindowTarget(id, 'title-text');
|
|
95
|
+
|
|
96
|
+
// Stop following by removing the tag
|
|
97
|
+
scene.removeTag(id, 'follow_window');
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Target resolution order: named follow targets (e.g., `'mouse'`) → object ID → first object with a matching tag.
|
|
45
101
|
|
|
46
102
|
### Pressure System
|
|
47
103
|
|
|
@@ -82,7 +138,7 @@ const { canvas, bounds } = OverlayScene.createContainer(container, {
|
|
|
82
138
|
// Create scene
|
|
83
139
|
const scene = new OverlayScene(canvas, {
|
|
84
140
|
bounds,
|
|
85
|
-
gravity: 1,
|
|
141
|
+
gravity: { x: 0, y: -1 },
|
|
86
142
|
wrapHorizontal: true,
|
|
87
143
|
background: 'transparent'
|
|
88
144
|
});
|
|
@@ -97,22 +153,22 @@ All objects are created through `spawnObject()` (or `spawnObjectAsync()` for ima
|
|
|
97
153
|
### Basic Shapes
|
|
98
154
|
|
|
99
155
|
```typescript
|
|
100
|
-
// Circle (dynamic
|
|
156
|
+
// Circle (dynamic by default — falls with gravity)
|
|
101
157
|
scene.spawnObject({
|
|
102
158
|
x: 100,
|
|
103
159
|
y: 50,
|
|
104
160
|
radius: 20,
|
|
105
161
|
fillStyle: '#ff0000',
|
|
106
|
-
tags: ['falling']
|
|
107
162
|
});
|
|
108
163
|
|
|
109
|
-
// Rectangle (static
|
|
164
|
+
// Rectangle (static obstacle — won't move)
|
|
110
165
|
scene.spawnObject({
|
|
111
166
|
x: 200,
|
|
112
167
|
y: 300,
|
|
113
168
|
width: 100,
|
|
114
169
|
height: 20,
|
|
115
|
-
fillStyle: '#0000ff'
|
|
170
|
+
fillStyle: '#0000ff',
|
|
171
|
+
tags: ['static']
|
|
116
172
|
});
|
|
117
173
|
|
|
118
174
|
// Polygon shapes
|
|
@@ -121,7 +177,6 @@ scene.spawnObject({
|
|
|
121
177
|
y: 100,
|
|
122
178
|
radius: 25,
|
|
123
179
|
fillStyle: '#00ff00',
|
|
124
|
-
tags: ['falling'],
|
|
125
180
|
shape: { type: 'hexagon' }
|
|
126
181
|
});
|
|
127
182
|
```
|
|
@@ -136,7 +191,7 @@ const id = await scene.spawnObjectAsync({
|
|
|
136
191
|
y: 100,
|
|
137
192
|
imageUrl: '/images/coin.png',
|
|
138
193
|
size: 50,
|
|
139
|
-
tags: ['
|
|
194
|
+
tags: ['grabable'] // dynamic by default
|
|
140
195
|
});
|
|
141
196
|
```
|
|
142
197
|
|
|
@@ -241,14 +296,16 @@ const result = await scene.addTTFTextObstacles({
|
|
|
241
296
|
});
|
|
242
297
|
```
|
|
243
298
|
|
|
299
|
+
Text obstacles default to `isStatic: true` — they are static obstacles that things fall onto. Pass `isStatic: false` to spawn falling text instead.
|
|
300
|
+
|
|
244
301
|
### Managing Text Obstacles
|
|
245
302
|
|
|
246
303
|
```typescript
|
|
247
|
-
// Spawn text that immediately falls (
|
|
304
|
+
// Spawn text that immediately falls (isStatic: false)
|
|
248
305
|
const result = await scene.spawnFallingTextObstacles(config);
|
|
249
306
|
const result = await scene.spawnFallingTTFTextObstacles(config);
|
|
250
307
|
|
|
251
|
-
// Release text obstacles (
|
|
308
|
+
// Release static text obstacles (removes 'static' tag so they fall)
|
|
252
309
|
scene.releaseTextObstacles(wordTag);
|
|
253
310
|
|
|
254
311
|
// Release letters one by one with delay
|
|
@@ -279,7 +336,7 @@ scene.setEffect({
|
|
|
279
336
|
objectConfig: {
|
|
280
337
|
radius: 15,
|
|
281
338
|
fillStyle: '#4a90d9',
|
|
282
|
-
tags
|
|
339
|
+
// dynamic by default — no tags needed
|
|
283
340
|
},
|
|
284
341
|
probability: 1,
|
|
285
342
|
minScale: 0.8,
|
|
@@ -341,14 +398,24 @@ scene.removeAllObjects();
|
|
|
341
398
|
scene.removeAll(); // Alias for removeAllObjects
|
|
342
399
|
scene.removeAllByTag('tag'); // Alias for removeObjectsByTag
|
|
343
400
|
|
|
344
|
-
// Add or remove tags
|
|
345
|
-
scene.addTag(id, '
|
|
346
|
-
scene.
|
|
347
|
-
scene.
|
|
401
|
+
// Add or remove tags — tags drive behavior, changes take effect immediately
|
|
402
|
+
scene.addTag(id, 'grabable');
|
|
403
|
+
scene.removeTag(id, 'static'); // releases a static object to fall
|
|
404
|
+
scene.addTag(id, 'static'); // freezes a dynamic object in place
|
|
405
|
+
scene.addFallingTag(id); // convenience: removes 'static', adds 'grabable'
|
|
406
|
+
scene.setFollowWindowTarget(id, 'mouse'); // change what a follow_window object walks toward
|
|
407
|
+
scene.setObjectSpeedOverride(id, 2); // double movement speed (negative = run away)
|
|
408
|
+
scene.setObjectSpeedOverride(id, null); // remove speed override
|
|
409
|
+
scene.setObjectMassOverride(id, 50); // heavy object resists follow force
|
|
410
|
+
scene.setObjectMassOverride(id, null); // restore natural mass
|
|
411
|
+
scene.setPosition(id, { x: 400, y: 300 }); // teleport object
|
|
412
|
+
scene.setVelocity(id, { x: 10, y: 0 }); // launch object rightward
|
|
413
|
+
scene.setObjectAngularVelocity(id, Math.PI); // set spin (rad/s)
|
|
414
|
+
scene.setObjectScale(id, 2, 2); // scale x and y independently
|
|
348
415
|
|
|
349
416
|
// Get object info
|
|
350
417
|
const ids = scene.getObjectIds();
|
|
351
|
-
const tagged = scene.getObjectIdsByTag('
|
|
418
|
+
const tagged = scene.getObjectIdsByTag('static');
|
|
352
419
|
const allTags = scene.getAllTags();
|
|
353
420
|
|
|
354
421
|
// Get full object state
|
|
@@ -361,13 +428,25 @@ const objs = scene.getObjectsByTag('tag'); // Returns ObjectState[]
|
|
|
361
428
|
```typescript
|
|
362
429
|
// Apply force to objects
|
|
363
430
|
scene.applyForce(id, { x: 0.01, y: -0.02 });
|
|
364
|
-
scene.applyForceToTag('
|
|
431
|
+
scene.applyForceToTag('grabable', { x: 0.005, y: 0 });
|
|
365
432
|
|
|
366
|
-
// Set velocity directly
|
|
367
|
-
scene.setVelocity(id, { x: 5, y:
|
|
433
|
+
// Set velocity directly (physical convention: positive y = upward, negative y = downward)
|
|
434
|
+
scene.setVelocity(id, { x: 5, y: 10 }); // moving right and upward
|
|
435
|
+
scene.setVelocity(id, { x: 0, y: -10 }); // moving downward
|
|
436
|
+
scene.setVelocity(id, { x: 0, y: 0 }); // stop all movement
|
|
368
437
|
|
|
369
|
-
// Set position directly
|
|
438
|
+
// Set position directly (screen pixels, y=0 at top)
|
|
370
439
|
scene.setPosition(id, { x: 100, y: 200 });
|
|
440
|
+
|
|
441
|
+
// Set angular velocity (spin) in radians/second
|
|
442
|
+
// Positive = counter-clockwise, negative = clockwise
|
|
443
|
+
scene.setObjectAngularVelocity(id, Math.PI); // half-rotation per second CCW
|
|
444
|
+
scene.setObjectAngularVelocity(id, 0); // stop spinning
|
|
445
|
+
|
|
446
|
+
// Scale an object (updates both physics shape and sprite rendering)
|
|
447
|
+
scene.setObjectScale(id, 2, 2); // double size uniformly
|
|
448
|
+
scene.setObjectScale(id, 2, 0.5); // stretch wide, squash tall
|
|
449
|
+
scene.setObjectScale(id, 1, 1); // restore original size
|
|
371
450
|
```
|
|
372
451
|
|
|
373
452
|
## Mouse Position and Grab API
|
|
@@ -426,7 +505,7 @@ const currentGrab = scene.getGrabbedObject(); // Returns ID or null
|
|
|
426
505
|
```typescript
|
|
427
506
|
const scene = new OverlayScene(canvas, {
|
|
428
507
|
bounds: { top: 0, bottom: 600, left: 0, right: 800 },
|
|
429
|
-
gravity: 1,
|
|
508
|
+
gravity: { x: 0, y: -1 },
|
|
430
509
|
wrapHorizontal: true,
|
|
431
510
|
debug: false,
|
|
432
511
|
background: '#16213e',
|
|
@@ -443,7 +522,7 @@ const scene = new OverlayScene(canvas, {
|
|
|
443
522
|
|
|
444
523
|
| Option | Default | Description |
|
|
445
524
|
|--------|---------|-------------|
|
|
446
|
-
| `gravity` | 1 | Gravity
|
|
525
|
+
| `gravity` | `{ x: 0, y: 1 }` | Gravity vector. Both axes support negative values |
|
|
447
526
|
| `wrapHorizontal` | true | Objects wrap around screen edges |
|
|
448
527
|
| `debug` | false | Show collision wireframes |
|
|
449
528
|
| `background` | transparent | Canvas background color |
|
|
@@ -507,7 +586,7 @@ Called every frame with all dynamic object states:
|
|
|
507
586
|
|
|
508
587
|
```typescript
|
|
509
588
|
scene.onUpdate((data) => {
|
|
510
|
-
// data.objects contains all dynamic (
|
|
589
|
+
// data.objects contains all dynamic objects (those without the 'static' tag)
|
|
511
590
|
for (const obj of data.objects) {
|
|
512
591
|
console.log(obj.id, obj.x, obj.y, obj.angle, obj.tags);
|
|
513
592
|
}
|
|
@@ -641,11 +720,104 @@ setLogLevel('debug'); // Options: debug, info, warn, error
|
|
|
641
720
|
## Lifecycle
|
|
642
721
|
|
|
643
722
|
```typescript
|
|
644
|
-
scene.start();
|
|
645
|
-
scene.stop();
|
|
646
|
-
scene.resize(w, h);
|
|
647
|
-
scene.setDebug(true);
|
|
648
|
-
scene.
|
|
723
|
+
scene.start(); // Start simulation
|
|
724
|
+
scene.stop(); // Pause simulation
|
|
725
|
+
scene.resize(w, h); // Resize canvas and bounds
|
|
726
|
+
scene.setDebug(true); // Toggle wireframe mode
|
|
727
|
+
scene.setGravity({ x: 0, y: -1 }); // Set gravity (negative y = upward)
|
|
728
|
+
scene.setGravity({ x: 0, y: 0 }); // Zero gravity
|
|
729
|
+
scene.setGravity({ x: 1, y: 0 }); // Sideways gravity
|
|
730
|
+
scene.destroy(); // Clean up resources
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
### Per-Object Gravity Override
|
|
734
|
+
|
|
735
|
+
Dynamic objects can have their own gravity vector instead of the scene gravity. Set it via `gravityOverride` in spawn config, or change it at runtime with `setObjectGravityOverride`. This automatically adds or removes the `gravity_override` tag.
|
|
736
|
+
|
|
737
|
+
```typescript
|
|
738
|
+
// Spawn a floaty object that drifts upward
|
|
739
|
+
scene.spawnObject({
|
|
740
|
+
x: 200, y: 300,
|
|
741
|
+
radius: 20,
|
|
742
|
+
fillStyle: '#4a90d9',
|
|
743
|
+
tags: ['grabable'],
|
|
744
|
+
gravityOverride: { x: 0, y: -0.3 } // floats upward
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
// Zero gravity — hovers in place
|
|
748
|
+
scene.spawnObject({
|
|
749
|
+
x: 400, y: 200,
|
|
750
|
+
radius: 15,
|
|
751
|
+
fillStyle: '#e94560',
|
|
752
|
+
gravityOverride: { x: 0, y: 0 }
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
// Change or clear a gravity override at runtime
|
|
756
|
+
scene.setObjectGravityOverride(id, { x: 0.5, y: 0 }); // drift sideways
|
|
757
|
+
scene.setObjectGravityOverride(id, null); // restore scene gravity
|
|
758
|
+
|
|
759
|
+
// removeTag works too — setObjectGravityOverride(id, null) calls it internally
|
|
760
|
+
scene.removeTag(id, 'gravity_override'); // restores scene gravity
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
Tags are the source of truth for all behavior. Boolean tags (presence = active, absence = inactive). `gravity_override` additionally carries a Vector2 value managed via `setObjectGravityOverride` or `gravityOverride` in spawn config.
|
|
764
|
+
|
|
765
|
+
| Tag | Behavior |
|
|
766
|
+
|-----|----------|
|
|
767
|
+
| `static` | Static obstacle, not affected by gravity. Absent by default — objects are dynamic unless tagged static. |
|
|
768
|
+
| `grabable` | Can be grabbed and dragged with the mouse |
|
|
769
|
+
| `follow_window` | Always applies a directional force toward its target (in all axes). Gravity determines whether the entity can actually reach targets above/below it. |
|
|
770
|
+
| `gravity_override` | Uses its own gravity vector instead of scene gravity (value set via `setObjectGravityOverride`) |
|
|
771
|
+
| `speed_override` | Multiplies movement speed for `follow_window` and future movement behaviors (value set via `setObjectSpeedOverride`). Negative = runs away from target. Default multiplier: 1 |
|
|
772
|
+
| `mass_override` | Overrides physics mass (value set via `setObjectMassOverride`). Higher mass resists follow forces; lower mass may allow entity to overcome gravity. |
|
|
773
|
+
|
|
774
|
+
### Speed Override
|
|
775
|
+
|
|
776
|
+
Objects with `follow_window` move toward their target at default speed. `speed_override` multiplies this force. Negative values reverse the direction, causing the object to run away.
|
|
777
|
+
|
|
778
|
+
```typescript
|
|
779
|
+
// Spawn a fast follower
|
|
780
|
+
scene.spawnObject({
|
|
781
|
+
tags: ['follow_window'],
|
|
782
|
+
speedOverride: 3, // 3× normal speed — automatically adds 'speed_override' tag
|
|
783
|
+
// ...
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
// Spawn a coward that runs away from the mouse
|
|
787
|
+
scene.spawnObject({
|
|
788
|
+
tags: ['follow_window'],
|
|
789
|
+
speedOverride: -2, // flees at 2× speed
|
|
790
|
+
// ...
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
// Change speed at runtime
|
|
794
|
+
scene.setObjectSpeedOverride(id, 5); // very fast follower
|
|
795
|
+
scene.setObjectSpeedOverride(id, -1); // now runs away at normal speed
|
|
796
|
+
scene.setObjectSpeedOverride(id, null); // remove override, restore default speed
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
### Mass Override
|
|
800
|
+
|
|
801
|
+
Entities have a default density of `0.005`, which gives typical sizes a mass of ~6–20 units — enough that normal gravity prevents the follow force from lifting them vertically. `mass_override` lets you change this at spawn or runtime.
|
|
802
|
+
|
|
803
|
+
```typescript
|
|
804
|
+
// Light object — follow force can overcome normal gravity, moves freely in all directions
|
|
805
|
+
scene.spawnObject({
|
|
806
|
+
tags: ['follow_window'],
|
|
807
|
+
massOverride: 1,
|
|
808
|
+
// ...
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
// Very heavy object — barely moves toward target under normal gravity
|
|
812
|
+
scene.spawnObject({
|
|
813
|
+
tags: ['follow_window'],
|
|
814
|
+
massOverride: 100,
|
|
815
|
+
// ...
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
// Change or clear mass at runtime
|
|
819
|
+
scene.setObjectMassOverride(id, 50); // now heavy
|
|
820
|
+
scene.setObjectMassOverride(id, null); // restore natural mass
|
|
649
821
|
```
|
|
650
822
|
|
|
651
823
|
## Examples
|
|
@@ -673,6 +845,7 @@ import type {
|
|
|
673
845
|
// Scene configuration
|
|
674
846
|
OverlaySceneConfig,
|
|
675
847
|
Bounds,
|
|
848
|
+
Vector2,
|
|
676
849
|
ContainerOptions,
|
|
677
850
|
FloorConfig,
|
|
678
851
|
|
|
@@ -732,5 +905,5 @@ import type {
|
|
|
732
905
|
} from '@blorkfield/overlay-core';
|
|
733
906
|
|
|
734
907
|
// Tag constants (values, not types)
|
|
735
|
-
import { TAGS, TAG_FALLING, TAG_GRABABLE, TAG_FOLLOW_WINDOW } from '@blorkfield/overlay-core';
|
|
908
|
+
import { TAGS, TAG_FALLING, TAG_GRABABLE, TAG_FOLLOW_WINDOW, TAG_GRAVITY_OVERRIDE } from '@blorkfield/overlay-core';
|
|
736
909
|
```
|