@vectojs/core 0.1.0 → 0.2.1

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.
Files changed (46) hide show
  1. package/dist/animation/drivers.d.ts +48 -0
  2. package/dist/animation/easing.d.ts +16 -0
  3. package/dist/{chunk-M2IZPGOL.mjs → chunk-H3QIE77O.mjs} +316 -12
  4. package/dist/{chunk-53DAQC3U.js → chunk-LA3FJLP2.js} +369 -65
  5. package/dist/components/GridTextEntity.d.ts +15 -0
  6. package/dist/components/SplineEntity.d.ts +144 -0
  7. package/dist/components/TextEntity.d.ts +35 -0
  8. package/dist/index.d.ts +26 -577
  9. package/dist/index.js +121 -136
  10. package/dist/index.mjs +19 -34
  11. package/dist/{layout.d.mts → layout/LayoutEngine.d.ts} +15 -70
  12. package/dist/layout/LayoutWorker.d.ts +23 -0
  13. package/dist/layout/LayoutWorkerManager.d.ts +22 -0
  14. package/dist/layout/LayoutWorkerSource.d.ts +1 -0
  15. package/dist/layout/index.d.ts +3 -0
  16. package/dist/layout/measure.d.ts +20 -0
  17. package/dist/math/SpatialHashGrid.d.ts +53 -0
  18. package/dist/math/SpringPhysics.d.ts +13 -0
  19. package/dist/renderer/CanvasRenderer.d.ts +81 -0
  20. package/dist/renderer/IRenderer.d.ts +178 -0
  21. package/dist/renderer/SVGRenderer.d.ts +69 -0
  22. package/dist/renderer/WebGLPointRenderer.d.ts +62 -0
  23. package/dist/renderer/WebGPUParticleSystemManager.d.ts +14 -0
  24. package/dist/renderer/colorParse.d.ts +17 -0
  25. package/dist/renderer/index.d.ts +6 -0
  26. package/dist/text/ArabicShaper.d.ts +10 -0
  27. package/dist/text/BidiResolver.d.ts +6 -0
  28. package/dist/{text.d.ts → text/MSDFFont.d.ts} +10 -82
  29. package/dist/text/MSDFTextEntity.d.ts +30 -0
  30. package/dist/text/SVGEntity.d.ts +22 -0
  31. package/dist/text/index.d.ts +5 -0
  32. package/dist/text.js +2 -2
  33. package/dist/text.mjs +1 -1
  34. package/dist/tree/ComputeParticleEntity.d.ts +118 -0
  35. package/dist/tree/DOMPortalEntity.d.ts +18 -0
  36. package/dist/{Entity-D-rfAFCf.d.mts → tree/Entity.d.ts} +71 -201
  37. package/dist/tree/Scene.d.ts +302 -0
  38. package/package.json +5 -5
  39. package/dist/Entity-D-rfAFCf.d.ts +0 -572
  40. package/dist/index-ByBDSmMK.d.mts +0 -365
  41. package/dist/index-C3Fd_XmG.d.ts +0 -365
  42. package/dist/index.d.mts +0 -577
  43. package/dist/layout.d.ts +0 -319
  44. package/dist/renderer.d.mts +0 -2
  45. package/dist/renderer.d.ts +0 -2
  46. package/dist/text.d.mts +0 -201
@@ -1,9 +1,123 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7;
2
2
 
3
3
  var _chunkRW6NC4RBjs = require('./chunk-RW6NC4RB.js');
4
4
 
