@vectojs/core 1.17.1 → 1.19.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/dist/{chunk-DUYB4GX4.js → chunk-IA3KW4CG.js} +6 -6
- package/dist/{chunk-AQTO7OSU.mjs → chunk-XWBVBXFZ.mjs} +6 -6
- package/dist/index.js +257 -171
- package/dist/index.mjs +89 -3
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +42 -0
- package/dist/tree/Scene.d.ts +57 -1
- package/package.json +1 -1
|
@@ -237,7 +237,7 @@ var Entity = (_class2 = class {
|
|
|
237
237
|
const s = this.scene;
|
|
238
238
|
if (s) {
|
|
239
239
|
s.a11yNeedsReorder = true;
|
|
240
|
-
s.markDirty();
|
|
240
|
+
s.markDirty({ entity: this.id, reason: "a11y-reorder" });
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
}
|
|
@@ -301,7 +301,7 @@ var Entity = (_class2 = class {
|
|
|
301
301
|
if (s) {
|
|
302
302
|
s.a11yNeedsReorder = true;
|
|
303
303
|
_optionalChain([s, 'access', _40 => _40.markStructureChanged, 'optionalCall', _41 => _41()]);
|
|
304
|
-
s.markDirty();
|
|
304
|
+
s.markDirty({ entity: this.id, reason: "child-added" });
|
|
305
305
|
child._notifyMounted();
|
|
306
306
|
}
|
|
307
307
|
}
|
|
@@ -331,7 +331,7 @@ var Entity = (_class2 = class {
|
|
|
331
331
|
s.detachA11y(child);
|
|
332
332
|
s.a11yNeedsReorder = true;
|
|
333
333
|
_optionalChain([s, 'access', _42 => _42.markStructureChanged, 'optionalCall', _43 => _43()]);
|
|
334
|
-
s.markDirty();
|
|
334
|
+
s.markDirty({ entity: this.id, reason: "child-removed" });
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
return this;
|
|
@@ -385,7 +385,7 @@ var Entity = (_class2 = class {
|
|
|
385
385
|
startTime: -1,
|
|
386
386
|
startProps: {}
|
|
387
387
|
});
|
|
388
|
-
_optionalChain([this, 'access', _44 => _44.scene, 'optionalAccess', _45 => _45.markDirty, 'call', _46 => _46()]);
|
|
388
|
+
_optionalChain([this, 'access', _44 => _44.scene, 'optionalAccess', _45 => _45.markDirty, 'call', _46 => _46({ entity: this.id, reason: "animation-start" })]);
|
|
389
389
|
return this;
|
|
390
390
|
}
|
|
391
391
|
/** Write a driver-computed value to a backing field without re-triggering the setter. */
|
|
@@ -460,7 +460,7 @@ var Entity = (_class2 = class {
|
|
|
460
460
|
const from = this._currentOf(prop);
|
|
461
461
|
const driver = _animation.isTweenConfig.call(void 0, cfg) ? new (0, _animation.TweenDriver)(from, to, cfg) : new (0, _animation.SpringDriver)(from, to, cfg === "spring" ? {} : cfg);
|
|
462
462
|
(this._drivers ??= /* @__PURE__ */ new Map()).set(prop, driver);
|
|
463
|
-
_optionalChain([this, 'access', _65 => _65.scene, 'optionalAccess', _66 => _66.markDirty, 'call', _67 => _67()]);
|
|
463
|
+
_optionalChain([this, 'access', _65 => _65.scene, 'optionalAccess', _66 => _66.markDirty, 'call', _67 => _67({ entity: this.id, reason: "driver-added" })]);
|
|
464
464
|
_optionalChain([this, 'access', _68 => _68.scene, 'optionalAccess', _69 => _69._registerActiveDriverEntity, 'call', _70 => _70(this)]);
|
|
465
465
|
}
|
|
466
466
|
/** Assignment path when a declarative transition is configured for `prop`. */
|
|
@@ -516,7 +516,7 @@ var Entity = (_class2 = class {
|
|
|
516
516
|
this._applyAnimated(prop, driver.value);
|
|
517
517
|
}
|
|
518
518
|
}
|
|
519
|
-
_optionalChain([this, 'access', _77 => _77.scene, 'optionalAccess', _78 => _78.markDirty, 'call', _79 => _79()]);
|
|
519
|
+
_optionalChain([this, 'access', _77 => _77.scene, 'optionalAccess', _78 => _78.markDirty, 'call', _79 => _79({ entity: this.id, reason: "driver-tick" })]);
|
|
520
520
|
}
|
|
521
521
|
/**
|
|
522
522
|
* Internal: this entity's active-driver map (read-only view), or `null` if
|
|
@@ -235,7 +235,7 @@ var Entity = class {
|
|
|
235
235
|
const s = this.scene;
|
|
236
236
|
if (s) {
|
|
237
237
|
s.a11yNeedsReorder = true;
|
|
238
|
-
s.markDirty();
|
|
238
|
+
s.markDirty({ entity: this.id, reason: "a11y-reorder" });
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
}
|
|
@@ -299,7 +299,7 @@ var Entity = class {
|
|
|
299
299
|
if (s) {
|
|
300
300
|
s.a11yNeedsReorder = true;
|
|
301
301
|
s.markStructureChanged?.();
|
|
302
|
-
s.markDirty();
|
|
302
|
+
s.markDirty({ entity: this.id, reason: "child-added" });
|
|
303
303
|
child._notifyMounted();
|
|
304
304
|
}
|
|
305
305
|
}
|
|
@@ -329,7 +329,7 @@ var Entity = class {
|
|
|
329
329
|
s.detachA11y(child);
|
|
330
330
|
s.a11yNeedsReorder = true;
|
|
331
331
|
s.markStructureChanged?.();
|
|
332
|
-
s.markDirty();
|
|
332
|
+
s.markDirty({ entity: this.id, reason: "child-removed" });
|
|
333
333
|
}
|
|
334
334
|
}
|
|
335
335
|
return this;
|
|
@@ -383,7 +383,7 @@ var Entity = class {
|
|
|
383
383
|
startTime: -1,
|
|
384
384
|
startProps: {}
|
|
385
385
|
});
|
|
386
|
-
this.scene?.markDirty();
|
|
386
|
+
this.scene?.markDirty({ entity: this.id, reason: "animation-start" });
|
|
387
387
|
return this;
|
|
388
388
|
}
|
|
389
389
|
/** Write a driver-computed value to a backing field without re-triggering the setter. */
|
|
@@ -458,7 +458,7 @@ var Entity = class {
|
|
|
458
458
|
const from = this._currentOf(prop);
|
|
459
459
|
const driver = isTweenConfig(cfg) ? new TweenDriver(from, to, cfg) : new SpringDriver(from, to, cfg === "spring" ? {} : cfg);
|
|
460
460
|
(this._drivers ??= /* @__PURE__ */ new Map()).set(prop, driver);
|
|
461
|
-
this.scene?.markDirty();
|
|
461
|
+
this.scene?.markDirty({ entity: this.id, reason: "driver-added" });
|
|
462
462
|
this.scene?._registerActiveDriverEntity(this);
|
|
463
463
|
}
|
|
464
464
|
/** Assignment path when a declarative transition is configured for `prop`. */
|
|
@@ -514,7 +514,7 @@ var Entity = class {
|
|
|
514
514
|
this._applyAnimated(prop, driver.value);
|
|
515
515
|
}
|
|
516
516
|
}
|
|
517
|
-
this.scene?.markDirty();
|
|
517
|
+
this.scene?.markDirty({ entity: this.id, reason: "driver-tick" });
|
|
518
518
|
}
|
|
519
519
|
/**
|
|
520
520
|
* Internal: this entity's active-driver map (read-only view), or `null` if
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var _chunkL4SWVP2Hjs = require('./chunk-L4SWVP2H.js');
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
var _chunkIA3KW4CGjs = require('./chunk-IA3KW4CG.js');
|
|
18
18
|
|
|
19
19
|
// src/tree/Scene.ts
|
|
20
20
|
var _animation = require('@vectojs/animation'); _createStarExport(_animation);
|
|
@@ -29,7 +29,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
|
|
|
29
29
|
var PARTICLE_OFFSET_ORIGIN_Y = 5;
|
|
30
30
|
var PARTICLE_OFFSET_SIZE = 6;
|
|
31
31
|
var PARTICLE_OFFSET_LIFE = 7;
|
|
32
|
-
var ComputeParticleEntity = (_class = class extends
|
|
32
|
+
var ComputeParticleEntity = (_class = class extends _chunkIA3KW4CGjs.Entity {
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
@@ -1191,6 +1191,7 @@ async function loadCoreWasmRuntime(source) {
|
|
|
1191
1191
|
|
|
1192
1192
|
// src/tree/Scene.ts
|
|
1193
1193
|
var _text = require('@vectojs/text'); _createStarExport(_text);
|
|
1194
|
+
var RANGE_VALUE_ROLES = /* @__PURE__ */ new Set(["slider", "spinbutton", "progressbar", "scrollbar", "meter"]);
|
|
1194
1195
|
var INTERACTIVE_A11Y_ROLES = /* @__PURE__ */ new Set([
|
|
1195
1196
|
"button",
|
|
1196
1197
|
"switch",
|
|
@@ -1536,30 +1537,34 @@ var Scene = (_class7 = class _Scene {
|
|
|
1536
1537
|
* event-driven UIs where idle frames should cost ~0.
|
|
1537
1538
|
*/
|
|
1538
1539
|
__init29() {this.renderMode = "always"}
|
|
1539
|
-
|
|
1540
|
+
/** Cap on distinct recorded dirty reasons (see `recordDirtyReason`). */
|
|
1541
|
+
static __initStatic4() {this.MAX_DIRTY_REASONS = 200}
|
|
1542
|
+
__init30() {this._dirtyTracking = false}
|
|
1543
|
+
__init31() {this._dirtyReasons = /* @__PURE__ */ new Map()}
|
|
1544
|
+
__init32() {this.dirty = true}
|
|
1540
1545
|
/** Whether to throttle rendering to 2 FPS when the scene is static to save power. */
|
|
1541
|
-
|
|
1546
|
+
__init33() {this.autoThrottle = true}
|
|
1542
1547
|
// --- Frame telemetry (read via `frameStats`) ---------------------------
|
|
1543
1548
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
1544
|
-
|
|
1549
|
+
__init34() {this._lastFrameMs = 0}
|
|
1545
1550
|
/** Rolling exponential average of rendered-frame intervals, in ms. */
|
|
1546
|
-
|
|
1551
|
+
__init35() {this._avgFrameIntervalMs = 0}
|
|
1547
1552
|
/** dt (ms) handed to the last rendered frame. */
|
|
1548
|
-
|
|
1553
|
+
__init36() {this._lastDt = 0}
|
|
1549
1554
|
/** Count of frames actually rendered since the loop started. */
|
|
1550
|
-
|
|
1555
|
+
__init37() {this._renderedFrames = 0}
|
|
1551
1556
|
/** Count of rAF ticks skipped (idle / capped) since the loop started. */
|
|
1552
|
-
|
|
1557
|
+
__init38() {this._skippedFrames = 0}
|
|
1553
1558
|
/** `time` of the previous *rendered* frame, for interval measurement. */
|
|
1554
|
-
|
|
1559
|
+
__init39() {this._lastRenderTick = 0}
|
|
1555
1560
|
/**
|
|
1556
1561
|
* Frame-rate cap (power saving). `0` = uncapped (native refresh). When set,
|
|
1557
1562
|
* the loop renders at most `maxFPS` times per second; animations still run,
|
|
1558
1563
|
* just less often. See {@link SceneOptions.maxFPS}.
|
|
1559
1564
|
*/
|
|
1560
|
-
|
|
1565
|
+
__init40() {this.maxFPS = 60}
|
|
1561
1566
|
/** Whether the OS prefers-reduced-motion setting auto-caps the loop. */
|
|
1562
|
-
|
|
1567
|
+
__init41() {this.respectReducedMotion = true}
|
|
1563
1568
|
/**
|
|
1564
1569
|
* Reading direction for accessibility tab/traversal order (`'ltr'` default,
|
|
1565
1570
|
* `'rtl'`). Controls the inline sort within a visual row in
|
|
@@ -1575,15 +1580,15 @@ var Scene = (_class7 = class _Scene {
|
|
|
1575
1580
|
this.a11yNeedsReorder = true;
|
|
1576
1581
|
}
|
|
1577
1582
|
}
|
|
1578
|
-
|
|
1583
|
+
__init42() {this._readingDirection = "ltr"}
|
|
1579
1584
|
/** Cached media-query list; `.matches` is read live each frame. */
|
|
1580
|
-
|
|
1585
|
+
__init43() {this.reducedMotionQuery = null}
|
|
1581
1586
|
/** Cached `(forced-colors: active)` query (Windows High Contrast etc.). A
|
|
1582
1587
|
* canvas gets NO automatic forced-colors treatment from the browser (it's
|
|
1583
1588
|
* opaque pixels), so components must read {@link forcedColors} and repaint
|
|
1584
1589
|
* with system colors themselves; a change listener repaints idle scenes. */
|
|
1585
|
-
|
|
1586
|
-
|
|
1590
|
+
__init44() {this.forcedColorsQuery = null}
|
|
1591
|
+
__init45() {this.forcedColorsChangeHandler = null}
|
|
1587
1592
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
1588
1593
|
get prefersReducedMotion() {
|
|
1589
1594
|
return this.respectReducedMotion && !!_optionalChain([this, 'access', _21 => _21.reducedMotionQuery, 'optionalAccess', _22 => _22.matches]);
|
|
@@ -1603,82 +1608,82 @@ var Scene = (_class7 = class _Scene {
|
|
|
1603
1608
|
* Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
|
|
1604
1609
|
* frame. See {@link SceneOptions.a11ySyncInterval}.
|
|
1605
1610
|
*/
|
|
1606
|
-
|
|
1611
|
+
__init46() {this.a11ySyncInterval = 0}
|
|
1607
1612
|
/** Timestamp of the last a11y sync, for throttling. */
|
|
1608
|
-
|
|
1613
|
+
__init47() {this.lastA11ySync = -Infinity}
|
|
1609
1614
|
/** True if we skipped an a11y sync during animation and need to sync when at rest. */
|
|
1610
|
-
|
|
1615
|
+
__init48() {this.a11yPendingSyncAfterAnimation = false}
|
|
1611
1616
|
// A11y / Automation Layer. `null` in non-DOM (SSR/Node) environments — the
|
|
1612
1617
|
// whole projection degrades to a no-op so the engine's logic stays usable
|
|
1613
1618
|
// server-side (e.g. headless layout / vector export) without jsdom.
|
|
1614
1619
|
|
|
1615
|
-
|
|
1620
|
+
__init49() {this.a11yElements = /* @__PURE__ */ new Map()}
|
|
1616
1621
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
1617
|
-
|
|
1622
|
+
__init50() {this.contentElements = /* @__PURE__ */ new Map()}
|
|
1618
1623
|
/** Pending cold font-calibration frame per projected grid entity. */
|
|
1619
|
-
|
|
1624
|
+
__init51() {this.contentGridCalibrationFrames = /* @__PURE__ */ new Map()}
|
|
1620
1625
|
/** Detached, untransformed font probes used by the cold calibration pass. */
|
|
1621
|
-
|
|
1626
|
+
__init52() {this.contentGridCalibrationProbes = /* @__PURE__ */ new Map()}
|
|
1622
1627
|
/** Invalidates grid font calibration after browser font availability changes. */
|
|
1623
|
-
|
|
1628
|
+
__init53() {this.contentFontEpoch = 0}
|
|
1624
1629
|
/** Cached Canvas-to-client scale for the current font/viewport epoch. */
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1630
|
+
__init54() {this.contentMetricScaleEpoch = -1}
|
|
1631
|
+
__init55() {this.contentMetricScaleX = 1}
|
|
1632
|
+
__init56() {this.contentProjectionEnabled = true}
|
|
1628
1633
|
// Virtualization margin (px) for content projection; `undefined` → one
|
|
1629
1634
|
// viewport height, resolved at sync time. `Infinity` = materialize everything.
|
|
1630
|
-
|
|
1635
|
+
__init57() {this.contentProjectionMargin = void 0}
|
|
1631
1636
|
/**
|
|
1632
1637
|
* True while a text-selection drag that started on a projection's blank
|
|
1633
1638
|
* region (no text node under the press) is being driven manually — the
|
|
1634
1639
|
* browser has no native anchor for it, so mousemove extends the Selection
|
|
1635
1640
|
* from the position we resolved ourselves.
|
|
1636
1641
|
*/
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1642
|
+
__init58() {this.blankRegionSelectionDrag = false}
|
|
1643
|
+
__init59() {this.contentSelectionAnchor = null}
|
|
1644
|
+
__init60() {this.contentSelectionEndListener = null}
|
|
1640
1645
|
// Animation/interactive flags collected during the render walk (tree-walk
|
|
1641
1646
|
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
1642
1647
|
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
1643
|
-
|
|
1644
|
-
|
|
1648
|
+
__init61() {this.frameHadAnimation = true}
|
|
1649
|
+
__init62() {this.frameHadInteractive = true}
|
|
1645
1650
|
|
|
1646
1651
|
/** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
|
|
1647
1652
|
* (window moved between monitors, browser zoom) so the canvas backing store
|
|
1648
1653
|
* can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
|
|
1649
1654
|
* A resolution media query only fires when leaving its exact value, so the
|
|
1650
1655
|
* handler re-arms a fresh query for the new DPR each time. */
|
|
1651
|
-
|
|
1656
|
+
__init63() {this.dprMediaQuery = null}
|
|
1652
1657
|
/** For embedded (`disableWindowResize`) scenes: observes the canvas element so
|
|
1653
1658
|
* a CSS/layout-driven size change re-runs `resize()`. A window `resize`
|
|
1654
1659
|
* listener never fires for these (the window isn't what changed), so without
|
|
1655
1660
|
* this an embedded canvas stayed at its initial size forever. */
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1661
|
+
__init64() {this.canvasResizeObserver = null}
|
|
1662
|
+
__init65() {this.dprChangeHandler = null}
|
|
1663
|
+
__init66() {this.focusedA11yElement = null}
|
|
1659
1664
|
/** Last geometry `syncOverlayGeometry` wrote, so an unchanged frame can skip the
|
|
1660
1665
|
* style writes entirely. Reset to `null` to force the next sync (a new overlay
|
|
1661
1666
|
* layer was created and has never been positioned). */
|
|
1662
|
-
|
|
1667
|
+
__init67() {this._overlayGeometry = null}
|
|
1663
1668
|
/** Shadow elements the pointer is currently inside. Lets a removal that happens
|
|
1664
1669
|
* mid-hover synthesize the `pointerleave` the browser never sends for a
|
|
1665
1670
|
* detached element, so the entity doesn't keep its hover state. */
|
|
1666
|
-
|
|
1671
|
+
__init68() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
|
|
1667
1672
|
/** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
|
|
1668
1673
|
* pruned (virtualization/streaming/removal) while it holds focus, we move
|
|
1669
1674
|
* focus here instead of letting the browser drop it to <body> — keeping the
|
|
1670
1675
|
* screen-reader virtual cursor inside the scene's a11y region. */
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1676
|
+
__init69() {this.focusSentinel = null}
|
|
1677
|
+
__init70() {this.caretBlinkTimer = null}
|
|
1678
|
+
__init71() {this.a11yNeedsReorder = true}
|
|
1679
|
+
__init72() {this.portalRoot = null}
|
|
1680
|
+
__init73() {this.fullViewportElements = []}
|
|
1681
|
+
__init74() {this.normalElements = []}
|
|
1682
|
+
__init75() {this.activeIds = /* @__PURE__ */ new Set()}
|
|
1683
|
+
__init76() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
|
|
1684
|
+
__init77() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
|
|
1685
|
+
__init78() {this.portalEntities = /* @__PURE__ */ new Map()}
|
|
1686
|
+
__init79() {this.renderOrderCounter = 0}
|
|
1682
1687
|
/**
|
|
1683
1688
|
* Monotonic render-frame counter, bumped once per authoritative `render()`
|
|
1684
1689
|
* pass. Entities stamp their per-frame world-matrix cache with this value and
|
|
@@ -1687,7 +1692,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1687
1692
|
* back to the ancestor walk. Public for the same reason `Entity._getTrig`/
|
|
1688
1693
|
* `_setWorldCache` are: it is a cross-class render-internal contract.
|
|
1689
1694
|
*/
|
|
1690
|
-
|
|
1695
|
+
__init80() {this.currentFrame = 0}
|
|
1691
1696
|
// ── WASM transform backend (invisible accelerator) ──────────────────────────
|
|
1692
1697
|
// When `_transformBackend === 'wasm'`, the main render walk sources each
|
|
1693
1698
|
// entity's world matrix from an SoA store composed by `_wasm` (see
|
|
@@ -1695,24 +1700,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
1695
1700
|
// fallback and the default: a null backend, a non-main renderer, or any entity
|
|
1696
1701
|
// absent from the store all fall back to the JS composition, so WASM can only
|
|
1697
1702
|
// ever change *how fast* a world matrix is produced, never *what* it is.
|
|
1698
|
-
|
|
1699
|
-
|
|
1703
|
+
__init81() {this._wasm = null}
|
|
1704
|
+
__init82() {this._transformBackend = "js"}
|
|
1700
1705
|
// Resident store state (Stage 3). The store layout — slot assignment + sibling
|
|
1701
1706
|
// runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
|
|
1702
1707
|
// structure changes (add/remove/reparent bump `_structureVersion`). Between
|
|
1703
1708
|
// rebuilds the per-frame cost is: gather each entity's transform into the
|
|
1704
1709
|
// resident wasm input view + run the kernel — no reallocation, no readback.
|
|
1705
|
-
|
|
1706
|
-
|
|
1710
|
+
__init83() {this._treeStore = null}
|
|
1711
|
+
__init84() {this._slotEntity = []}
|
|
1707
1712
|
// store slot -> entity (also validates slots)
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1713
|
+
__init85() {this._wasmInputs = null}
|
|
1714
|
+
__init86() {this._wasmWorld = null}
|
|
1715
|
+
__init87() {this._structureVersion = 0}
|
|
1716
|
+
__init88() {this._storeStructureVersion = -1}
|
|
1712
1717
|
// Cached list of ComputeParticleEntity instances in the tree, keyed by the
|
|
1713
1718
|
// structure version it was gathered at. Rebuilt only on a topology change.
|
|
1714
|
-
|
|
1715
|
-
|
|
1719
|
+
__init89() {this._computeEntities = []}
|
|
1720
|
+
__init90() {this._computeEntitiesVersion = -1}
|
|
1716
1721
|
/** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
|
|
1717
1722
|
* it. Called by `Entity.add`/`remove` (topology changes only). */
|
|
1718
1723
|
markStructureChanged() {
|
|
@@ -1794,7 +1799,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1794
1799
|
* cached globally; the instance is per-Scene, which is the isolation that
|
|
1795
1800
|
* actually matters.
|
|
1796
1801
|
*/
|
|
1797
|
-
|
|
1802
|
+
__init91() {this._wasmRuntime = null}
|
|
1798
1803
|
/**
|
|
1799
1804
|
* Load (or reuse) this Scene's shared WASM runtime.
|
|
1800
1805
|
*
|
|
@@ -1822,30 +1827,30 @@ var Scene = (_class7 = class _Scene {
|
|
|
1822
1827
|
get wasmRuntime() {
|
|
1823
1828
|
return this._wasmRuntime;
|
|
1824
1829
|
}
|
|
1825
|
-
|
|
1830
|
+
__init92() {this._hitWasm = null}
|
|
1826
1831
|
// Cache key: which frame + structure version the grid was last (successfully,
|
|
1827
1832
|
// non-overflowing) built for. findEntityAt is called ad-hoc (pointer
|
|
1828
1833
|
// hover/click), not every frame, so the grid is refreshed lazily on demand
|
|
1829
1834
|
// rather than proactively every render() — unlike the transform store, which
|
|
1830
1835
|
// every frame's draw depends on.
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1836
|
+
__init93() {this._hitGridFrame = -1}
|
|
1837
|
+
__init94() {this._hitGridOk = false}
|
|
1838
|
+
__init95() {this._hitSlotEntity = []}
|
|
1839
|
+
__init96() {this._hitBoundless = []}
|
|
1835
1840
|
/** Reused buffer for the fused gather, so a pointer query allocates nothing. */
|
|
1836
|
-
|
|
1841
|
+
__init97() {this._hitGatherBuffer = null}
|
|
1837
1842
|
/**
|
|
1838
1843
|
* Whether the last grid build sourced its AABBs from the WASM transform store
|
|
1839
1844
|
* rather than recomputing them in JS. Diagnostic only — both paths must
|
|
1840
1845
|
* produce the same entity for a given point.
|
|
1841
1846
|
*/
|
|
1842
|
-
|
|
1847
|
+
__init98() {this._hitFusedGather = false}
|
|
1843
1848
|
/**
|
|
1844
1849
|
* Whether `compute_aabbs` has run against the current frame's world matrices.
|
|
1845
1850
|
* The AABB pass is only meaningful after a `compose_*`, so the fused gather
|
|
1846
1851
|
* must not read the views before then.
|
|
1847
1852
|
*/
|
|
1848
|
-
|
|
1853
|
+
__init99() {this._wasmAabbsFresh = false}
|
|
1849
1854
|
/** Did the last hit-grid build use the fused (WASM-store) gather? */
|
|
1850
1855
|
get hitGatherPath() {
|
|
1851
1856
|
return this._hitFusedGather ? "fused" : "js";
|
|
@@ -1959,25 +1964,25 @@ var Scene = (_class7 = class _Scene {
|
|
|
1959
1964
|
// EasingFn (which cannot cross into WASM) all fall through to it — WASM can
|
|
1960
1965
|
// only ever change *how* a driver is advanced, never *what* value it lands
|
|
1961
1966
|
// on.
|
|
1962
|
-
|
|
1967
|
+
__init100() {this._animWasm = null}
|
|
1963
1968
|
// Entities with at least one active driver, added by Entity._spawnDriver.
|
|
1964
1969
|
// Self-pruning: _tickBatchedDrivers drops an entry the first time it visits
|
|
1965
1970
|
// an entity whose drivers have since all completed or been removed. This is
|
|
1966
1971
|
// what lets the batch pass find its candidates in O(active drivers), not
|
|
1967
1972
|
// O(tree size) — the exact mistake G3's first integrated benchmark made.
|
|
1968
|
-
|
|
1973
|
+
__init101() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
|
|
1969
1974
|
// Reused across frames instead of allocating a fresh array + N {entity,prop,
|
|
1970
1975
|
// driver} objects every call — the integrated benchmark
|
|
1971
1976
|
// (benchmarks/anim-wasm-scene) found that allocation churn was the
|
|
1972
1977
|
// dominant integrated cost, not the wasm kernel itself. Parallel arrays,
|
|
1973
1978
|
// truncated to the live count after each use so a stale tail slot never
|
|
1974
1979
|
// pins a no-longer-active entity/driver in memory.
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1980
|
+
__init102() {this._springEntities = []}
|
|
1981
|
+
__init103() {this._springProps = []}
|
|
1982
|
+
__init104() {this._springDrivers = []}
|
|
1983
|
+
__init105() {this._tweenEntities = []}
|
|
1984
|
+
__init106() {this._tweenProps = []}
|
|
1985
|
+
__init107() {this._tweenDrivers = []}
|
|
1981
1986
|
/**
|
|
1982
1987
|
* Minimum number of batchable (spring, or named-easing tween) active drivers
|
|
1983
1988
|
* before a frame engages the WASM batch path at all; below it, every driver
|
|
@@ -2049,7 +2054,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2049
2054
|
* Setting {@link animDriverGateCount} overwrites all three, so existing code
|
|
2050
2055
|
* that tuned the single knob keeps working unchanged.
|
|
2051
2056
|
*/
|
|
2052
|
-
|
|
2057
|
+
__init108() {this._animBatchedLastFrame = false}
|
|
2053
2058
|
/**
|
|
2054
2059
|
* Whether the WASM batch path actually ran on the most recent frame.
|
|
2055
2060
|
*
|
|
@@ -2061,7 +2066,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2061
2066
|
get animBatchedLastFrame() {
|
|
2062
2067
|
return this._animBatchedLastFrame;
|
|
2063
2068
|
}
|
|
2064
|
-
|
|
2069
|
+
__init109() {this.animGate = {
|
|
2065
2070
|
spring: 128,
|
|
2066
2071
|
tween: 256,
|
|
2067
2072
|
mixed: 128
|
|
@@ -2099,7 +2104,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2099
2104
|
// (benchmarks/particle-wasm). f32 (matches the WGSL shader), bit-identical to
|
|
2100
2105
|
// a JS f32 reference oracle; updateCPU (f64) stays the permanent fallback when
|
|
2101
2106
|
// no backend is installed or a scene runs on WebGPU.
|
|
2102
|
-
|
|
2107
|
+
__init110() {this._particleWasm = null}
|
|
2103
2108
|
/** Which backend runs the CPU particle simulation. Reflects only whether a
|
|
2104
2109
|
* backend is installed (the WebGPU compute path, when active, is used first
|
|
2105
2110
|
* regardless). */
|
|
@@ -2349,46 +2354,46 @@ var Scene = (_class7 = class _Scene {
|
|
|
2349
2354
|
* sync, so retaining the order prevents a newly opened overlay from spending
|
|
2350
2355
|
* its first frame below previously projected controls.
|
|
2351
2356
|
*/
|
|
2352
|
-
|
|
2357
|
+
__init111() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
|
|
2353
2358
|
// Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2359
|
+
__init112() {this.pointRenderer = null}
|
|
2360
|
+
__init113() {this.glCanvas = null}
|
|
2361
|
+
__init114() {this.glContextLostHandler = null}
|
|
2362
|
+
__init115() {this.glContextRestoredHandler = null}
|
|
2358
2363
|
|
|
2359
2364
|
|
|
2360
2365
|
|
|
2361
|
-
|
|
2366
|
+
__init116() {this.disableWindowResize = false}
|
|
2362
2367
|
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
2363
2368
|
|
|
2364
2369
|
// WebGPU properties
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
+
__init117() {this.destroyed = false}
|
|
2371
|
+
__init118() {this.device = null}
|
|
2372
|
+
__init119() {this.deviceLost = false}
|
|
2373
|
+
__init120() {this.particleBackend = "auto"}
|
|
2374
|
+
__init121() {this._webgpuDisabled = false}
|
|
2370
2375
|
get webgpuDisabled() {
|
|
2371
2376
|
return this._webgpuDisabled || this.particleBackend === "cpu";
|
|
2372
2377
|
}
|
|
2373
2378
|
set webgpuDisabled(value) {
|
|
2374
2379
|
this._webgpuDisabled = value;
|
|
2375
2380
|
}
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
+
__init122() {this.recoveryTimerId = null}
|
|
2382
|
+
__init123() {this.manager = null}
|
|
2383
|
+
__init124() {this.initializingWebGPU = false}
|
|
2384
|
+
__init125() {this.gpuCanvas = null}
|
|
2385
|
+
__init126() {this.gpuContext = null}
|
|
2381
2386
|
/** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
+
__init127() {this.gpuHasContent = false}
|
|
2388
|
+
__init128() {this.mouseX = -9999}
|
|
2389
|
+
__init129() {this.mouseY = -9999}
|
|
2390
|
+
__init130() {this.pointerMoveListener = null}
|
|
2391
|
+
__init131() {this.pointerLeaveListener = null}
|
|
2387
2392
|
/** Element the pointer listeners are bound to (parent container if present,
|
|
2388
2393
|
* else the canvas). Stored so `destroy()` detaches from the same element. */
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2394
|
+
__init132() {this.pointerEventTarget = null}
|
|
2395
|
+
__init133() {this.hasWarnedZeroSize = false}
|
|
2396
|
+
__init134() {this.fontLoadHandler = null}
|
|
2392
2397
|
// ── Dev-mode warning infrastructure ──────────────────────────────
|
|
2393
2398
|
//
|
|
2394
2399
|
// Enable with `Scene.devMode = true` or by setting `globalThis.__DEV__`.
|
|
@@ -2397,7 +2402,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2397
2402
|
// Checks run once every ~120 frames (~2s at 60fps) to keep overhead
|
|
2398
2403
|
// negligible even when dev mode is on.
|
|
2399
2404
|
/** Toggle development-mode runtime warnings globally. */
|
|
2400
|
-
static
|
|
2405
|
+
static __initStatic5() {this.devMode = false}
|
|
2401
2406
|
static _devModeDetected() {
|
|
2402
2407
|
if (_Scene.devMode) return true;
|
|
2403
2408
|
const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
@@ -2406,7 +2411,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2406
2411
|
return false;
|
|
2407
2412
|
}
|
|
2408
2413
|
|
|
2409
|
-
|
|
2414
|
+
__init135() {this._devFrameCount = 0}
|
|
2410
2415
|
_devWarn(message) {
|
|
2411
2416
|
if (!this._devActive) return;
|
|
2412
2417
|
console.warn(`[vectojs/dev] ${message}`);
|
|
@@ -2450,7 +2455,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2450
2455
|
};
|
|
2451
2456
|
walkProjections(this.root);
|
|
2452
2457
|
}
|
|
2453
|
-
constructor(canvas, options = {}) {;_class7.prototype.__init25.call(this);_class7.prototype.__init26.call(this);_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_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);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);
|
|
2458
|
+
constructor(canvas, options = {}) {;_class7.prototype.__init25.call(this);_class7.prototype.__init26.call(this);_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_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);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);
|
|
2454
2459
|
this.canvas = canvas;
|
|
2455
2460
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
2456
2461
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
@@ -2481,7 +2486,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2481
2486
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
2482
2487
|
_optionalChain([this, 'access', _45 => _45.forcedColorsQuery, 'access', _46 => _46.addEventListener, 'optionalCall', _47 => _47("change", this.forcedColorsChangeHandler)]);
|
|
2483
2488
|
}
|
|
2484
|
-
this.root = new class RootEntity extends
|
|
2489
|
+
this.root = new class RootEntity extends _chunkIA3KW4CGjs.Entity {
|
|
2485
2490
|
isPointInside() {
|
|
2486
2491
|
return false;
|
|
2487
2492
|
}
|
|
@@ -2490,7 +2495,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2490
2495
|
}
|
|
2491
2496
|
}("root");
|
|
2492
2497
|
this.root._scene = this;
|
|
2493
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
2498
|
+
this.overlayRoot = new class OverlayRoot extends _chunkIA3KW4CGjs.Entity {
|
|
2494
2499
|
isPointInside() {
|
|
2495
2500
|
return false;
|
|
2496
2501
|
}
|
|
@@ -2856,7 +2861,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2856
2861
|
}
|
|
2857
2862
|
if (this.hoveredA11yElements.has(el)) {
|
|
2858
2863
|
this.hoveredA11yElements.delete(el);
|
|
2859
|
-
node.dispatchEvent(new (0,
|
|
2864
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("pointerleave", node, void 0, false));
|
|
2860
2865
|
}
|
|
2861
2866
|
this.preserveFocusOnRemoval(el);
|
|
2862
2867
|
el.remove();
|
|
@@ -3156,8 +3161,65 @@ var Scene = (_class7 = class _Scene {
|
|
|
3156
3161
|
* Only meaningful in `onDemand` {@link renderMode}: call it after mutating
|
|
3157
3162
|
* entity state outside of {@link Entity.animate} so the change is rendered.
|
|
3158
3163
|
*/
|
|
3159
|
-
markDirty() {
|
|
3164
|
+
markDirty(source) {
|
|
3160
3165
|
this.dirty = true;
|
|
3166
|
+
if (this._dirtyTracking && source) this.recordDirtyReason(source);
|
|
3167
|
+
}
|
|
3168
|
+
/**
|
|
3169
|
+
* Record who marked the scene dirty and why.
|
|
3170
|
+
*
|
|
3171
|
+
* Kept separate from {@link markDirty} so the hot path is not a function call
|
|
3172
|
+
* with a branch — V8 inlines the one-field version reliably.
|
|
3173
|
+
*/
|
|
3174
|
+
recordDirtyReason(source) {
|
|
3175
|
+
const key = `${_nullishCoalesce(source.entity, () => ( "scene"))}:${source.reason}${source.property ? `.${source.property}` : ""}`;
|
|
3176
|
+
const existing = this._dirtyReasons.get(key);
|
|
3177
|
+
if (existing) {
|
|
3178
|
+
existing.count++;
|
|
3179
|
+
existing.lastFrame = this.currentFrame;
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
if (this._dirtyReasons.size >= _Scene.MAX_DIRTY_REASONS) {
|
|
3183
|
+
const oldest = this._dirtyReasons.keys().next().value;
|
|
3184
|
+
if (oldest !== void 0) this._dirtyReasons.delete(oldest);
|
|
3185
|
+
}
|
|
3186
|
+
this._dirtyReasons.set(key, {
|
|
3187
|
+
entity: source.entity,
|
|
3188
|
+
reason: source.reason,
|
|
3189
|
+
property: source.property,
|
|
3190
|
+
count: 1,
|
|
3191
|
+
firstFrame: this.currentFrame,
|
|
3192
|
+
lastFrame: this.currentFrame
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3195
|
+
/**
|
|
3196
|
+
* Start or stop recording dirty attributions.
|
|
3197
|
+
*
|
|
3198
|
+
* Off by default. `renderMode: 'onDemand'` silently degrades to always-on when
|
|
3199
|
+
* something marks the scene dirty every frame, and until now there was no way
|
|
3200
|
+
* to find out what — `dirty === true` said nothing about the cause. Enable
|
|
3201
|
+
* this, run the scene, then read {@link dirtyReasons}.
|
|
3202
|
+
*/
|
|
3203
|
+
setDirtyTracking(enabled) {
|
|
3204
|
+
this._dirtyTracking = enabled;
|
|
3205
|
+
if (!enabled) this._dirtyReasons.clear();
|
|
3206
|
+
}
|
|
3207
|
+
/** Whether dirty attribution is currently being recorded. */
|
|
3208
|
+
get dirtyTracking() {
|
|
3209
|
+
return this._dirtyTracking;
|
|
3210
|
+
}
|
|
3211
|
+
/**
|
|
3212
|
+
* Recorded dirty attributions, most frequent first.
|
|
3213
|
+
*
|
|
3214
|
+
* `count` is what matters for the `onDemand` diagnosis: a reason appearing once
|
|
3215
|
+
* per frame over hundreds of frames is the thing keeping the scene awake.
|
|
3216
|
+
*/
|
|
3217
|
+
get dirtyReasons() {
|
|
3218
|
+
return [...this._dirtyReasons.values()].sort((a, b) => b.count - a.count);
|
|
3219
|
+
}
|
|
3220
|
+
/** Drop recorded attributions, keeping tracking enabled. */
|
|
3221
|
+
clearDirtyReasons() {
|
|
3222
|
+
this._dirtyReasons.clear();
|
|
3161
3223
|
}
|
|
3162
3224
|
/**
|
|
3163
3225
|
* Live frame telemetry for profilers and devtools overlays. All timings are
|
|
@@ -3266,20 +3328,20 @@ var Scene = (_class7 = class _Scene {
|
|
|
3266
3328
|
el.style.background = "transparent";
|
|
3267
3329
|
}
|
|
3268
3330
|
el.addEventListener("click", (e) => {
|
|
3269
|
-
node.dispatchEvent(new (0,
|
|
3331
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("click", node, e));
|
|
3270
3332
|
});
|
|
3271
3333
|
el.addEventListener("dblclick", (e) => {
|
|
3272
|
-
node.dispatchEvent(new (0,
|
|
3334
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("dblclick", node, e));
|
|
3273
3335
|
});
|
|
3274
3336
|
el.addEventListener("mouseenter", (e) => {
|
|
3275
3337
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
3276
3338
|
this.hoveredA11yElements.add(el);
|
|
3277
|
-
node.dispatchEvent(new (0,
|
|
3339
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("hover", node, e, false));
|
|
3278
3340
|
});
|
|
3279
3341
|
el.addEventListener("mouseleave", (e) => {
|
|
3280
3342
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
3281
3343
|
this.hoveredA11yElements.delete(el);
|
|
3282
|
-
node.dispatchEvent(new (0,
|
|
3344
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("pointerleave", node, e, false));
|
|
3283
3345
|
});
|
|
3284
3346
|
const capEl = el;
|
|
3285
3347
|
const releasePointer = (event) => {
|
|
@@ -3295,32 +3357,32 @@ var Scene = (_class7 = class _Scene {
|
|
|
3295
3357
|
};
|
|
3296
3358
|
el.addEventListener("pointerdown", (e) => {
|
|
3297
3359
|
if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
|
|
3298
|
-
node.dispatchEvent(new (0,
|
|
3360
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("pointerdown", node, e));
|
|
3299
3361
|
});
|
|
3300
3362
|
el.addEventListener("pointerup", (e) => {
|
|
3301
3363
|
releasePointer(e);
|
|
3302
|
-
node.dispatchEvent(new (0,
|
|
3364
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("pointerup", node, e));
|
|
3303
3365
|
});
|
|
3304
3366
|
el.addEventListener("pointercancel", (e) => {
|
|
3305
3367
|
releasePointer(e);
|
|
3306
|
-
node.dispatchEvent(new (0,
|
|
3368
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("pointercancel", node, e));
|
|
3307
3369
|
});
|
|
3308
3370
|
el.addEventListener(
|
|
3309
3371
|
"pointermove",
|
|
3310
|
-
(e) => node.dispatchEvent(new (0,
|
|
3372
|
+
(e) => node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("pointermove", node, e))
|
|
3311
3373
|
);
|
|
3312
3374
|
el.addEventListener(
|
|
3313
3375
|
"wheel",
|
|
3314
3376
|
(e) => {
|
|
3315
|
-
node.dispatchEvent(new (0,
|
|
3377
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("wheel", node, e));
|
|
3316
3378
|
},
|
|
3317
3379
|
{ passive: false }
|
|
3318
3380
|
);
|
|
3319
3381
|
el.addEventListener("keydown", (e) => {
|
|
3320
|
-
node.dispatchEvent(new (0,
|
|
3382
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("keydown", node, e));
|
|
3321
3383
|
});
|
|
3322
3384
|
el.addEventListener("keyup", (e) => {
|
|
3323
|
-
node.dispatchEvent(new (0,
|
|
3385
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("keyup", node, e));
|
|
3324
3386
|
});
|
|
3325
3387
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
3326
3388
|
const input = el;
|
|
@@ -3386,7 +3448,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3386
3448
|
el.addEventListener("keydown", (e) => {
|
|
3387
3449
|
if (e.key === "Enter" || e.key === " ") {
|
|
3388
3450
|
e.preventDefault();
|
|
3389
|
-
node.dispatchEvent(new (0,
|
|
3451
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("click", node, e));
|
|
3390
3452
|
}
|
|
3391
3453
|
});
|
|
3392
3454
|
}
|
|
@@ -3498,6 +3560,28 @@ var Scene = (_class7 = class _Scene {
|
|
|
3498
3560
|
"aria-level",
|
|
3499
3561
|
attrs.level === void 0 ? void 0 : String(attrs.level)
|
|
3500
3562
|
);
|
|
3563
|
+
this.syncOptionalAttribute(
|
|
3564
|
+
el,
|
|
3565
|
+
"aria-posinset",
|
|
3566
|
+
attrs.posInSet === void 0 ? void 0 : String(attrs.posInSet)
|
|
3567
|
+
);
|
|
3568
|
+
this.syncOptionalAttribute(
|
|
3569
|
+
el,
|
|
3570
|
+
"aria-setsize",
|
|
3571
|
+
attrs.setSize === void 0 ? void 0 : String(attrs.setSize)
|
|
3572
|
+
);
|
|
3573
|
+
this.syncOptionalAttribute(
|
|
3574
|
+
el,
|
|
3575
|
+
"aria-rowcount",
|
|
3576
|
+
attrs.rowCount === void 0 ? void 0 : String(attrs.rowCount)
|
|
3577
|
+
);
|
|
3578
|
+
this.syncOptionalAttribute(
|
|
3579
|
+
el,
|
|
3580
|
+
"aria-rowindex",
|
|
3581
|
+
attrs.rowIndex === void 0 ? void 0 : String(attrs.rowIndex)
|
|
3582
|
+
);
|
|
3583
|
+
this.syncOptionalAttribute(el, "aria-valuetext", attrs.valueText);
|
|
3584
|
+
this.syncOptionalAttribute(el, "aria-orientation", attrs.orientation);
|
|
3501
3585
|
if (attrs.value !== void 0) {
|
|
3502
3586
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
3503
3587
|
if (el.value !== attrs.value) {
|
|
@@ -3507,8 +3591,10 @@ var Scene = (_class7 = class _Scene {
|
|
|
3507
3591
|
el._lastSyncedValue = attrs.value;
|
|
3508
3592
|
}
|
|
3509
3593
|
}
|
|
3510
|
-
} else {
|
|
3594
|
+
} else if (RANGE_VALUE_ROLES.has(_nullishCoalesce(attrs.role, () => ( "")))) {
|
|
3511
3595
|
this.syncOptionalAttribute(el, "aria-valuenow", attrs.value);
|
|
3596
|
+
} else {
|
|
3597
|
+
this.syncOptionalAttribute(el, "aria-valuenow", void 0);
|
|
3512
3598
|
}
|
|
3513
3599
|
} else if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
|
|
3514
3600
|
this.syncOptionalAttribute(el, "aria-valuenow", void 0);
|
|
@@ -3644,7 +3730,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3644
3730
|
el.addEventListener(
|
|
3645
3731
|
"wheel",
|
|
3646
3732
|
(e2) => {
|
|
3647
|
-
node.dispatchEvent(new (0,
|
|
3733
|
+
node.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)("wheel", node, e2));
|
|
3648
3734
|
},
|
|
3649
3735
|
{ passive: false }
|
|
3650
3736
|
);
|
|
@@ -4447,7 +4533,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4447
4533
|
let walkHadAnimation = false;
|
|
4448
4534
|
let walkHadInteractive = false;
|
|
4449
4535
|
const runUpdate = (node) => {
|
|
4450
|
-
const overridesUpdate = node.update !==
|
|
4536
|
+
const overridesUpdate = node.update !== _chunkIA3KW4CGjs.Entity.prototype.update;
|
|
4451
4537
|
let pending = node.hasPendingAnimations();
|
|
4452
4538
|
if (pending || overridesUpdate) {
|
|
4453
4539
|
node.update(dt, time);
|
|
@@ -4456,7 +4542,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4456
4542
|
if (pending) walkHadAnimation = true;
|
|
4457
4543
|
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
4458
4544
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
4459
|
-
if (overridesUpdate && node.hasPendingAnimations ===
|
|
4545
|
+
if (overridesUpdate && node.hasPendingAnimations === _chunkIA3KW4CGjs.Entity.prototype.hasPendingAnimations) {
|
|
4460
4546
|
this._devWarn(
|
|
4461
4547
|
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to drop the animation to ~2fps. Override hasPendingAnimations() to return true while motion is in flight.`
|
|
4462
4548
|
);
|
|
@@ -4888,7 +4974,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4888
4974
|
}
|
|
4889
4975
|
return true;
|
|
4890
4976
|
}
|
|
4891
|
-
}, _class7.__initStatic(), _class7.__initStatic2(), _class7.__initStatic3(), _class7.__initStatic4(), _class7);
|
|
4977
|
+
}, _class7.__initStatic(), _class7.__initStatic2(), _class7.__initStatic3(), _class7.__initStatic4(), _class7.__initStatic5(), _class7);
|
|
4892
4978
|
function intersectBounds(a, b) {
|
|
4893
4979
|
const x = Math.max(a.x, b.x);
|
|
4894
4980
|
const y = Math.max(a.y, b.y);
|
|
@@ -4915,20 +5001,20 @@ function defaultMeasurer() {
|
|
|
4915
5001
|
if (sharedMeasurer === void 0) sharedMeasurer = _layout.createCanvasMeasurer.call(void 0, "sans-serif");
|
|
4916
5002
|
return sharedMeasurer;
|
|
4917
5003
|
}
|
|
4918
|
-
var TextEntity = (_class8 = class extends
|
|
5004
|
+
var TextEntity = (_class8 = class extends _chunkIA3KW4CGjs.Entity {
|
|
4919
5005
|
|
|
4920
5006
|
|
|
4921
5007
|
|
|
4922
5008
|
|
|
4923
|
-
|
|
5009
|
+
__init136() {this.nodes = []}
|
|
4924
5010
|
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
5011
|
+
__init137() {this.fillStyle = "#94a3b8"}
|
|
5012
|
+
__init138() {this.strokeStyle = null}
|
|
5013
|
+
__init139() {this.hoveredFillStyle = "#ffffff"}
|
|
5014
|
+
__init140() {this.lineWidth = 1}
|
|
5015
|
+
__init141() {this.isHovered = false}
|
|
4930
5016
|
constructor(text, atlas, maxWidth, fontSize = 24) {
|
|
4931
|
-
super();_class8.prototype.
|
|
5017
|
+
super();_class8.prototype.__init136.call(this);_class8.prototype.__init137.call(this);_class8.prototype.__init138.call(this);_class8.prototype.__init139.call(this);_class8.prototype.__init140.call(this);_class8.prototype.__init141.call(this);;
|
|
4932
5018
|
this.text = text;
|
|
4933
5019
|
this.atlas = atlas;
|
|
4934
5020
|
this.fontSize = fontSize;
|
|
@@ -5041,17 +5127,17 @@ var TextEntity = (_class8 = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5041
5127
|
}, _class8);
|
|
5042
5128
|
|
|
5043
5129
|
// src/components/GridTextEntity.ts
|
|
5044
|
-
var GridTextEntity = (_class9 = class extends
|
|
5130
|
+
var GridTextEntity = (_class9 = class extends _chunkIA3KW4CGjs.Entity {
|
|
5045
5131
|
|
|
5046
|
-
|
|
5047
|
-
|
|
5132
|
+
__init142() {this.fillStyle = "#ffffff"}
|
|
5133
|
+
__init143() {this.grid = []}
|
|
5048
5134
|
// Array of rows
|
|
5049
|
-
|
|
5050
|
-
|
|
5135
|
+
__init144() {this.cols = 0}
|
|
5136
|
+
__init145() {this.rows = 0}
|
|
5051
5137
|
|
|
5052
5138
|
|
|
5053
5139
|
constructor(_atlas, fontSize = 10) {
|
|
5054
|
-
super();_class9.prototype.
|
|
5140
|
+
super();_class9.prototype.__init142.call(this);_class9.prototype.__init143.call(this);_class9.prototype.__init144.call(this);_class9.prototype.__init145.call(this);;
|
|
5055
5141
|
this.fontSize = fontSize;
|
|
5056
5142
|
this.charWidth = fontSize * 1;
|
|
5057
5143
|
this.charHeight = fontSize * 1.1;
|
|
@@ -5135,7 +5221,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
5135
5221
|
const ey = py - cy;
|
|
5136
5222
|
return ex * ex + ey * ey;
|
|
5137
5223
|
}
|
|
5138
|
-
var SplineEntity = (_class10 = class extends
|
|
5224
|
+
var SplineEntity = (_class10 = class extends _chunkIA3KW4CGjs.Entity {
|
|
5139
5225
|
|
|
5140
5226
|
|
|
5141
5227
|
|
|
@@ -5143,23 +5229,23 @@ var SplineEntity = (_class10 = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5143
5229
|
|
|
5144
5230
|
|
|
5145
5231
|
|
|
5146
|
-
|
|
5147
|
-
|
|
5232
|
+
__init146() {this.offscreen = null}
|
|
5233
|
+
__init147() {this.baked = false}
|
|
5148
5234
|
/** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
|
|
5149
|
-
|
|
5150
|
-
|
|
5235
|
+
__init148() {this.bakedWidth = 0}
|
|
5236
|
+
__init149() {this.bakedHeight = 0}
|
|
5151
5237
|
/** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
|
|
5152
5238
|
|
|
5153
5239
|
/** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
|
|
5154
|
-
|
|
5240
|
+
__init150() {this.polylines = null}
|
|
5155
5241
|
/**
|
|
5156
5242
|
* When `true`, the renderer draws a rounded-rect outline of the entity's
|
|
5157
5243
|
* local bounds after painting the curves. Useful for drag feedback and
|
|
5158
5244
|
* debugging hit areas. Defaults to `false`.
|
|
5159
5245
|
*/
|
|
5160
|
-
|
|
5246
|
+
__init151() {this.showBounds = false}
|
|
5161
5247
|
constructor(doc, opts = {}) {
|
|
5162
|
-
super();_class10.prototype.
|
|
5248
|
+
super();_class10.prototype.__init146.call(this);_class10.prototype.__init147.call(this);_class10.prototype.__init148.call(this);_class10.prototype.__init149.call(this);_class10.prototype.__init150.call(this);_class10.prototype.__init151.call(this);;
|
|
5163
5249
|
this.doc = doc;
|
|
5164
5250
|
this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
|
|
5165
5251
|
this.cache = _nullishCoalesce(opts.cache, () => ( true));
|
|
@@ -5410,7 +5496,7 @@ async function loadSpline(url) {
|
|
|
5410
5496
|
}
|
|
5411
5497
|
|
|
5412
5498
|
// src/components/Rect.ts
|
|
5413
|
-
var Rect = class extends
|
|
5499
|
+
var Rect = class extends _chunkIA3KW4CGjs.Entity {
|
|
5414
5500
|
|
|
5415
5501
|
|
|
5416
5502
|
|
|
@@ -5459,7 +5545,7 @@ var Rect = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5459
5545
|
};
|
|
5460
5546
|
|
|
5461
5547
|
// src/components/Circle.ts
|
|
5462
|
-
var Circle = class extends
|
|
5548
|
+
var Circle = class extends _chunkIA3KW4CGjs.Entity {
|
|
5463
5549
|
|
|
5464
5550
|
|
|
5465
5551
|
|
|
@@ -5519,7 +5605,7 @@ var Circle = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5519
5605
|
};
|
|
5520
5606
|
|
|
5521
5607
|
// src/components/Group.ts
|
|
5522
|
-
var Group = class extends
|
|
5608
|
+
var Group = class extends _chunkIA3KW4CGjs.Entity {
|
|
5523
5609
|
constructor(...children) {
|
|
5524
5610
|
super();
|
|
5525
5611
|
if (children.length > 0) this.add(...children);
|
|
@@ -5538,21 +5624,21 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
5538
5624
|
|
|
5539
5625
|
|
|
5540
5626
|
// src/tree/DOMPortalEntity.ts
|
|
5541
|
-
var DOMPortalEntity = (_class11 = class extends
|
|
5627
|
+
var DOMPortalEntity = (_class11 = class extends _chunkIA3KW4CGjs.Entity {
|
|
5542
5628
|
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5629
|
+
__init152() {this.isDOMPortal = true}
|
|
5630
|
+
__init153() {this.domListeners = []}
|
|
5631
|
+
__init154() {this.resizeObserver = null}
|
|
5632
|
+
__init155() {this.domBound = false}
|
|
5633
|
+
__init156() {this.cachedWidth = 100}
|
|
5634
|
+
__init157() {this.cachedHeight = 100}
|
|
5635
|
+
__init158() {this.lastWidth = ""}
|
|
5636
|
+
__init159() {this.lastHeight = ""}
|
|
5637
|
+
__init160() {this.lastTransform = ""}
|
|
5638
|
+
__init161() {this.lastZIndex = ""}
|
|
5639
|
+
__init162() {this.lastOpacity = ""}
|
|
5554
5640
|
constructor(domElement, width, height, id) {
|
|
5555
|
-
super(id);_class11.prototype.
|
|
5641
|
+
super(id);_class11.prototype.__init152.call(this);_class11.prototype.__init153.call(this);_class11.prototype.__init154.call(this);_class11.prototype.__init155.call(this);_class11.prototype.__init156.call(this);_class11.prototype.__init157.call(this);_class11.prototype.__init158.call(this);_class11.prototype.__init159.call(this);_class11.prototype.__init160.call(this);_class11.prototype.__init161.call(this);_class11.prototype.__init162.call(this);;
|
|
5556
5642
|
this.domElement = domElement;
|
|
5557
5643
|
this.width = _nullishCoalesce(width, () => ( 0));
|
|
5558
5644
|
this.height = _nullishCoalesce(height, () => ( 0));
|
|
@@ -5594,7 +5680,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5594
5680
|
];
|
|
5595
5681
|
for (const type of events) {
|
|
5596
5682
|
const handler = (e) => {
|
|
5597
|
-
this.dispatchEvent(new (0,
|
|
5683
|
+
this.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)(type, this, e));
|
|
5598
5684
|
};
|
|
5599
5685
|
this.domElement.addEventListener(type, handler);
|
|
5600
5686
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -5605,7 +5691,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5605
5691
|
];
|
|
5606
5692
|
for (const { native, vecto } of hoverEvents) {
|
|
5607
5693
|
const handler = (e) => {
|
|
5608
|
-
this.dispatchEvent(new (0,
|
|
5694
|
+
this.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)(vecto, this, e, false));
|
|
5609
5695
|
};
|
|
5610
5696
|
this.domElement.addEventListener(native, handler);
|
|
5611
5697
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -5613,7 +5699,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkDUYB4GX4js.Entity {
|
|
|
5613
5699
|
const focusEvents = ["focus", "blur"];
|
|
5614
5700
|
for (const type of focusEvents) {
|
|
5615
5701
|
const handler = (e) => {
|
|
5616
|
-
this.dispatchEvent(new (0,
|
|
5702
|
+
this.dispatchEvent(new (0, _chunkIA3KW4CGjs.VectoJSEvent)(type, this, e, true));
|
|
5617
5703
|
};
|
|
5618
5704
|
this.domElement.addEventListener(type, handler, true);
|
|
5619
5705
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -5700,4 +5786,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkL4SWVP2Hjs.WebGPUParticleSystemM
|
|
|
5700
5786
|
|
|
5701
5787
|
|
|
5702
5788
|
|
|
5703
|
-
exports.CanvasRenderer = _chunkL4SWVP2Hjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity =
|
|
5789
|
+
exports.CanvasRenderer = _chunkL4SWVP2Hjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkIA3KW4CGjs.Entity; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkIA3KW4CGjs.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.Rect = Rect; exports.SVGEntity = _chunkIA3KW4CGjs.SVGEntity; exports.SVGRenderer = _chunkL4SWVP2Hjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkL4SWVP2Hjs.TextRasterCache; exports.VectoJSEvent = _chunkIA3KW4CGjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkL4SWVP2Hjs.WebGPUParticleSystemManager; exports.createWebGLPointRenderer = _chunkL4SWVP2Hjs.createWebGLPointRenderer; exports.isSafeUrl = _chunkL4SWVP2Hjs.isSafeUrl; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkL4SWVP2Hjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkL4SWVP2Hjs.sanitizeUrl;
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
MSDFTextEntity,
|
|
14
14
|
SVGEntity,
|
|
15
15
|
VectoJSEvent
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-XWBVBXFZ.mjs";
|
|
17
17
|
|
|
18
18
|
// src/tree/Scene.ts
|
|
19
19
|
import { SpringDriver, TweenDriver } from "@vectojs/animation";
|
|
@@ -1190,6 +1190,7 @@ async function loadCoreWasmRuntime(source) {
|
|
|
1190
1190
|
|
|
1191
1191
|
// src/tree/Scene.ts
|
|
1192
1192
|
import { clearCssLineBoxMetrics, cssLineBoxBaseline } from "@vectojs/text";
|
|
1193
|
+
var RANGE_VALUE_ROLES = /* @__PURE__ */ new Set(["slider", "spinbutton", "progressbar", "scrollbar", "meter"]);
|
|
1193
1194
|
var INTERACTIVE_A11Y_ROLES = /* @__PURE__ */ new Set([
|
|
1194
1195
|
"button",
|
|
1195
1196
|
"switch",
|
|
@@ -1535,6 +1536,10 @@ var Scene = class _Scene {
|
|
|
1535
1536
|
* event-driven UIs where idle frames should cost ~0.
|
|
1536
1537
|
*/
|
|
1537
1538
|
renderMode = "always";
|
|
1539
|
+
/** Cap on distinct recorded dirty reasons (see `recordDirtyReason`). */
|
|
1540
|
+
static MAX_DIRTY_REASONS = 200;
|
|
1541
|
+
_dirtyTracking = false;
|
|
1542
|
+
_dirtyReasons = /* @__PURE__ */ new Map();
|
|
1538
1543
|
dirty = true;
|
|
1539
1544
|
/** Whether to throttle rendering to 2 FPS when the scene is static to save power. */
|
|
1540
1545
|
autoThrottle = true;
|
|
@@ -3155,8 +3160,65 @@ var Scene = class _Scene {
|
|
|
3155
3160
|
* Only meaningful in `onDemand` {@link renderMode}: call it after mutating
|
|
3156
3161
|
* entity state outside of {@link Entity.animate} so the change is rendered.
|
|
3157
3162
|
*/
|
|
3158
|
-
markDirty() {
|
|
3163
|
+
markDirty(source) {
|
|
3159
3164
|
this.dirty = true;
|
|
3165
|
+
if (this._dirtyTracking && source) this.recordDirtyReason(source);
|
|
3166
|
+
}
|
|
3167
|
+
/**
|
|
3168
|
+
* Record who marked the scene dirty and why.
|
|
3169
|
+
*
|
|
3170
|
+
* Kept separate from {@link markDirty} so the hot path is not a function call
|
|
3171
|
+
* with a branch — V8 inlines the one-field version reliably.
|
|
3172
|
+
*/
|
|
3173
|
+
recordDirtyReason(source) {
|
|
3174
|
+
const key = `${source.entity ?? "scene"}:${source.reason}${source.property ? `.${source.property}` : ""}`;
|
|
3175
|
+
const existing = this._dirtyReasons.get(key);
|
|
3176
|
+
if (existing) {
|
|
3177
|
+
existing.count++;
|
|
3178
|
+
existing.lastFrame = this.currentFrame;
|
|
3179
|
+
return;
|
|
3180
|
+
}
|
|
3181
|
+
if (this._dirtyReasons.size >= _Scene.MAX_DIRTY_REASONS) {
|
|
3182
|
+
const oldest = this._dirtyReasons.keys().next().value;
|
|
3183
|
+
if (oldest !== void 0) this._dirtyReasons.delete(oldest);
|
|
3184
|
+
}
|
|
3185
|
+
this._dirtyReasons.set(key, {
|
|
3186
|
+
entity: source.entity,
|
|
3187
|
+
reason: source.reason,
|
|
3188
|
+
property: source.property,
|
|
3189
|
+
count: 1,
|
|
3190
|
+
firstFrame: this.currentFrame,
|
|
3191
|
+
lastFrame: this.currentFrame
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
/**
|
|
3195
|
+
* Start or stop recording dirty attributions.
|
|
3196
|
+
*
|
|
3197
|
+
* Off by default. `renderMode: 'onDemand'` silently degrades to always-on when
|
|
3198
|
+
* something marks the scene dirty every frame, and until now there was no way
|
|
3199
|
+
* to find out what — `dirty === true` said nothing about the cause. Enable
|
|
3200
|
+
* this, run the scene, then read {@link dirtyReasons}.
|
|
3201
|
+
*/
|
|
3202
|
+
setDirtyTracking(enabled) {
|
|
3203
|
+
this._dirtyTracking = enabled;
|
|
3204
|
+
if (!enabled) this._dirtyReasons.clear();
|
|
3205
|
+
}
|
|
3206
|
+
/** Whether dirty attribution is currently being recorded. */
|
|
3207
|
+
get dirtyTracking() {
|
|
3208
|
+
return this._dirtyTracking;
|
|
3209
|
+
}
|
|
3210
|
+
/**
|
|
3211
|
+
* Recorded dirty attributions, most frequent first.
|
|
3212
|
+
*
|
|
3213
|
+
* `count` is what matters for the `onDemand` diagnosis: a reason appearing once
|
|
3214
|
+
* per frame over hundreds of frames is the thing keeping the scene awake.
|
|
3215
|
+
*/
|
|
3216
|
+
get dirtyReasons() {
|
|
3217
|
+
return [...this._dirtyReasons.values()].sort((a, b) => b.count - a.count);
|
|
3218
|
+
}
|
|
3219
|
+
/** Drop recorded attributions, keeping tracking enabled. */
|
|
3220
|
+
clearDirtyReasons() {
|
|
3221
|
+
this._dirtyReasons.clear();
|
|
3160
3222
|
}
|
|
3161
3223
|
/**
|
|
3162
3224
|
* Live frame telemetry for profilers and devtools overlays. All timings are
|
|
@@ -3497,6 +3559,28 @@ var Scene = class _Scene {
|
|
|
3497
3559
|
"aria-level",
|
|
3498
3560
|
attrs.level === void 0 ? void 0 : String(attrs.level)
|
|
3499
3561
|
);
|
|
3562
|
+
this.syncOptionalAttribute(
|
|
3563
|
+
el,
|
|
3564
|
+
"aria-posinset",
|
|
3565
|
+
attrs.posInSet === void 0 ? void 0 : String(attrs.posInSet)
|
|
3566
|
+
);
|
|
3567
|
+
this.syncOptionalAttribute(
|
|
3568
|
+
el,
|
|
3569
|
+
"aria-setsize",
|
|
3570
|
+
attrs.setSize === void 0 ? void 0 : String(attrs.setSize)
|
|
3571
|
+
);
|
|
3572
|
+
this.syncOptionalAttribute(
|
|
3573
|
+
el,
|
|
3574
|
+
"aria-rowcount",
|
|
3575
|
+
attrs.rowCount === void 0 ? void 0 : String(attrs.rowCount)
|
|
3576
|
+
);
|
|
3577
|
+
this.syncOptionalAttribute(
|
|
3578
|
+
el,
|
|
3579
|
+
"aria-rowindex",
|
|
3580
|
+
attrs.rowIndex === void 0 ? void 0 : String(attrs.rowIndex)
|
|
3581
|
+
);
|
|
3582
|
+
this.syncOptionalAttribute(el, "aria-valuetext", attrs.valueText);
|
|
3583
|
+
this.syncOptionalAttribute(el, "aria-orientation", attrs.orientation);
|
|
3500
3584
|
if (attrs.value !== void 0) {
|
|
3501
3585
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
3502
3586
|
if (el.value !== attrs.value) {
|
|
@@ -3506,8 +3590,10 @@ var Scene = class _Scene {
|
|
|
3506
3590
|
el._lastSyncedValue = attrs.value;
|
|
3507
3591
|
}
|
|
3508
3592
|
}
|
|
3509
|
-
} else {
|
|
3593
|
+
} else if (RANGE_VALUE_ROLES.has(attrs.role ?? "")) {
|
|
3510
3594
|
this.syncOptionalAttribute(el, "aria-valuenow", attrs.value);
|
|
3595
|
+
} else {
|
|
3596
|
+
this.syncOptionalAttribute(el, "aria-valuenow", void 0);
|
|
3511
3597
|
}
|
|
3512
3598
|
} else if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
|
|
3513
3599
|
this.syncOptionalAttribute(el, "aria-valuenow", void 0);
|
package/dist/text.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkIA3KW4CGjs = require('./chunk-IA3KW4CG.js');
|
|
6
6
|
|
|
7
7
|
// src/text/index.ts
|
|
8
8
|
var _text = require('@vectojs/text'); _createStarExport(_text);
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
exports.MSDFTextEntity =
|
|
12
|
+
exports.MSDFTextEntity = _chunkIA3KW4CGjs.MSDFTextEntity; exports.SVGEntity = _chunkIA3KW4CGjs.SVGEntity;
|
package/dist/text.mjs
CHANGED
package/dist/tree/Entity.d.ts
CHANGED
|
@@ -221,6 +221,48 @@ export interface A11yAttributes {
|
|
|
221
221
|
/** `aria-invalid`: the field's current value fails validation. */
|
|
222
222
|
invalid?: boolean;
|
|
223
223
|
/** `aria-level`: hierarchical level (headings, tree items, etc.). */
|
|
224
|
+
/**
|
|
225
|
+
* Position within a set, 1-based — projected as `aria-posinset`.
|
|
226
|
+
*
|
|
227
|
+
* Required whenever the DOM contains only part of the set, which is exactly
|
|
228
|
+
* what virtualization produces: a list rendering rows 40-52 of 10,000 otherwise
|
|
229
|
+
* announces "item 3 of 12", because that is all the accessibility tree can see.
|
|
230
|
+
* Pair with {@link setSize}.
|
|
231
|
+
*/
|
|
232
|
+
posInSet?: number;
|
|
233
|
+
/**
|
|
234
|
+
* Total size of the set the element belongs to — projected as `aria-setsize`.
|
|
235
|
+
*
|
|
236
|
+
* `-1` is the ARIA-defined value for "unknown but non-empty", appropriate for a
|
|
237
|
+
* lazily loaded set whose total is not yet known.
|
|
238
|
+
*/
|
|
239
|
+
setSize?: number;
|
|
240
|
+
/**
|
|
241
|
+
* Total row count of a grid whose DOM holds only the visible rows — projected
|
|
242
|
+
* as `aria-rowcount`. Same rationale as {@link posInSet}: a virtualized table
|
|
243
|
+
* needs to state the real total, not the rendered one.
|
|
244
|
+
*/
|
|
245
|
+
rowCount?: number;
|
|
246
|
+
/** 1-based row index within the full grid — projected as `aria-rowindex`. */
|
|
247
|
+
rowIndex?: number;
|
|
248
|
+
/**
|
|
249
|
+
* Human-readable form of a range widget's current value — projected as
|
|
250
|
+
* `aria-valuetext`.
|
|
251
|
+
*
|
|
252
|
+
* A bare `aria-valuenow` is announced as a number out of context: "40" rather
|
|
253
|
+
* than "40 percent" or "Medium". Only set this when the number alone is
|
|
254
|
+
* genuinely ambiguous; a redundant valuetext makes announcements longer for no
|
|
255
|
+
* gain.
|
|
256
|
+
*/
|
|
257
|
+
valueText?: string;
|
|
258
|
+
/**
|
|
259
|
+
* Orientation of a composite widget — projected as `aria-orientation`.
|
|
260
|
+
*
|
|
261
|
+
* Worth setting when it differs from the role's default (`slider` and
|
|
262
|
+
* `separator` default horizontal; `listbox`, `menu`, `tree` default vertical),
|
|
263
|
+
* because it tells assistive technology which arrow keys to expect.
|
|
264
|
+
*/
|
|
265
|
+
orientation?: 'horizontal' | 'vertical';
|
|
224
266
|
level?: number;
|
|
225
267
|
/** `aria-modal`: marks a `role="dialog"` as modal so assistive tech confines
|
|
226
268
|
* reading to it. Set on a modal dialog's shell. */
|
package/dist/tree/Scene.d.ts
CHANGED
|
@@ -17,6 +17,31 @@ import { type CoreWasmRuntime } from '../wasm/runtime';
|
|
|
17
17
|
import { type HitModuleSource, type HitTestBackend } from '../wasm/hit-backend';
|
|
18
18
|
import { type AnimModuleSource, type AnimBackend } from '../wasm/anim-backend';
|
|
19
19
|
import { type ParticleModuleSource, type ParticleBackend } from '../wasm/particle-backend';
|
|
20
|
+
/**
|
|
21
|
+
* Who marked the scene dirty, and why.
|
|
22
|
+
*
|
|
23
|
+
* Every field is optional except `reason` so a call site can be as specific as it
|
|
24
|
+
* cheaply can — an entity id costs nothing to pass, a property name is often
|
|
25
|
+
* already in scope.
|
|
26
|
+
*/
|
|
27
|
+
export interface DirtySource {
|
|
28
|
+
/** Entity id responsible, when one is. Omitted for scene-level invalidation. */
|
|
29
|
+
entity?: string;
|
|
30
|
+
/** Short, stable category — e.g. `'text-changed'`, `'animation'`, `'resize'`. */
|
|
31
|
+
reason: string;
|
|
32
|
+
/** Property that changed, when the reason alone is ambiguous. */
|
|
33
|
+
property?: string;
|
|
34
|
+
}
|
|
35
|
+
/** An aggregated dirty attribution. */
|
|
36
|
+
export interface DirtyReasonEntry {
|
|
37
|
+
entity?: string;
|
|
38
|
+
reason: string;
|
|
39
|
+
property?: string;
|
|
40
|
+
/** How many times this exact attribution was recorded. */
|
|
41
|
+
count: number;
|
|
42
|
+
firstFrame: number;
|
|
43
|
+
lastFrame: number;
|
|
44
|
+
}
|
|
20
45
|
/**
|
|
21
46
|
* Options for {@link Scene}.
|
|
22
47
|
*/
|
|
@@ -203,6 +228,10 @@ export declare class Scene {
|
|
|
203
228
|
* event-driven UIs where idle frames should cost ~0.
|
|
204
229
|
*/
|
|
205
230
|
renderMode: 'always' | 'onDemand';
|
|
231
|
+
/** Cap on distinct recorded dirty reasons (see `recordDirtyReason`). */
|
|
232
|
+
private static readonly MAX_DIRTY_REASONS;
|
|
233
|
+
private _dirtyTracking;
|
|
234
|
+
private _dirtyReasons;
|
|
206
235
|
private dirty;
|
|
207
236
|
/** Whether to throttle rendering to 2 FPS when the scene is static to save power. */
|
|
208
237
|
autoThrottle: boolean;
|
|
@@ -845,7 +874,34 @@ export declare class Scene {
|
|
|
845
874
|
* Only meaningful in `onDemand` {@link renderMode}: call it after mutating
|
|
846
875
|
* entity state outside of {@link Entity.animate} so the change is rendered.
|
|
847
876
|
*/
|
|
848
|
-
markDirty(): void;
|
|
877
|
+
markDirty(source?: DirtySource): void;
|
|
878
|
+
/**
|
|
879
|
+
* Record who marked the scene dirty and why.
|
|
880
|
+
*
|
|
881
|
+
* Kept separate from {@link markDirty} so the hot path is not a function call
|
|
882
|
+
* with a branch — V8 inlines the one-field version reliably.
|
|
883
|
+
*/
|
|
884
|
+
private recordDirtyReason;
|
|
885
|
+
/**
|
|
886
|
+
* Start or stop recording dirty attributions.
|
|
887
|
+
*
|
|
888
|
+
* Off by default. `renderMode: 'onDemand'` silently degrades to always-on when
|
|
889
|
+
* something marks the scene dirty every frame, and until now there was no way
|
|
890
|
+
* to find out what — `dirty === true` said nothing about the cause. Enable
|
|
891
|
+
* this, run the scene, then read {@link dirtyReasons}.
|
|
892
|
+
*/
|
|
893
|
+
setDirtyTracking(enabled: boolean): void;
|
|
894
|
+
/** Whether dirty attribution is currently being recorded. */
|
|
895
|
+
get dirtyTracking(): boolean;
|
|
896
|
+
/**
|
|
897
|
+
* Recorded dirty attributions, most frequent first.
|
|
898
|
+
*
|
|
899
|
+
* `count` is what matters for the `onDemand` diagnosis: a reason appearing once
|
|
900
|
+
* per frame over hundreds of frames is the thing keeping the scene awake.
|
|
901
|
+
*/
|
|
902
|
+
get dirtyReasons(): DirtyReasonEntry[];
|
|
903
|
+
/** Drop recorded attributions, keeping tracking enabled. */
|
|
904
|
+
clearDirtyReasons(): void;
|
|
849
905
|
/**
|
|
850
906
|
* Live frame telemetry for profilers and devtools overlays. All timings are
|
|
851
907
|
* measured on the `requestAnimationFrame` loop; a scene driven only by
|