5
+ // src/math/SpringPhysics.ts
6
+ var SpringPhysics = (_class = class {
7
+
8
+
9
+ __init() {this.velocity = 0}
10
+ __init2() {this.stiffness = 180}
11
+ __init3() {this.damping = 12}
12
+ __init4() {this.mass = 1}
13
+ __init5() {this.valEpsilon = 5e-3}
14
+ __init6() {this.velEpsilon = 5e-3}
15
+ constructor(initial) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);
16
+ this.value = initial;
17
+ this.target = initial;
18
+ }
19
+ update(dt) {
20
+ if (this.isAtRest()) {
21
+ this.value = this.target;
22
+ this.velocity = 0;
23
+ return;
24
+ }
25
+ const forceSpring = -this.stiffness * (this.value - this.target);
26
+ const forceDamping = -this.damping * this.velocity;
27
+ const acceleration = (forceSpring + forceDamping) / this.mass;
28
+ this.velocity += acceleration * dt;
29
+ this.value += this.velocity * dt;
30
+ }
31
+ isAtRest() {
32
+ return Math.abs(this.value - this.target) < this.valEpsilon && Math.abs(this.velocity) < this.velEpsilon;
33
+ }
34
+ }, _class);
35
+
36
+ // src/animation/easing.ts
37
+ var c1 = 1.70158;
38
+ var c3 = c1 + 1;
39
+ var Easing = {
40
+ linear: (t) => t,
41
+ easeInQuad: (t) => t * t,
42
+ easeOutQuad: (t) => t * (2 - t),
43
+ easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2,
44
+ easeInCubic: (t) => t * t * t,
45
+ easeOutCubic: (t) => 1 - Math.pow(1 - t, 3),
46
+ easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2,
47
+ easeOutBack: (t) => 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2),
48
+ easeInOutBack: (t) => {
49
+ const c2 = c1 * 1.525;
50
+ return t < 0.5 ? Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2) / 2 : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
51
+ }
52
+ };
53
+
54
+ // src/animation/drivers.ts
55
+ function isTweenConfig(c) {
56
+ return typeof c === "object" && "duration" in c;
57
+ }
58
+ var TweenDriver = (_class2 = class {
59
+
60
+
61
+
62
+ __init7() {this.elapsed = 0}
63
+
64
+
65
+
66
+ constructor(from, to, cfg) {;_class2.prototype.__init7.call(this);
67
+ this.value = from;
68
+ this.from = from;
69
+ this.to = to;
70
+ this.duration = Math.max(1, cfg.duration);
71
+ this.delay = _nullishCoalesce(cfg.delay, () => ( 0));
72
+ this.ease = typeof cfg.easing === "function" ? cfg.easing : Easing[_nullishCoalesce(cfg.easing, () => ( "easeOutQuad"))];
73
+ }
74
+ get target() {
75
+ return this.to;
76
+ }
77
+ retarget(to) {
78
+ this.from = this.value;
79
+ this.to = to;
80
+ this.elapsed = 0;
81
+ }
82
+ tick(dtMs) {
83
+ this.elapsed += dtMs;
84
+ const active = this.elapsed - this.delay;
85
+ if (active <= 0) return;
86
+ const p = Math.min(active / this.duration, 1);
87
+ this.value = this.from + (this.to - this.from) * this.ease(p);
88
+ }
89
+ isDone() {
90
+ return this.elapsed - this.delay >= this.duration;
91
+ }
92
+ }, _class2);
93
+ var SpringDriver = class {
94
+
95
+ constructor(from, to, cfg) {
96
+ this.spring = new SpringPhysics(from);
97
+ if (cfg.stiffness !== void 0) this.spring.stiffness = cfg.stiffness;
98
+ if (cfg.damping !== void 0) this.spring.damping = cfg.damping;
99
+ if (cfg.mass !== void 0) this.spring.mass = cfg.mass;
100
+ this.spring.target = to;
101
+ }
102
+ get value() {
103
+ return this.spring.value;
104
+ }
105
+ get target() {
106
+ return this.spring.target;
107
+ }
108
+ retarget(to) {
109
+ this.spring.target = to;
110
+ }
111
+ tick(dtMs) {
112
+ this.spring.update(dtMs / 1e3);
113
+ }
114
+ isDone() {
115
+ return this.spring.isAtRest();
116
+ }
117
+ };
118
+
5
119
  // src/tree/Entity.ts
6
- var VectoJSEvent = (_class = class {
120
+ var VectoJSEvent = (_class3 = class {
7
121
  /** The event name. */
8
122
 
9
123
  /** The entity the event originated on. */
@@ -14,9 +128,9 @@ var VectoJSEvent = (_class = class {
14
128
 
15
129
  /** Whether the event bubbles past its target (capture always runs). */
16
130
 
17
- __init() {this.stopped = false}
18
- __init2() {this.stoppedImmediate = false}
19
- constructor(type, target, nativeEvent, bubbles = true) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
131
+ __init8() {this.stopped = false}
132
+ __init9() {this.stoppedImmediate = false}
133
+ constructor(type, target, nativeEvent, bubbles = true) {;_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);
20
134
  this.type = type;
21
135
  this.target = target;
22
136
  this.currentTarget = target;
@@ -68,11 +182,11 @@ var VectoJSEvent = (_class = class {
68
182
  get key() {
69
183
  return _optionalChain([this, 'access', _14 => _14.nativeEvent, 'optionalAccess', _15 => _15.key]);
70
184
  }
71
- }, _class);
72
- var Entity = (_class2 = class {
185
+ }, _class3);
186
+ var Entity = (_class4 = class {
73
187
 
74
- __init3() {this.children = []}
75
- __init4() {this.parent = null}
188
+ __init10() {this.children = []}
189
+ __init11() {this.parent = null}
76
190
  /**
77
191
  * Walk up the parent chain to find the scene this entity is currently attached to.
78
192
  */
@@ -80,14 +194,62 @@ var Entity = (_class2 = class {
80
194
  if (this._scene) return this._scene;
81
195
  return this.parent ? this.parent.scene : null;
82
196
  }
83
- __init5() {this.x = 0}
84
- __init6() {this.y = 0}
85
- __init7() {this.scaleX = 1}
86
- __init8() {this.scaleY = 1}
87
- __init9() {this.rotation = 0}
88
- __init10() {this.opacity = 1}
89
- __init11() {this.isDOMPortal = false}
90
- __init12() {this._interactive = false}
197
+ __init12() {this._x = 0}
198
+ __init13() {this._y = 0}
199
+ __init14() {this._scaleX = 1}
200
+ __init15() {this._scaleY = 1}
201
+ __init16() {this._rotation = 0}
202
+ __init17() {this._opacity = 1}
203
+ // Fast-path flag: false for the overwhelming majority of entities (incl. the
204
+ // Danmaku hot loop), so a bare `entity.x = v` is one boolean check + field write.
205
+ __init18() {this._hasTransitions = false}
206
+ __init19() {this._transitions = null}
207
+ __init20() {this._drivers = /* @__PURE__ */ new Map()}
208
+ __init21() {this._mounted = false}
209
+ get x() {
210
+ return this._x;
211
+ }
212
+ set x(v) {
213
+ if (this._hasTransitions) this._animateProp("x", v);
214
+ else this._x = v;
215
+ }
216
+ get y() {
217
+ return this._y;
218
+ }
219
+ set y(v) {
220
+ if (this._hasTransitions) this._animateProp("y", v);
221
+ else this._y = v;
222
+ }
223
+ get scaleX() {
224
+ return this._scaleX;
225
+ }
226
+ set scaleX(v) {
227
+ if (this._hasTransitions) this._animateProp("scaleX", v);
228
+ else this._scaleX = v;
229
+ }
230
+ get scaleY() {
231
+ return this._scaleY;
232
+ }
233
+ set scaleY(v) {
234
+ if (this._hasTransitions) this._animateProp("scaleY", v);
235
+ else this._scaleY = v;
236
+ }
237
+ get rotation() {
238
+ return this._rotation;
239
+ }
240
+ set rotation(v) {
241
+ if (this._hasTransitions) this._animateProp("rotation", v);
242
+ else this._rotation = v;
243
+ }
244
+ get opacity() {
245
+ return this._opacity;
246
+ }
247
+ set opacity(v) {
248
+ if (this._hasTransitions) this._animateProp("opacity", v);
249
+ else this._opacity = v;
250
+ }
251
+ __init22() {this.isDOMPortal = false}
252
+ __init23() {this._interactive = false}
91
253
  get interactive() {
92
254
  return this._interactive;
93
255
  }
@@ -101,10 +263,10 @@ var Entity = (_class2 = class {
101
263
  }
102
264
  }
103
265
  }
104
- __init13() {this.width = 0}
105
- __init14() {this.height = 0}
106
- __init15() {this.a11yOffsetX = 0}
107
- __init16() {this.a11yOffsetY = 0}
266
+ __init24() {this.width = 0}
267
+ __init25() {this.height = 0}
268
+ __init26() {this.a11yOffsetX = 0}
269
+ __init27() {this.a11yOffsetY = 0}
108
270
  /**
109
271
  * Opt in to a viewport-filling accessibility/automation shadow node even when
110
272
  * this entity has no intrinsic box (`width`/`height` of `0`). Use for
@@ -112,19 +274,19 @@ var Entity = (_class2 = class {
112
274
  * that need global pointer events. The node is mounted behind all other shadow
113
275
  * nodes, so on-top components stay clickable.
114
276
  */
115
- __init17() {this.a11yFullViewport = false}
277
+ __init28() {this.a11yFullViewport = false}
116
278
  /**
117
279
  * Clip this node's children to its local box (`[0,0]–[width,height]`) while
118
280
  * rendering. Combined with translating a content child, this is how
119
281
  * scroll/overflow containers (e.g. `ScrollView`) keep their content inside a
120
282
  * fixed viewport. Off by default (children render unclipped). Canvas2D only.
121
283
  */
122
- __init18() {this.clipChildren = false}
123
- __init19() {this.listeners = /* @__PURE__ */ new Map()}
284
+ __init29() {this.clipChildren = false}
285
+ __init30() {this.listeners = /* @__PURE__ */ new Map()}
124
286
  /** Capture-phase listeners (fired root→target before bubble). */
125
- __init20() {this.captureListeners = /* @__PURE__ */ new Map()}
126
- __init21() {this.animations = []}
127
- constructor(id) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);_class2.prototype.__init12.call(this);_class2.prototype.__init13.call(this);_class2.prototype.__init14.call(this);_class2.prototype.__init15.call(this);_class2.prototype.__init16.call(this);_class2.prototype.__init17.call(this);_class2.prototype.__init18.call(this);_class2.prototype.__init19.call(this);_class2.prototype.__init20.call(this);_class2.prototype.__init21.call(this);
287
+ __init31() {this.captureListeners = /* @__PURE__ */ new Map()}
288
+ __init32() {this.animations = []}
289
+ constructor(id) {;_class4.prototype.__init10.call(this);_class4.prototype.__init11.call(this);_class4.prototype.__init12.call(this);_class4.prototype.__init13.call(this);_class4.prototype.__init14.call(this);_class4.prototype.__init15.call(this);_class4.prototype.__init16.call(this);_class4.prototype.__init17.call(this);_class4.prototype.__init18.call(this);_class4.prototype.__init19.call(this);_class4.prototype.__init20.call(this);_class4.prototype.__init21.call(this);_class4.prototype.__init22.call(this);_class4.prototype.__init23.call(this);_class4.prototype.__init24.call(this);_class4.prototype.__init25.call(this);_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);_class4.prototype.__init28.call(this);_class4.prototype.__init29.call(this);_class4.prototype.__init30.call(this);_class4.prototype.__init31.call(this);_class4.prototype.__init32.call(this);
128
290
  this.id = id || `entity_${Math.random().toString(36).substring(2, 9)}`;
129
291
  }
130
292
  /**
@@ -140,9 +302,20 @@ var Entity = (_class2 = class {
140
302
  if (s) {
141
303
  s.a11yNeedsReorder = true;
142
304
  s.markDirty();
305
+ child._notifyMounted();
143
306
  }
144
307
  return this;
145
308
  }
309
+ /** Called once when this entity becomes attached to a live Scene. Override to react. */
310
+ onMounted() {
311
+ }
312
+ /** Fire onMounted for this node and its descendants, guarded against double-fire. */
313
+ _notifyMounted() {
314
+ if (this._mounted) return;
315
+ this._mounted = true;
316
+ this.onMounted();
317
+ for (const c of this.children) c._notifyMounted();
318
+ }
146
319
  /**
147
320
  * Remove a child entity from this node.
148
321
  *
@@ -195,6 +368,123 @@ var Entity = (_class2 = class {
195
368
  });
196
369
  return this;
197
370
  }
371
+ /** Write a driver-computed value to a backing field without re-triggering the setter. */
372
+ _applyAnimated(prop, v) {
373
+ switch (prop) {
374
+ case "x":
375
+ this._x = v;
376
+ break;
377
+ case "y":
378
+ this._y = v;
379
+ break;
380
+ case "scaleX":
381
+ this._scaleX = v;
382
+ break;
383
+ case "scaleY":
384
+ this._scaleY = v;
385
+ break;
386
+ case "rotation":
387
+ this._rotation = v;
388
+ break;
389
+ case "opacity":
390
+ this._opacity = v;
391
+ break;
392
+ }
393
+ }
394
+ _currentOf(prop) {
395
+ switch (prop) {
396
+ case "x":
397
+ return this._x;
398
+ case "y":
399
+ return this._y;
400
+ case "scaleX":
401
+ return this._scaleX;
402
+ case "scaleY":
403
+ return this._scaleY;
404
+ case "rotation":
405
+ return this._rotation;
406
+ case "opacity":
407
+ return this._opacity;
408
+ }
409
+ }
410
+ /**
411
+ * Write a value immediately, bypassing any configured transition. For subclasses
412
+ * that need to seed a starting state (e.g. the presence helper's enter `from`).
413
+ */
414
+ setImmediate(prop, v) {
415
+ this._drivers.delete(prop);
416
+ this._applyAnimated(prop, v);
417
+ }
418
+ _spawnDriver(prop, to, cfg) {
419
+ if (prop !== "opacity" && _optionalChain([this, 'access', _16 => _16.scene, 'optionalAccess', _17 => _17.prefersReducedMotion])) {
420
+ this._drivers.delete(prop);
421
+ this._applyAnimated(prop, to);
422
+ return;
423
+ }
424
+ const existing = this._drivers.get(prop);
425
+ if (existing) {
426
+ existing.retarget(to);
427
+ return;
428
+ }
429
+ const from = this._currentOf(prop);
430
+ const driver = isTweenConfig(cfg) ? new TweenDriver(from, to, cfg) : new SpringDriver(from, to, cfg === "spring" ? {} : cfg);
431
+ this._drivers.set(prop, driver);
432
+ _optionalChain([this, 'access', _18 => _18.scene, 'optionalAccess', _19 => _19.markDirty, 'call', _20 => _20()]);
433
+ }
434
+ /** Assignment path when a declarative transition is configured for `prop`. */
435
+ _animateProp(prop, to) {
436
+ const cfg = _optionalChain([this, 'access', _21 => _21._transitions, 'optionalAccess', _22 => _22.get, 'call', _23 => _23(prop)]);
437
+ if (!cfg) {
438
+ this._applyAnimated(prop, to);
439
+ return;
440
+ }
441
+ this._spawnDriver(prop, to, cfg);
442
+ }
443
+ /** Declare which properties animate, and how. Subsequent assignment animates them. */
444
+ setTransition(config) {
445
+ this._transitions ??= /* @__PURE__ */ new Map();
446
+ for (const [k, v] of Object.entries(config))
447
+ this._transitions.set(k, v);
448
+ this._hasTransitions = this._transitions.size > 0;
449
+ return this;
450
+ }
451
+ /** Imperative tween toward targets; resolves when all reach their end. */
452
+ animateTo(props, cfg) {
453
+ return this._driveTo(props, cfg);
454
+ }
455
+ /** Imperative spring toward targets; resolves when all reach rest. */
456
+ springTo(props, cfg = {}) {
457
+ return this._driveTo(props, cfg);
458
+ }
459
+ _driveTo(props, cfg) {
460
+ const entries = Object.entries(props);
461
+ return Promise.all(
462
+ entries.map(
463
+ (e) => new Promise((resolve) => {
464
+ this._spawnDriver(e[0], e[1], cfg);
465
+ const d = this._drivers.get(e[0]);
466
+ if (!d)
467
+ resolve();
468
+ else d.onDone = resolve;
469
+ })
470
+ )
471
+ ).then(() => void 0);
472
+ }
473
+ /** Advance active property drivers one frame. Call from update(). */
474
+ tickDrivers(dt) {
475
+ if (this._drivers.size === 0) return;
476
+ for (const [prop, driver] of this._drivers) {
477
+ driver.tick(dt);
478
+ if (driver.isDone()) {
479
+ this._applyAnimated(prop, driver.target);
480
+ _optionalChain([driver, 'access', _24 => _24.onDone, 'optionalCall', _25 => _25()]);
481
+ this._drivers.delete(prop);
482
+ } else {
483
+ this._applyAnimated(prop, driver.value);
484
+ }
485
+ }
486
+ _optionalChain([this, 'access', _26 => _26.scene, 'optionalAccess', _27 => _27.markDirty, 'call', _28 => _28()]);
487
+ }
198
488
  /**
199
489
  * Advance the entity's internal state for one frame.
200
490
  *
@@ -204,7 +494,8 @@ var Entity = (_class2 = class {
204
494
  * @param dt - Elapsed time since the last frame in milliseconds.
205
495
  * @param time - Absolute timestamp from `performance.now()`.
206
496
  */
207
- update(_dt, time) {
497
+ update(dt, time) {
498
+ this.tickDrivers(dt);
208
499
  if (this.animations.length > 0) {
209
500
  const anim = this.animations[0];
210
501
  if (anim.startTime === -1) {
@@ -241,7 +532,7 @@ var Entity = (_class2 = class {
241
532
  * @example entity.on('click', (e) => console.log('clicked', e));
242
533
  */
243
534
  on(event, callback, options) {
244
- const map = _optionalChain([options, 'optionalAccess', _16 => _16.capture]) ? this.captureListeners : this.listeners;
535
+ const map = _optionalChain([options, 'optionalAccess', _29 => _29.capture]) ? this.captureListeners : this.listeners;
245
536
  if (!map.has(event)) {
246
537
  map.set(event, []);
247
538
  }
@@ -257,7 +548,7 @@ var Entity = (_class2 = class {
257
548
  * @returns `this` for method chaining.
258
549
  */
259
550
  off(event, callback, options) {
260
- const handlers = (_optionalChain([options, 'optionalAccess', _17 => _17.capture]) ? this.captureListeners : this.listeners).get(event);
551
+ const handlers = (_optionalChain([options, 'optionalAccess', _30 => _30.capture]) ? this.captureListeners : this.listeners).get(event);
261
552
  if (handlers) {
262
553
  const idx = handlers.indexOf(callback);
263
554
  if (idx !== -1) handlers.splice(idx, 1);
@@ -438,29 +729,37 @@ var Entity = (_class2 = class {
438
729
  return null;
439
730
  }
440
731
  /**
441
- * Whether this entity still has a queued/running tween animation.
732
+ * Whether this entity still has a queued/running tween animation, or an
733
+ * active {@link setTransition}/{@link animateTo}/{@link springTo} property
734
+ * driver.
442
735
  *
443
- * Used by {@link Scene}'s `onDemand` render mode to keep redrawing while an
444
- * animation is in flight.
736
+ * Used by {@link Scene} to keep rendering continuously while an animation
737
+ * is in flight — both in `onDemand` render mode, and to hold off the
738
+ * `always`-mode idle auto-throttle. Without checking `_drivers` here, a
739
+ * property driver becomes invisible to that throttle: `markDirty()` called
740
+ * from inside `update()`/`tickDrivers()` is wiped by the loop's own
741
+ * `dirty = false` at the end of that same tick, so once the throttle
742
+ * engages an in-flight spring/tween only advances one animation-frame per
743
+ * external `markDirty()` trigger instead of every render frame.
445
744
  *
446
- * @returns `true` if at least one animation remains.
745
+ * @returns `true` if at least one animation or property driver remains.
447
746
  */
448
747
  hasPendingAnimations() {
449
- return this.animations.length > 0;
748
+ return this.animations.length > 0 || this._drivers.size > 0;
450
749
  }
451
- }, _class2);
750
+ }, _class4);
452
751
 
453
752
  // src/text/MSDFFont.ts
454
753
  function kernKey(a, b) {
455
754
  return a * 1114112 + b;
456
755
  }
457
- var MSDFFont = (_class3 = class _MSDFFont {
756
+ var MSDFFont = (_class5 = class _MSDFFont {
458
757
  static __initStatic() {this.idCounter = 0}
459
758
 
460
759
 
461
- __init22() {this.byCode = /* @__PURE__ */ new Map()}
462
- __init23() {this.kern = /* @__PURE__ */ new Map()}
463
- constructor(data) {;_class3.prototype.__init22.call(this);_class3.prototype.__init23.call(this);
760
+ __init33() {this.byCode = /* @__PURE__ */ new Map()}
761
+ __init34() {this.kern = /* @__PURE__ */ new Map()}
762
+ constructor(data) {;_class5.prototype.__init33.call(this);_class5.prototype.__init34.call(this);
464
763
  this.id = `font-${_MSDFFont.idCounter++}`;
465
764
  this.data = data;
466
765
  for (const g of data.glyphs) this.byCode.set(g.unicode, g);
@@ -545,10 +844,10 @@ var MSDFFont = (_class3 = class _MSDFFont {
545
844
  height: (line + 1) * lineHeight * fontSizePx
546
845
  };
547
846
  }
548
- }, _class3.__initStatic(), _class3);
847
+ }, _class5.__initStatic(), _class5);
549
848
 
550
849
  // src/text/MSDFTextEntity.ts
551
- var MSDFTextEntity = (_class4 = class extends Entity {
850
+ var MSDFTextEntity = (_class6 = class extends Entity {
552
851
 
553
852
 
554
853
 
@@ -556,13 +855,13 @@ var MSDFTextEntity = (_class4 = class extends Entity {
556
855
 
557
856
 
558
857
 
559
- __init24() {this.text = ""}
560
- __init25() {this.lastRenderedSeqId = 0}
561
- __init26() {this.rgbColorCache = /* @__PURE__ */ new Map()}
562
- __init27() {this.fontStringCache = []}
563
- __init28() {this.layoutResult = null}
858
+ __init35() {this.text = ""}
859
+ __init36() {this.lastRenderedSeqId = 0}
860
+ __init37() {this.rgbColorCache = /* @__PURE__ */ new Map()}
861
+ __init38() {this.fontStringCache = []}
862
+ __init39() {this.layoutResult = null}
564
863
  constructor(text, options) {
565
- super();_class4.prototype.__init24.call(this);_class4.prototype.__init25.call(this);_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);_class4.prototype.__init28.call(this);;
864
+ super();_class6.prototype.__init35.call(this);_class6.prototype.__init36.call(this);_class6.prototype.__init37.call(this);_class6.prototype.__init38.call(this);_class6.prototype.__init39.call(this);;
566
865
  this.font = options.font;
567
866
  this.texture = options.texture;
568
867
  this.fallbackFont = _nullishCoalesce(options.fallbackFont, () => ( "sans-serif"));
@@ -588,7 +887,7 @@ var MSDFTextEntity = (_class4 = class extends Entity {
588
887
  if (res.seqId < this.lastRenderedSeqId) return;
589
888
  this.lastRenderedSeqId = res.seqId;
590
889
  this.layoutResult = res;
591
- _optionalChain([this, 'access', _18 => _18.scene, 'optionalAccess', _19 => _19.markDirty, 'call', _20 => _20()]);
890
+ _optionalChain([this, 'access', _31 => _31.scene, 'optionalAccess', _32 => _32.markDirty, 'call', _33 => _33()]);
592
891
  }
593
892
  });
594
893
  }
@@ -683,23 +982,23 @@ var MSDFTextEntity = (_class4 = class extends Entity {
683
982
  _chunkRW6NC4RBjs.LayoutWorkerManager.getInstance().cancelLayout(this.id);
684
983
  super.destroy();
685
984
  }
686
- }, _class4);
985
+ }, _class6);
687
986
 
688
987
  // src/text/SVGEntity.ts
689
- var SVGEntity = (_class5 = class extends Entity {
690
- __init29() {this.svgSource = ""}
691
- __init30() {this.imageBitmap = null}
692
- __init31() {this.imageElement = null}
693
- __init32() {this.blobURL = null}
694
- __init33() {this.currentImg = null}
695
- __init34() {this.lodTimeout = null}
696
- __init35() {this.cachedDoc = null}
697
- __init36() {this.baseWidth = 100}
698
- __init37() {this.baseHeight = 100}
699
- __init38() {this.lastRasterizedScale = 1}
700
- __init39() {this.targetScale = 1}
988
+ var SVGEntity = (_class7 = class extends Entity {
989
+ __init40() {this.svgSource = ""}
990
+ __init41() {this.imageBitmap = null}
991
+ __init42() {this.imageElement = null}
992
+ __init43() {this.blobURL = null}
993
+ __init44() {this.currentImg = null}
994
+ __init45() {this.lodTimeout = null}
995
+ __init46() {this.cachedDoc = null}
996
+ __init47() {this.baseWidth = 100}
997
+ __init48() {this.baseHeight = 100}
998
+ __init49() {this.lastRasterizedScale = 1}
999
+ __init50() {this.targetScale = 1}
701
1000
  constructor(svgSource, id) {
702
- super(id);_class5.prototype.__init29.call(this);_class5.prototype.__init30.call(this);_class5.prototype.__init31.call(this);_class5.prototype.__init32.call(this);_class5.prototype.__init33.call(this);_class5.prototype.__init34.call(this);_class5.prototype.__init35.call(this);_class5.prototype.__init36.call(this);_class5.prototype.__init37.call(this);_class5.prototype.__init38.call(this);_class5.prototype.__init39.call(this);;
1001
+ super(id);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);;
703
1002
  this.setSVGSource(svgSource);
704
1003
  }
705
1004
  setSVGSource(svgSource) {
@@ -896,7 +1195,12 @@ var SVGEntity = (_class5 = class extends Entity {
896
1195
  this.cachedDoc = null;
897
1196
  super.destroy();
898
1197
  }
899
- }, _class5);
1198
+ }, _class7);
1199
+
1200
+
1201
+
1202
+
1203
+
900
1204
 
901
1205
 
902
1206
 
@@ -904,4 +1208,4 @@ var SVGEntity = (_class5 = class extends Entity {
904
1208
 
905
1209
 
906
1210
 
907
- exports.VectoJSEvent = VectoJSEvent; exports.Entity = Entity; exports.MSDFFont = MSDFFont; exports.MSDFTextEntity = MSDFTextEntity; exports.SVGEntity = SVGEntity;
1211
+ exports.SpringPhysics = SpringPhysics; exports.Easing = Easing; exports.isTweenConfig = isTweenConfig; exports.TweenDriver = TweenDriver; exports.SpringDriver = SpringDriver; exports.VectoJSEvent = VectoJSEvent; exports.Entity = Entity; exports.MSDFFont = MSDFFont; exports.MSDFTextEntity = MSDFTextEntity; exports.SVGEntity = SVGEntity;
@@ -0,0 +1,15 @@
1
+ import { Entity } from '../tree/Entity';
2
+ import { IRenderer } from '../renderer/IRenderer';
3
+ export declare class GridTextEntity extends Entity {
4
+ fontSize: number;
5
+ fillStyle: string;
6
+ grid: string[];
7
+ cols: number;
8
+ rows: number;
9
+ charWidth: number;
10
+ charHeight: number;
11
+ constructor(_atlas: any, fontSize?: number);
12
+ updateGrid(ascii: string[]): void;
13
+ isPointInside(_globalX: number, _globalY: number): boolean;
14
+ render(renderer: IRenderer): void;
15
+ }