@vectojs/core 1.19.0 → 1.21.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-IA3KW4CG.js → chunk-AGP4VLF4.js} +75 -25
- package/dist/{chunk-XWBVBXFZ.mjs → chunk-FRMLD4PP.mjs} +50 -0
- package/dist/{chunk-L4SWVP2H.js → chunk-GKSCJ6AF.js} +201 -9
- package/dist/{chunk-QS3CUV7H.mjs → chunk-RTENOAYT.mjs} +192 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +542 -228
- package/dist/index.mjs +335 -21
- package/dist/renderer/CanvasRenderer.d.ts +2 -0
- package/dist/renderer/GlyphRasterAtlas.d.ts +186 -0
- package/dist/renderer/IRenderer.d.ts +31 -0
- package/dist/renderer/index.d.ts +1 -0
- package/dist/renderer.js +4 -2
- package/dist/renderer.mjs +3 -1
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +144 -0
- package/dist/tree/Scene.d.ts +179 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var _chunkL4SWVP2Hjs = require('./chunk-L4SWVP2H.js');
|
|
12
11
|
|
|
12
|
+
var _chunkGKSCJ6AFjs = require('./chunk-GKSCJ6AF.js');
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
var _chunkAGP4VLF4js = require('./chunk-AGP4VLF4.js');
|
|
18
19
|
|
|
19
20
|
// src/tree/Scene.ts
|
|
20
21
|
var _animation = require('@vectojs/animation'); _createStarExport(_animation);
|
|
@@ -29,7 +30,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
|
|
|
29
30
|
var PARTICLE_OFFSET_ORIGIN_Y = 5;
|
|
30
31
|
var PARTICLE_OFFSET_SIZE = 6;
|
|
31
32
|
var PARTICLE_OFFSET_LIFE = 7;
|
|
32
|
-
var ComputeParticleEntity = (_class = class extends
|
|
33
|
+
var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
|
|
@@ -1539,32 +1540,96 @@ var Scene = (_class7 = class _Scene {
|
|
|
1539
1540
|
__init29() {this.renderMode = "always"}
|
|
1540
1541
|
/** Cap on distinct recorded dirty reasons (see `recordDirtyReason`). */
|
|
1541
1542
|
static __initStatic4() {this.MAX_DIRTY_REASONS = 200}
|
|
1542
|
-
__init30() {this.
|
|
1543
|
-
__init31() {this.
|
|
1544
|
-
|
|
1543
|
+
__init30() {this._phaseTiming = false}
|
|
1544
|
+
__init31() {this._phaseTotals = /* @__PURE__ */ new Map()}
|
|
1545
|
+
/**
|
|
1546
|
+
* Start or stop per-phase render timing.
|
|
1547
|
+
*
|
|
1548
|
+
* Off by default, and the probes compile to a single boolean test when off:
|
|
1549
|
+
* these sit on the frame path, so the disabled cost has to be nothing. Enable,
|
|
1550
|
+
* run the scene, then read {@link renderPhases}.
|
|
1551
|
+
*
|
|
1552
|
+
* Exists because a frame total cannot tell you where the time went. The
|
|
1553
|
+
* markdown streaming benchmark put render at 85-99% of an append's cost, and
|
|
1554
|
+
* there was no way to decompose that number further — which is exactly the
|
|
1555
|
+
* position that led to two wrong optimisation guesses earlier
|
|
1556
|
+
* (`CodeBlock` reuse, hit-grid fusion), both of which measured as no change.
|
|
1557
|
+
*/
|
|
1558
|
+
setPhaseTiming(enabled) {
|
|
1559
|
+
this._phaseTiming = enabled;
|
|
1560
|
+
if (!enabled) this.clearRenderPhases();
|
|
1561
|
+
}
|
|
1562
|
+
/** Whether per-phase render timing is being recorded. */
|
|
1563
|
+
get phaseTiming() {
|
|
1564
|
+
return this._phaseTiming;
|
|
1565
|
+
}
|
|
1566
|
+
/**
|
|
1567
|
+
* Accumulate one phase sample.
|
|
1568
|
+
*
|
|
1569
|
+
* Totals rather than a per-frame log: the question is always "which phase owns
|
|
1570
|
+
* the frame", and a log of thousands of samples answers it less directly while
|
|
1571
|
+
* costing far more memory. `maxMs` is kept because a phase that is cheap on
|
|
1572
|
+
* average but spikes is a different problem from one that is uniformly slow.
|
|
1573
|
+
*/
|
|
1574
|
+
_recordPhase(phase, ms) {
|
|
1575
|
+
const existing = this._phaseTotals.get(phase);
|
|
1576
|
+
if (existing) {
|
|
1577
|
+
existing.totalMs += ms;
|
|
1578
|
+
existing.calls++;
|
|
1579
|
+
if (ms > existing.maxMs) existing.maxMs = ms;
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
this._phaseTotals.set(phase, { totalMs: ms, calls: 1, maxMs: ms });
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Recorded phase timings, most expensive first, with each phase's share of the
|
|
1586
|
+
* measured total.
|
|
1587
|
+
*
|
|
1588
|
+
* `share` is the number that matters: a phase at 4% cannot be worth optimising
|
|
1589
|
+
* however inefficient it looks in isolation.
|
|
1590
|
+
*/
|
|
1591
|
+
get renderPhases() {
|
|
1592
|
+
const entries = [...this._phaseTotals.entries()];
|
|
1593
|
+
const denominator = entries.filter(([phase]) => phase !== "render").reduce((sum, [, v]) => sum + v.totalMs, 0);
|
|
1594
|
+
return entries.map(([phase, v]) => ({
|
|
1595
|
+
phase,
|
|
1596
|
+
totalMs: +v.totalMs.toFixed(3),
|
|
1597
|
+
calls: v.calls,
|
|
1598
|
+
avgMs: +(v.totalMs / Math.max(1, v.calls)).toFixed(4),
|
|
1599
|
+
maxMs: +v.maxMs.toFixed(3),
|
|
1600
|
+
share: phase === "render" ? null : +(100 * v.totalMs / Math.max(1e-9, denominator)).toFixed(1)
|
|
1601
|
+
})).sort((a, b) => b.totalMs - a.totalMs);
|
|
1602
|
+
}
|
|
1603
|
+
/** Drop recorded phase timings, keeping timing enabled. */
|
|
1604
|
+
clearRenderPhases() {
|
|
1605
|
+
this._phaseTotals.clear();
|
|
1606
|
+
}
|
|
1607
|
+
__init32() {this._dirtyTracking = false}
|
|
1608
|
+
__init33() {this._dirtyReasons = /* @__PURE__ */ new Map()}
|
|
1609
|
+
__init34() {this.dirty = true}
|
|
1545
1610
|
/** Whether to throttle rendering to 2 FPS when the scene is static to save power. */
|
|
1546
|
-
|
|
1611
|
+
__init35() {this.autoThrottle = true}
|
|
1547
1612
|
// --- Frame telemetry (read via `frameStats`) ---------------------------
|
|
1548
1613
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
1549
|
-
|
|
1614
|
+
__init36() {this._lastFrameMs = 0}
|
|
1550
1615
|
/** Rolling exponential average of rendered-frame intervals, in ms. */
|
|
1551
|
-
|
|
1616
|
+
__init37() {this._avgFrameIntervalMs = 0}
|
|
1552
1617
|
/** dt (ms) handed to the last rendered frame. */
|
|
1553
|
-
|
|
1618
|
+
__init38() {this._lastDt = 0}
|
|
1554
1619
|
/** Count of frames actually rendered since the loop started. */
|
|
1555
|
-
|
|
1620
|
+
__init39() {this._renderedFrames = 0}
|
|
1556
1621
|
/** Count of rAF ticks skipped (idle / capped) since the loop started. */
|
|
1557
|
-
|
|
1622
|
+
__init40() {this._skippedFrames = 0}
|
|
1558
1623
|
/** `time` of the previous *rendered* frame, for interval measurement. */
|
|
1559
|
-
|
|
1624
|
+
__init41() {this._lastRenderTick = 0}
|
|
1560
1625
|
/**
|
|
1561
1626
|
* Frame-rate cap (power saving). `0` = uncapped (native refresh). When set,
|
|
1562
1627
|
* the loop renders at most `maxFPS` times per second; animations still run,
|
|
1563
1628
|
* just less often. See {@link SceneOptions.maxFPS}.
|
|
1564
1629
|
*/
|
|
1565
|
-
|
|
1630
|
+
__init42() {this.maxFPS = 60}
|
|
1566
1631
|
/** Whether the OS prefers-reduced-motion setting auto-caps the loop. */
|
|
1567
|
-
|
|
1632
|
+
__init43() {this.respectReducedMotion = true}
|
|
1568
1633
|
/**
|
|
1569
1634
|
* Reading direction for accessibility tab/traversal order (`'ltr'` default,
|
|
1570
1635
|
* `'rtl'`). Controls the inline sort within a visual row in
|
|
@@ -1580,15 +1645,15 @@ var Scene = (_class7 = class _Scene {
|
|
|
1580
1645
|
this.a11yNeedsReorder = true;
|
|
1581
1646
|
}
|
|
1582
1647
|
}
|
|
1583
|
-
|
|
1648
|
+
__init44() {this._readingDirection = "ltr"}
|
|
1584
1649
|
/** Cached media-query list; `.matches` is read live each frame. */
|
|
1585
|
-
|
|
1650
|
+
__init45() {this.reducedMotionQuery = null}
|
|
1586
1651
|
/** Cached `(forced-colors: active)` query (Windows High Contrast etc.). A
|
|
1587
1652
|
* canvas gets NO automatic forced-colors treatment from the browser (it's
|
|
1588
1653
|
* opaque pixels), so components must read {@link forcedColors} and repaint
|
|
1589
1654
|
* with system colors themselves; a change listener repaints idle scenes. */
|
|
1590
|
-
|
|
1591
|
-
|
|
1655
|
+
__init46() {this.forcedColorsQuery = null}
|
|
1656
|
+
__init47() {this.forcedColorsChangeHandler = null}
|
|
1592
1657
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
1593
1658
|
get prefersReducedMotion() {
|
|
1594
1659
|
return this.respectReducedMotion && !!_optionalChain([this, 'access', _21 => _21.reducedMotionQuery, 'optionalAccess', _22 => _22.matches]);
|
|
@@ -1608,82 +1673,105 @@ var Scene = (_class7 = class _Scene {
|
|
|
1608
1673
|
* Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
|
|
1609
1674
|
* frame. See {@link SceneOptions.a11ySyncInterval}.
|
|
1610
1675
|
*/
|
|
1611
|
-
|
|
1676
|
+
__init48() {this.a11ySyncInterval = 0}
|
|
1612
1677
|
/** Timestamp of the last a11y sync, for throttling. */
|
|
1613
|
-
|
|
1678
|
+
__init49() {this.lastA11ySync = -Infinity}
|
|
1614
1679
|
/** True if we skipped an a11y sync during animation and need to sync when at rest. */
|
|
1615
|
-
|
|
1680
|
+
__init50() {this.a11yPendingSyncAfterAnimation = false}
|
|
1616
1681
|
// A11y / Automation Layer. `null` in non-DOM (SSR/Node) environments — the
|
|
1617
1682
|
// whole projection degrades to a no-op so the engine's logic stays usable
|
|
1618
1683
|
// server-side (e.g. headless layout / vector export) without jsdom.
|
|
1619
1684
|
|
|
1620
|
-
|
|
1685
|
+
__init51() {this.a11yElements = /* @__PURE__ */ new Map()}
|
|
1621
1686
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
1622
|
-
|
|
1687
|
+
__init52() {this.contentElements = /* @__PURE__ */ new Map()}
|
|
1623
1688
|
/** Pending cold font-calibration frame per projected grid entity. */
|
|
1624
|
-
|
|
1689
|
+
__init53() {this.contentGridCalibrationFrames = /* @__PURE__ */ new Map()}
|
|
1625
1690
|
/** Detached, untransformed font probes used by the cold calibration pass. */
|
|
1626
|
-
|
|
1691
|
+
__init54() {this.contentGridCalibrationProbes = /* @__PURE__ */ new Map()}
|
|
1692
|
+
/**
|
|
1693
|
+
* Monotonic stamp identifying the conditions grid cells were calibrated under.
|
|
1694
|
+
*
|
|
1695
|
+
* Calibration measures the difference between the advance the canvas grid assigns
|
|
1696
|
+
* a cluster and the width the browser lays it out at, then writes a per-cell
|
|
1697
|
+
* `scaleX`. That result stays valid until the font or the page scale changes, and
|
|
1698
|
+
* it lives on the cell element — so a cell carrying this stamp needs no further
|
|
1699
|
+
* work.
|
|
1700
|
+
*
|
|
1701
|
+
* The scan that feeds calibration was O(cells) on every revision bump: for a
|
|
1702
|
+
* streaming code block it re-derived a measurement key for every cell in the
|
|
1703
|
+
* block each frame in order to produce only ~20 distinct keys, costing about
|
|
1704
|
+
* 2.5 ms/frame after the `style.font` fix and still over half of `a11ySync`. Since
|
|
1705
|
+
* carrier reuse (#244) leaves untouched lines — and therefore their calibrated
|
|
1706
|
+
* transforms — in place, cells stamped with the current generation can simply be
|
|
1707
|
+
* skipped, making the scan O(new cells) instead.
|
|
1708
|
+
*
|
|
1709
|
+
* A plain incrementing integer rather than the descriptive calibration key,
|
|
1710
|
+
* because it goes into an attribute selector and must not need escaping.
|
|
1711
|
+
*/
|
|
1712
|
+
__init55() {this.contentGridCalibrationGeneration = 0}
|
|
1713
|
+
/** The `(fontEpoch, pageScale)` pair the current generation corresponds to. */
|
|
1714
|
+
__init56() {this.contentGridCalibrationStamp = ""}
|
|
1627
1715
|
/** Invalidates grid font calibration after browser font availability changes. */
|
|
1628
|
-
|
|
1716
|
+
__init57() {this.contentFontEpoch = 0}
|
|
1629
1717
|
/** Cached Canvas-to-client scale for the current font/viewport epoch. */
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1718
|
+
__init58() {this.contentMetricScaleEpoch = -1}
|
|
1719
|
+
__init59() {this.contentMetricScaleX = 1}
|
|
1720
|
+
__init60() {this.contentProjectionEnabled = true}
|
|
1633
1721
|
// Virtualization margin (px) for content projection; `undefined` → one
|
|
1634
1722
|
// viewport height, resolved at sync time. `Infinity` = materialize everything.
|
|
1635
|
-
|
|
1723
|
+
__init61() {this.contentProjectionMargin = void 0}
|
|
1636
1724
|
/**
|
|
1637
1725
|
* True while a text-selection drag that started on a projection's blank
|
|
1638
1726
|
* region (no text node under the press) is being driven manually — the
|
|
1639
1727
|
* browser has no native anchor for it, so mousemove extends the Selection
|
|
1640
1728
|
* from the position we resolved ourselves.
|
|
1641
1729
|
*/
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1730
|
+
__init62() {this.blankRegionSelectionDrag = false}
|
|
1731
|
+
__init63() {this.contentSelectionAnchor = null}
|
|
1732
|
+
__init64() {this.contentSelectionEndListener = null}
|
|
1645
1733
|
// Animation/interactive flags collected during the render walk (tree-walk
|
|
1646
1734
|
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
1647
1735
|
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
1648
|
-
|
|
1649
|
-
|
|
1736
|
+
__init65() {this.frameHadAnimation = true}
|
|
1737
|
+
__init66() {this.frameHadInteractive = true}
|
|
1650
1738
|
|
|
1651
1739
|
/** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
|
|
1652
1740
|
* (window moved between monitors, browser zoom) so the canvas backing store
|
|
1653
1741
|
* can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
|
|
1654
1742
|
* A resolution media query only fires when leaving its exact value, so the
|
|
1655
1743
|
* handler re-arms a fresh query for the new DPR each time. */
|
|
1656
|
-
|
|
1744
|
+
__init67() {this.dprMediaQuery = null}
|
|
1657
1745
|
/** For embedded (`disableWindowResize`) scenes: observes the canvas element so
|
|
1658
1746
|
* a CSS/layout-driven size change re-runs `resize()`. A window `resize`
|
|
1659
1747
|
* listener never fires for these (the window isn't what changed), so without
|
|
1660
1748
|
* this an embedded canvas stayed at its initial size forever. */
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1749
|
+
__init68() {this.canvasResizeObserver = null}
|
|
1750
|
+
__init69() {this.dprChangeHandler = null}
|
|
1751
|
+
__init70() {this.focusedA11yElement = null}
|
|
1664
1752
|
/** Last geometry `syncOverlayGeometry` wrote, so an unchanged frame can skip the
|
|
1665
1753
|
* style writes entirely. Reset to `null` to force the next sync (a new overlay
|
|
1666
1754
|
* layer was created and has never been positioned). */
|
|
1667
|
-
|
|
1755
|
+
__init71() {this._overlayGeometry = null}
|
|
1668
1756
|
/** Shadow elements the pointer is currently inside. Lets a removal that happens
|
|
1669
1757
|
* mid-hover synthesize the `pointerleave` the browser never sends for a
|
|
1670
1758
|
* detached element, so the entity doesn't keep its hover state. */
|
|
1671
|
-
|
|
1759
|
+
__init72() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
|
|
1672
1760
|
/** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
|
|
1673
1761
|
* pruned (virtualization/streaming/removal) while it holds focus, we move
|
|
1674
1762
|
* focus here instead of letting the browser drop it to <body> — keeping the
|
|
1675
1763
|
* screen-reader virtual cursor inside the scene's a11y region. */
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1764
|
+
__init73() {this.focusSentinel = null}
|
|
1765
|
+
__init74() {this.caretBlinkTimer = null}
|
|
1766
|
+
__init75() {this.a11yNeedsReorder = true}
|
|
1767
|
+
__init76() {this.portalRoot = null}
|
|
1768
|
+
__init77() {this.fullViewportElements = []}
|
|
1769
|
+
__init78() {this.normalElements = []}
|
|
1770
|
+
__init79() {this.activeIds = /* @__PURE__ */ new Set()}
|
|
1771
|
+
__init80() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
|
|
1772
|
+
__init81() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
|
|
1773
|
+
__init82() {this.portalEntities = /* @__PURE__ */ new Map()}
|
|
1774
|
+
__init83() {this.renderOrderCounter = 0}
|
|
1687
1775
|
/**
|
|
1688
1776
|
* Monotonic render-frame counter, bumped once per authoritative `render()`
|
|
1689
1777
|
* pass. Entities stamp their per-frame world-matrix cache with this value and
|
|
@@ -1692,7 +1780,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1692
1780
|
* back to the ancestor walk. Public for the same reason `Entity._getTrig`/
|
|
1693
1781
|
* `_setWorldCache` are: it is a cross-class render-internal contract.
|
|
1694
1782
|
*/
|
|
1695
|
-
|
|
1783
|
+
__init84() {this.currentFrame = 0}
|
|
1696
1784
|
// ── WASM transform backend (invisible accelerator) ──────────────────────────
|
|
1697
1785
|
// When `_transformBackend === 'wasm'`, the main render walk sources each
|
|
1698
1786
|
// entity's world matrix from an SoA store composed by `_wasm` (see
|
|
@@ -1700,24 +1788,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
1700
1788
|
// fallback and the default: a null backend, a non-main renderer, or any entity
|
|
1701
1789
|
// absent from the store all fall back to the JS composition, so WASM can only
|
|
1702
1790
|
// ever change *how fast* a world matrix is produced, never *what* it is.
|
|
1703
|
-
|
|
1704
|
-
|
|
1791
|
+
__init85() {this._wasm = null}
|
|
1792
|
+
__init86() {this._transformBackend = "js"}
|
|
1705
1793
|
// Resident store state (Stage 3). The store layout — slot assignment + sibling
|
|
1706
1794
|
// runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
|
|
1707
1795
|
// structure changes (add/remove/reparent bump `_structureVersion`). Between
|
|
1708
1796
|
// rebuilds the per-frame cost is: gather each entity's transform into the
|
|
1709
1797
|
// resident wasm input view + run the kernel — no reallocation, no readback.
|
|
1710
|
-
|
|
1711
|
-
|
|
1798
|
+
__init87() {this._treeStore = null}
|
|
1799
|
+
__init88() {this._slotEntity = []}
|
|
1712
1800
|
// store slot -> entity (also validates slots)
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1801
|
+
__init89() {this._wasmInputs = null}
|
|
1802
|
+
__init90() {this._wasmWorld = null}
|
|
1803
|
+
__init91() {this._structureVersion = 0}
|
|
1804
|
+
__init92() {this._storeStructureVersion = -1}
|
|
1717
1805
|
// Cached list of ComputeParticleEntity instances in the tree, keyed by the
|
|
1718
1806
|
// structure version it was gathered at. Rebuilt only on a topology change.
|
|
1719
|
-
|
|
1720
|
-
|
|
1807
|
+
__init93() {this._computeEntities = []}
|
|
1808
|
+
__init94() {this._computeEntitiesVersion = -1}
|
|
1721
1809
|
/** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
|
|
1722
1810
|
* it. Called by `Entity.add`/`remove` (topology changes only). */
|
|
1723
1811
|
markStructureChanged() {
|
|
@@ -1799,7 +1887,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1799
1887
|
* cached globally; the instance is per-Scene, which is the isolation that
|
|
1800
1888
|
* actually matters.
|
|
1801
1889
|
*/
|
|
1802
|
-
|
|
1890
|
+
__init95() {this._wasmRuntime = null}
|
|
1803
1891
|
/**
|
|
1804
1892
|
* Load (or reuse) this Scene's shared WASM runtime.
|
|
1805
1893
|
*
|
|
@@ -1827,30 +1915,30 @@ var Scene = (_class7 = class _Scene {
|
|
|
1827
1915
|
get wasmRuntime() {
|
|
1828
1916
|
return this._wasmRuntime;
|
|
1829
1917
|
}
|
|
1830
|
-
|
|
1918
|
+
__init96() {this._hitWasm = null}
|
|
1831
1919
|
// Cache key: which frame + structure version the grid was last (successfully,
|
|
1832
1920
|
// non-overflowing) built for. findEntityAt is called ad-hoc (pointer
|
|
1833
1921
|
// hover/click), not every frame, so the grid is refreshed lazily on demand
|
|
1834
1922
|
// rather than proactively every render() — unlike the transform store, which
|
|
1835
1923
|
// every frame's draw depends on.
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1924
|
+
__init97() {this._hitGridFrame = -1}
|
|
1925
|
+
__init98() {this._hitGridOk = false}
|
|
1926
|
+
__init99() {this._hitSlotEntity = []}
|
|
1927
|
+
__init100() {this._hitBoundless = []}
|
|
1840
1928
|
/** Reused buffer for the fused gather, so a pointer query allocates nothing. */
|
|
1841
|
-
|
|
1929
|
+
__init101() {this._hitGatherBuffer = null}
|
|
1842
1930
|
/**
|
|
1843
1931
|
* Whether the last grid build sourced its AABBs from the WASM transform store
|
|
1844
1932
|
* rather than recomputing them in JS. Diagnostic only — both paths must
|
|
1845
1933
|
* produce the same entity for a given point.
|
|
1846
1934
|
*/
|
|
1847
|
-
|
|
1935
|
+
__init102() {this._hitFusedGather = false}
|
|
1848
1936
|
/**
|
|
1849
1937
|
* Whether `compute_aabbs` has run against the current frame's world matrices.
|
|
1850
1938
|
* The AABB pass is only meaningful after a `compose_*`, so the fused gather
|
|
1851
1939
|
* must not read the views before then.
|
|
1852
1940
|
*/
|
|
1853
|
-
|
|
1941
|
+
__init103() {this._wasmAabbsFresh = false}
|
|
1854
1942
|
/** Did the last hit-grid build use the fused (WASM-store) gather? */
|
|
1855
1943
|
get hitGatherPath() {
|
|
1856
1944
|
return this._hitFusedGather ? "fused" : "js";
|
|
@@ -1964,25 +2052,25 @@ var Scene = (_class7 = class _Scene {
|
|
|
1964
2052
|
// EasingFn (which cannot cross into WASM) all fall through to it — WASM can
|
|
1965
2053
|
// only ever change *how* a driver is advanced, never *what* value it lands
|
|
1966
2054
|
// on.
|
|
1967
|
-
|
|
2055
|
+
__init104() {this._animWasm = null}
|
|
1968
2056
|
// Entities with at least one active driver, added by Entity._spawnDriver.
|
|
1969
2057
|
// Self-pruning: _tickBatchedDrivers drops an entry the first time it visits
|
|
1970
2058
|
// an entity whose drivers have since all completed or been removed. This is
|
|
1971
2059
|
// what lets the batch pass find its candidates in O(active drivers), not
|
|
1972
2060
|
// O(tree size) — the exact mistake G3's first integrated benchmark made.
|
|
1973
|
-
|
|
2061
|
+
__init105() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
|
|
1974
2062
|
// Reused across frames instead of allocating a fresh array + N {entity,prop,
|
|
1975
2063
|
// driver} objects every call — the integrated benchmark
|
|
1976
2064
|
// (benchmarks/anim-wasm-scene) found that allocation churn was the
|
|
1977
2065
|
// dominant integrated cost, not the wasm kernel itself. Parallel arrays,
|
|
1978
2066
|
// truncated to the live count after each use so a stale tail slot never
|
|
1979
2067
|
// pins a no-longer-active entity/driver in memory.
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
2068
|
+
__init106() {this._springEntities = []}
|
|
2069
|
+
__init107() {this._springProps = []}
|
|
2070
|
+
__init108() {this._springDrivers = []}
|
|
2071
|
+
__init109() {this._tweenEntities = []}
|
|
2072
|
+
__init110() {this._tweenProps = []}
|
|
2073
|
+
__init111() {this._tweenDrivers = []}
|
|
1986
2074
|
/**
|
|
1987
2075
|
* Minimum number of batchable (spring, or named-easing tween) active drivers
|
|
1988
2076
|
* before a frame engages the WASM batch path at all; below it, every driver
|
|
@@ -2054,7 +2142,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2054
2142
|
* Setting {@link animDriverGateCount} overwrites all three, so existing code
|
|
2055
2143
|
* that tuned the single knob keeps working unchanged.
|
|
2056
2144
|
*/
|
|
2057
|
-
|
|
2145
|
+
__init112() {this._animBatchedLastFrame = false}
|
|
2058
2146
|
/**
|
|
2059
2147
|
* Whether the WASM batch path actually ran on the most recent frame.
|
|
2060
2148
|
*
|
|
@@ -2066,7 +2154,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2066
2154
|
get animBatchedLastFrame() {
|
|
2067
2155
|
return this._animBatchedLastFrame;
|
|
2068
2156
|
}
|
|
2069
|
-
|
|
2157
|
+
__init113() {this.animGate = {
|
|
2070
2158
|
spring: 128,
|
|
2071
2159
|
tween: 256,
|
|
2072
2160
|
mixed: 128
|
|
@@ -2104,7 +2192,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2104
2192
|
// (benchmarks/particle-wasm). f32 (matches the WGSL shader), bit-identical to
|
|
2105
2193
|
// a JS f32 reference oracle; updateCPU (f64) stays the permanent fallback when
|
|
2106
2194
|
// no backend is installed or a scene runs on WebGPU.
|
|
2107
|
-
|
|
2195
|
+
__init114() {this._particleWasm = null}
|
|
2108
2196
|
/** Which backend runs the CPU particle simulation. Reflects only whether a
|
|
2109
2197
|
* backend is installed (the WebGPU compute path, when active, is used first
|
|
2110
2198
|
* regardless). */
|
|
@@ -2354,46 +2442,46 @@ var Scene = (_class7 = class _Scene {
|
|
|
2354
2442
|
* sync, so retaining the order prevents a newly opened overlay from spending
|
|
2355
2443
|
* its first frame below previously projected controls.
|
|
2356
2444
|
*/
|
|
2357
|
-
|
|
2445
|
+
__init115() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
|
|
2358
2446
|
// Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2447
|
+
__init116() {this.pointRenderer = null}
|
|
2448
|
+
__init117() {this.glCanvas = null}
|
|
2449
|
+
__init118() {this.glContextLostHandler = null}
|
|
2450
|
+
__init119() {this.glContextRestoredHandler = null}
|
|
2363
2451
|
|
|
2364
2452
|
|
|
2365
2453
|
|
|
2366
|
-
|
|
2454
|
+
__init120() {this.disableWindowResize = false}
|
|
2367
2455
|
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
2368
2456
|
|
|
2369
2457
|
// WebGPU properties
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2458
|
+
__init121() {this.destroyed = false}
|
|
2459
|
+
__init122() {this.device = null}
|
|
2460
|
+
__init123() {this.deviceLost = false}
|
|
2461
|
+
__init124() {this.particleBackend = "auto"}
|
|
2462
|
+
__init125() {this._webgpuDisabled = false}
|
|
2375
2463
|
get webgpuDisabled() {
|
|
2376
2464
|
return this._webgpuDisabled || this.particleBackend === "cpu";
|
|
2377
2465
|
}
|
|
2378
2466
|
set webgpuDisabled(value) {
|
|
2379
2467
|
this._webgpuDisabled = value;
|
|
2380
2468
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2469
|
+
__init126() {this.recoveryTimerId = null}
|
|
2470
|
+
__init127() {this.manager = null}
|
|
2471
|
+
__init128() {this.initializingWebGPU = false}
|
|
2472
|
+
__init129() {this.gpuCanvas = null}
|
|
2473
|
+
__init130() {this.gpuContext = null}
|
|
2386
2474
|
/** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2475
|
+
__init131() {this.gpuHasContent = false}
|
|
2476
|
+
__init132() {this.mouseX = -9999}
|
|
2477
|
+
__init133() {this.mouseY = -9999}
|
|
2478
|
+
__init134() {this.pointerMoveListener = null}
|
|
2479
|
+
__init135() {this.pointerLeaveListener = null}
|
|
2392
2480
|
/** Element the pointer listeners are bound to (parent container if present,
|
|
2393
2481
|
* else the canvas). Stored so `destroy()` detaches from the same element. */
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2482
|
+
__init136() {this.pointerEventTarget = null}
|
|
2483
|
+
__init137() {this.hasWarnedZeroSize = false}
|
|
2484
|
+
__init138() {this.fontLoadHandler = null}
|
|
2397
2485
|
// ── Dev-mode warning infrastructure ──────────────────────────────
|
|
2398
2486
|
//
|
|
2399
2487
|
// Enable with `Scene.devMode = true` or by setting `globalThis.__DEV__`.
|
|
@@ -2411,7 +2499,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2411
2499
|
return false;
|
|
2412
2500
|
}
|
|
2413
2501
|
|
|
2414
|
-
|
|
2502
|
+
__init139() {this._devFrameCount = 0}
|
|
2415
2503
|
_devWarn(message) {
|
|
2416
2504
|
if (!this._devActive) return;
|
|
2417
2505
|
console.warn(`[vectojs/dev] ${message}`);
|
|
@@ -2455,7 +2543,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2455
2543
|
};
|
|
2456
2544
|
walkProjections(this.root);
|
|
2457
2545
|
}
|
|
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);
|
|
2546
|
+
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);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);
|
|
2459
2547
|
this.canvas = canvas;
|
|
2460
2548
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
2461
2549
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
@@ -2486,7 +2574,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2486
2574
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
2487
2575
|
_optionalChain([this, 'access', _45 => _45.forcedColorsQuery, 'access', _46 => _46.addEventListener, 'optionalCall', _47 => _47("change", this.forcedColorsChangeHandler)]);
|
|
2488
2576
|
}
|
|
2489
|
-
this.root = new class RootEntity extends
|
|
2577
|
+
this.root = new class RootEntity extends _chunkAGP4VLF4js.Entity {
|
|
2490
2578
|
isPointInside() {
|
|
2491
2579
|
return false;
|
|
2492
2580
|
}
|
|
@@ -2495,7 +2583,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2495
2583
|
}
|
|
2496
2584
|
}("root");
|
|
2497
2585
|
this.root._scene = this;
|
|
2498
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
2586
|
+
this.overlayRoot = new class OverlayRoot extends _chunkAGP4VLF4js.Entity {
|
|
2499
2587
|
isPointInside() {
|
|
2500
2588
|
return false;
|
|
2501
2589
|
}
|
|
@@ -2506,7 +2594,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2506
2594
|
if (options.renderer) {
|
|
2507
2595
|
this.renderer = options.renderer;
|
|
2508
2596
|
} else {
|
|
2509
|
-
this.renderer = new (0,
|
|
2597
|
+
this.renderer = new (0, _chunkGKSCJ6AFjs.CanvasRenderer)(
|
|
2510
2598
|
canvas,
|
|
2511
2599
|
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
2512
2600
|
this.maxDPR
|
|
@@ -2732,12 +2820,35 @@ var Scene = (_class7 = class _Scene {
|
|
|
2732
2820
|
this.contentSelectionAnchor = null;
|
|
2733
2821
|
if (this.a11yRoot) this.a11yRoot.style.pointerEvents = "none";
|
|
2734
2822
|
}
|
|
2823
|
+
/**
|
|
2824
|
+
* Index of the carrier line currently holding a selection inside `el`, or
|
|
2825
|
+
* `null`.
|
|
2826
|
+
*
|
|
2827
|
+
* Lets a partial re-materialization decide whether the user's selection is even
|
|
2828
|
+
* affected. Checks the tracked anchor first (it survives a drag) and falls back
|
|
2829
|
+
* to the live DOM selection.
|
|
2830
|
+
*/
|
|
2831
|
+
contentGridSelectionLine(el) {
|
|
2832
|
+
const candidates = [_optionalChain([this, 'access', _62 => _62.contentSelectionAnchor, 'optionalAccess', _63 => _63.node])];
|
|
2833
|
+
if (typeof window !== "undefined" && typeof window.getSelection === "function") {
|
|
2834
|
+
const selection = window.getSelection();
|
|
2835
|
+
candidates.push(_optionalChain([selection, 'optionalAccess', _64 => _64.anchorNode]), _optionalChain([selection, 'optionalAccess', _65 => _65.focusNode]));
|
|
2836
|
+
}
|
|
2837
|
+
for (const candidate of candidates) {
|
|
2838
|
+
if (!candidate || !el.contains(candidate)) continue;
|
|
2839
|
+
let cursor = candidate;
|
|
2840
|
+
while (cursor && cursor.parentNode !== el) cursor = cursor.parentNode;
|
|
2841
|
+
const lineIndex = _optionalChain([cursor, 'optionalAccess', _66 => _66.dataset, 'optionalAccess', _67 => _67.vectoGridLine]);
|
|
2842
|
+
if (lineIndex !== void 0) return Number(lineIndex);
|
|
2843
|
+
}
|
|
2844
|
+
return null;
|
|
2845
|
+
}
|
|
2735
2846
|
releaseContentSelectionForRebuild(el) {
|
|
2736
2847
|
const selection = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
|
|
2737
|
-
const ownsSelection = this.contentSelectionAnchor && el.contains(this.contentSelectionAnchor.node) || (_optionalChain([selection, 'optionalAccess',
|
|
2848
|
+
const ownsSelection = this.contentSelectionAnchor && el.contains(this.contentSelectionAnchor.node) || (_optionalChain([selection, 'optionalAccess', _68 => _68.anchorNode]) ? el.contains(selection.anchorNode) : false) || (_optionalChain([selection, 'optionalAccess', _69 => _69.focusNode]) ? el.contains(selection.focusNode) : false);
|
|
2738
2849
|
if (!ownsSelection) return;
|
|
2739
2850
|
this.endContentSelectionDrag();
|
|
2740
|
-
_optionalChain([selection, 'optionalAccess',
|
|
2851
|
+
_optionalChain([selection, 'optionalAccess', _70 => _70.removeAllRanges, 'call', _71 => _71()]);
|
|
2741
2852
|
}
|
|
2742
2853
|
/**
|
|
2743
2854
|
* Rebuild a content-projection element's DOM (`rebuild`) while preserving a
|
|
@@ -2796,7 +2907,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2796
2907
|
}
|
|
2797
2908
|
/** Convert browser viewport coordinates into this Scene's logical coordinates. */
|
|
2798
2909
|
clientToScene(clientX, clientY) {
|
|
2799
|
-
const rect = _optionalChain([this, 'access',
|
|
2910
|
+
const rect = _optionalChain([this, 'access', _72 => _72.canvas, 'access', _73 => _73.getBoundingClientRect, 'optionalCall', _74 => _74()]);
|
|
2800
2911
|
if (!rect) return { x: clientX, y: clientY };
|
|
2801
2912
|
const cssWidth = rect.width || this.canvas.clientWidth || this.width;
|
|
2802
2913
|
const cssHeight = rect.height || this.canvas.clientHeight || this.height;
|
|
@@ -2817,13 +2928,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
2817
2928
|
this.registerActiveDriverSubtree(entity);
|
|
2818
2929
|
return this;
|
|
2819
2930
|
}
|
|
2820
|
-
|
|
2931
|
+
/**
|
|
2932
|
+
* Reset per-grid calibration and bookkeeping before a (re)materialization.
|
|
2933
|
+
*
|
|
2934
|
+
* @param entityId - Owning entity, keyed into the calibration maps.
|
|
2935
|
+
* @param el - The projection element.
|
|
2936
|
+
* @param releaseSelection - Whether to drop a selection this element owns.
|
|
2937
|
+
* Pass `false` when carrier lines are being reused: the selection's DOM nodes
|
|
2938
|
+
* survive the pass, so tearing it down would wipe a user's selection on every
|
|
2939
|
+
* streamed chunk — the exact bug `preserveContentSelectionAcrossRebuild`
|
|
2940
|
+
* exists to prevent on the non-grid path.
|
|
2941
|
+
*/
|
|
2942
|
+
clearContentGridState(entityId, el, releaseSelection = true) {
|
|
2821
2943
|
const calibrationFrame = this.contentGridCalibrationFrames.get(entityId);
|
|
2822
2944
|
if (calibrationFrame !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
2823
2945
|
cancelAnimationFrame(calibrationFrame);
|
|
2824
2946
|
}
|
|
2825
2947
|
this.contentGridCalibrationFrames.delete(entityId);
|
|
2826
|
-
_optionalChain([this, 'access',
|
|
2948
|
+
_optionalChain([this, 'access', _75 => _75.contentGridCalibrationProbes, 'access', _76 => _76.get, 'call', _77 => _77(entityId), 'optionalAccess', _78 => _78.remove, 'call', _79 => _79()]);
|
|
2827
2949
|
this.contentGridCalibrationProbes.delete(entityId);
|
|
2828
2950
|
delete el.dataset.vectoGridCalibrationPending;
|
|
2829
2951
|
delete el.dataset.vectoGridCalibration;
|
|
@@ -2833,7 +2955,21 @@ var Scene = (_class7 = class _Scene {
|
|
|
2833
2955
|
delete el.dataset.vectoGridMaterializeMs;
|
|
2834
2956
|
delete el.dataset.vectoGridCalibrationSamples;
|
|
2835
2957
|
delete el.dataset.vectoGridCalibrationMs;
|
|
2836
|
-
this.releaseContentSelectionForRebuild(el);
|
|
2958
|
+
if (releaseSelection) this.releaseContentSelectionForRebuild(el);
|
|
2959
|
+
}
|
|
2960
|
+
/**
|
|
2961
|
+
* Drop any projected elements under `node` without touching the entity tree.
|
|
2962
|
+
*
|
|
2963
|
+
* Used when the walk reaches an invisible subtree: the entities stay put (a
|
|
2964
|
+
* later `show()` re-projects them), but nothing under here may remain
|
|
2965
|
+
* focusable or announced while hidden.
|
|
2966
|
+
*/
|
|
2967
|
+
pruneA11ySubtree(node) {
|
|
2968
|
+
if (this.a11yElements.has(node.id) || this.contentElements.has(node.id)) {
|
|
2969
|
+
this.removeA11yRecursively(node);
|
|
2970
|
+
return;
|
|
2971
|
+
}
|
|
2972
|
+
for (const child of node.children) this.pruneA11ySubtree(child);
|
|
2837
2973
|
}
|
|
2838
2974
|
removeA11yRecursively(node) {
|
|
2839
2975
|
if (node.isDOMPortal) {
|
|
@@ -2861,7 +2997,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2861
2997
|
}
|
|
2862
2998
|
if (this.hoveredA11yElements.has(el)) {
|
|
2863
2999
|
this.hoveredA11yElements.delete(el);
|
|
2864
|
-
node.dispatchEvent(new (0,
|
|
3000
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerleave", node, void 0, false));
|
|
2865
3001
|
}
|
|
2866
3002
|
this.preserveFocusOnRemoval(el);
|
|
2867
3003
|
el.remove();
|
|
@@ -2963,12 +3099,12 @@ var Scene = (_class7 = class _Scene {
|
|
|
2963
3099
|
this.canvasResizeObserver = null;
|
|
2964
3100
|
}
|
|
2965
3101
|
if (this.dprMediaQuery && this.dprChangeHandler) {
|
|
2966
|
-
_optionalChain([this, 'access',
|
|
3102
|
+
_optionalChain([this, 'access', _80 => _80.dprMediaQuery, 'access', _81 => _81.removeEventListener, 'optionalCall', _82 => _82("change", this.dprChangeHandler)]);
|
|
2967
3103
|
this.dprMediaQuery = null;
|
|
2968
3104
|
this.dprChangeHandler = null;
|
|
2969
3105
|
}
|
|
2970
3106
|
if (this.forcedColorsQuery && this.forcedColorsChangeHandler) {
|
|
2971
|
-
_optionalChain([this, 'access',
|
|
3107
|
+
_optionalChain([this, 'access', _83 => _83.forcedColorsQuery, 'access', _84 => _84.removeEventListener, 'optionalCall', _85 => _85("change", this.forcedColorsChangeHandler)]);
|
|
2972
3108
|
this.forcedColorsQuery = null;
|
|
2973
3109
|
this.forcedColorsChangeHandler = null;
|
|
2974
3110
|
}
|
|
@@ -2986,9 +3122,9 @@ var Scene = (_class7 = class _Scene {
|
|
|
2986
3122
|
}
|
|
2987
3123
|
this.pointerEventTarget = null;
|
|
2988
3124
|
}
|
|
2989
|
-
_optionalChain([this, 'access',
|
|
3125
|
+
_optionalChain([this, 'access', _86 => _86.a11yRoot, 'optionalAccess', _87 => _87.remove, 'call', _88 => _88()]);
|
|
2990
3126
|
this.focusSentinel = null;
|
|
2991
|
-
_optionalChain([this, 'access',
|
|
3127
|
+
_optionalChain([this, 'access', _89 => _89.portalRoot, 'optionalAccess', _90 => _90.remove, 'call', _91 => _91()]);
|
|
2992
3128
|
this.a11yElements.clear();
|
|
2993
3129
|
for (const el of this.contentElements.values()) el.remove();
|
|
2994
3130
|
this.contentElements.clear();
|
|
@@ -3011,10 +3147,10 @@ var Scene = (_class7 = class _Scene {
|
|
|
3011
3147
|
}
|
|
3012
3148
|
this.glContextLostHandler = null;
|
|
3013
3149
|
this.glContextRestoredHandler = null;
|
|
3014
|
-
_optionalChain([this, 'access',
|
|
3015
|
-
_optionalChain([this, 'access',
|
|
3016
|
-
_optionalChain([this, 'access',
|
|
3017
|
-
_optionalChain([this, 'access',
|
|
3150
|
+
_optionalChain([this, 'access', _92 => _92.pointRenderer, 'optionalAccess', _93 => _93.destroy, 'call', _94 => _94()]);
|
|
3151
|
+
_optionalChain([this, 'access', _95 => _95.renderer, 'access', _96 => _96.dispose, 'optionalCall', _97 => _97()]);
|
|
3152
|
+
_optionalChain([this, 'access', _98 => _98.glCanvas, 'optionalAccess', _99 => _99.remove, 'call', _100 => _100()]);
|
|
3153
|
+
_optionalChain([this, 'access', _101 => _101.gpuCanvas, 'optionalAccess', _102 => _102.remove, 'call', _103 => _103()]);
|
|
3018
3154
|
this.gpuCanvas = null;
|
|
3019
3155
|
this.gpuContext = null;
|
|
3020
3156
|
if (this.recoveryTimerId) {
|
|
@@ -3026,7 +3162,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3026
3162
|
this.manager = null;
|
|
3027
3163
|
}
|
|
3028
3164
|
if (this.device) {
|
|
3029
|
-
_optionalChain([this, 'access',
|
|
3165
|
+
_optionalChain([this, 'access', _104 => _104.device, 'access', _105 => _105.destroy, 'optionalCall', _106 => _106()]);
|
|
3030
3166
|
this.device = null;
|
|
3031
3167
|
}
|
|
3032
3168
|
}
|
|
@@ -3149,10 +3285,32 @@ var Scene = (_class7 = class _Scene {
|
|
|
3149
3285
|
get overlayRootEntity() {
|
|
3150
3286
|
return this.overlayRoot;
|
|
3151
3287
|
}
|
|
3288
|
+
/**
|
|
3289
|
+
* Advance and render exactly one frame, synchronously.
|
|
3290
|
+
*
|
|
3291
|
+
* This renders UNCONDITIONALLY: it consults neither {@link renderMode} nor
|
|
3292
|
+
* {@link dirty}, and it does not apply the `always`-mode idle auto-throttle.
|
|
3293
|
+
* That is deliberate — a deterministic driver (video export, a test, a
|
|
3294
|
+
* fixed-step benchmark) asks for a frame because it wants that frame, not a
|
|
3295
|
+
* scheduler opinion about whether it is needed.
|
|
3296
|
+
*
|
|
3297
|
+
* The consequence is a measurement footgun worth stating explicitly: a
|
|
3298
|
+
* benchmark that drives frames through `step()` CANNOT observe frame skipping,
|
|
3299
|
+
* so `always` and `onDemand` produce byte-identical draw counts through this
|
|
3300
|
+
* path. An investigation into whether `onDemand` skips redundant repaints once
|
|
3301
|
+
* concluded "it does not" on exactly that basis; on the real rAF loop the same
|
|
3302
|
+
* workload rendered ~1.0 frames per content change. To measure anything about
|
|
3303
|
+
* scheduling, use {@link start} and let `requestAnimationFrame` drive.
|
|
3304
|
+
*
|
|
3305
|
+
* @param dt Seconds to advance. Not clamped by `MAX_FRAME_DT` — the caller
|
|
3306
|
+
* chooses the step, since determinism is the point.
|
|
3307
|
+
*/
|
|
3152
3308
|
step(dt) {
|
|
3153
3309
|
const time = this.lastTime + dt;
|
|
3154
3310
|
this.lastTime = time;
|
|
3311
|
+
const t0 = this._phaseTiming ? performance.now() : 0;
|
|
3155
3312
|
this.render(this.renderer, dt, time);
|
|
3313
|
+
if (this._phaseTiming) this._recordPhase("render", performance.now() - t0);
|
|
3156
3314
|
this.dirty = false;
|
|
3157
3315
|
}
|
|
3158
3316
|
/**
|
|
@@ -3165,6 +3323,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
3165
3323
|
this.dirty = true;
|
|
3166
3324
|
if (this._dirtyTracking && source) this.recordDirtyReason(source);
|
|
3167
3325
|
}
|
|
3326
|
+
/**
|
|
3327
|
+
* Increments whenever the tree's shape changes: add, remove or reparent.
|
|
3328
|
+
*
|
|
3329
|
+
* Already maintained for the resident WASM transform store (see
|
|
3330
|
+
* {@link markStructureChanged}, called from `Entity.add`/`remove`), and exposed
|
|
3331
|
+
* here because a cache of the tree's shape — a DevTools tree model, a serialized
|
|
3332
|
+
* snapshot — is valid exactly as long as this value is unchanged. Comparing it is
|
|
3333
|
+
* O(1) against re-walking the tree, which is what it replaces: DevTools rebuilt
|
|
3334
|
+
* both trees on a fixed 500 ms interval, a constant cost proportional to entity
|
|
3335
|
+
* count, purely because it had no way to ask whether the shape had changed.
|
|
3336
|
+
*
|
|
3337
|
+
* Property changes do NOT bump it. Moving or restyling an entity leaves the
|
|
3338
|
+
* shape intact, so a consumer that also cares about values must read those
|
|
3339
|
+
* directly rather than rebuilding a tree.
|
|
3340
|
+
*/
|
|
3341
|
+
get structureVersion() {
|
|
3342
|
+
return this._structureVersion;
|
|
3343
|
+
}
|
|
3168
3344
|
/**
|
|
3169
3345
|
* Record who marked the scene dirty and why.
|
|
3170
3346
|
*
|
|
@@ -3287,6 +3463,11 @@ var Scene = (_class7 = class _Scene {
|
|
|
3287
3463
|
if (node.isDOMPortal) {
|
|
3288
3464
|
return;
|
|
3289
3465
|
}
|
|
3466
|
+
if (node.a11yHidden) {
|
|
3467
|
+
this.pruneA11ySubtree(node);
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
const nodeStart = this._phaseTiming ? performance.now() : 0;
|
|
3290
3471
|
if (this.shouldProjectA11y(node)) {
|
|
3291
3472
|
let el = this.a11yElements.get(node.id);
|
|
3292
3473
|
const attrs = node.getA11yAttributes();
|
|
@@ -3328,20 +3509,20 @@ var Scene = (_class7 = class _Scene {
|
|
|
3328
3509
|
el.style.background = "transparent";
|
|
3329
3510
|
}
|
|
3330
3511
|
el.addEventListener("click", (e) => {
|
|
3331
|
-
node.dispatchEvent(new (0,
|
|
3512
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("click", node, e));
|
|
3332
3513
|
});
|
|
3333
3514
|
el.addEventListener("dblclick", (e) => {
|
|
3334
|
-
node.dispatchEvent(new (0,
|
|
3515
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("dblclick", node, e));
|
|
3335
3516
|
});
|
|
3336
3517
|
el.addEventListener("mouseenter", (e) => {
|
|
3337
3518
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
3338
3519
|
this.hoveredA11yElements.add(el);
|
|
3339
|
-
node.dispatchEvent(new (0,
|
|
3520
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("hover", node, e, false));
|
|
3340
3521
|
});
|
|
3341
3522
|
el.addEventListener("mouseleave", (e) => {
|
|
3342
3523
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
3343
3524
|
this.hoveredA11yElements.delete(el);
|
|
3344
|
-
node.dispatchEvent(new (0,
|
|
3525
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerleave", node, e, false));
|
|
3345
3526
|
});
|
|
3346
3527
|
const capEl = el;
|
|
3347
3528
|
const releasePointer = (event) => {
|
|
@@ -3357,32 +3538,32 @@ var Scene = (_class7 = class _Scene {
|
|
|
3357
3538
|
};
|
|
3358
3539
|
el.addEventListener("pointerdown", (e) => {
|
|
3359
3540
|
if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
|
|
3360
|
-
node.dispatchEvent(new (0,
|
|
3541
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerdown", node, e));
|
|
3361
3542
|
});
|
|
3362
3543
|
el.addEventListener("pointerup", (e) => {
|
|
3363
3544
|
releasePointer(e);
|
|
3364
|
-
node.dispatchEvent(new (0,
|
|
3545
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointerup", node, e));
|
|
3365
3546
|
});
|
|
3366
3547
|
el.addEventListener("pointercancel", (e) => {
|
|
3367
3548
|
releasePointer(e);
|
|
3368
|
-
node.dispatchEvent(new (0,
|
|
3549
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointercancel", node, e));
|
|
3369
3550
|
});
|
|
3370
3551
|
el.addEventListener(
|
|
3371
3552
|
"pointermove",
|
|
3372
|
-
(e) => node.dispatchEvent(new (0,
|
|
3553
|
+
(e) => node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("pointermove", node, e))
|
|
3373
3554
|
);
|
|
3374
3555
|
el.addEventListener(
|
|
3375
3556
|
"wheel",
|
|
3376
3557
|
(e) => {
|
|
3377
|
-
node.dispatchEvent(new (0,
|
|
3558
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("wheel", node, e));
|
|
3378
3559
|
},
|
|
3379
3560
|
{ passive: false }
|
|
3380
3561
|
);
|
|
3381
3562
|
el.addEventListener("keydown", (e) => {
|
|
3382
|
-
node.dispatchEvent(new (0,
|
|
3563
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("keydown", node, e));
|
|
3383
3564
|
});
|
|
3384
3565
|
el.addEventListener("keyup", (e) => {
|
|
3385
|
-
node.dispatchEvent(new (0,
|
|
3566
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("keyup", node, e));
|
|
3386
3567
|
});
|
|
3387
3568
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
3388
3569
|
const input = el;
|
|
@@ -3413,7 +3594,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3413
3594
|
el.addEventListener("compositionupdate", (e) => {
|
|
3414
3595
|
const data = _nullishCoalesce(e.data, () => ( ""));
|
|
3415
3596
|
composition = {
|
|
3416
|
-
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess',
|
|
3597
|
+
start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _107 => _107.start]), () => ( 0)),
|
|
3417
3598
|
length: data.length
|
|
3418
3599
|
};
|
|
3419
3600
|
forward();
|
|
@@ -3448,7 +3629,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3448
3629
|
el.addEventListener("keydown", (e) => {
|
|
3449
3630
|
if (e.key === "Enter" || e.key === " ") {
|
|
3450
3631
|
e.preventDefault();
|
|
3451
|
-
node.dispatchEvent(new (0,
|
|
3632
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("click", node, e));
|
|
3452
3633
|
}
|
|
3453
3634
|
});
|
|
3454
3635
|
}
|
|
@@ -3486,7 +3667,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3486
3667
|
this.syncOptionalAttribute(
|
|
3487
3668
|
el,
|
|
3488
3669
|
"href",
|
|
3489
|
-
attrs.href === void 0 ? void 0 :
|
|
3670
|
+
attrs.href === void 0 ? void 0 : _chunkGKSCJ6AFjs.sanitizeUrl.call(void 0, attrs.href)
|
|
3490
3671
|
);
|
|
3491
3672
|
this.syncOptionalAttribute(el, "target", attrs.target);
|
|
3492
3673
|
}
|
|
@@ -3629,7 +3810,14 @@ var Scene = (_class7 = class _Scene {
|
|
|
3629
3810
|
if (el.style.display !== display) el.style.display = display;
|
|
3630
3811
|
}
|
|
3631
3812
|
}
|
|
3632
|
-
this.
|
|
3813
|
+
if (this._phaseTiming) {
|
|
3814
|
+
const projectionStart = performance.now();
|
|
3815
|
+
this.syncContentProjection(node);
|
|
3816
|
+
this._recordPhase("contentProjection", performance.now() - projectionStart);
|
|
3817
|
+
this._recordPhase("a11yNodes", projectionStart - nodeStart);
|
|
3818
|
+
} else {
|
|
3819
|
+
this.syncContentProjection(node);
|
|
3820
|
+
}
|
|
3633
3821
|
for (const child of node.children) this.syncA11y(child);
|
|
3634
3822
|
if (node === this.root) {
|
|
3635
3823
|
for (const overlay of this.overlayRoot.children) this.syncA11y(overlay);
|
|
@@ -3730,7 +3918,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
3730
3918
|
el.addEventListener(
|
|
3731
3919
|
"wheel",
|
|
3732
3920
|
(e2) => {
|
|
3733
|
-
node.dispatchEvent(new (0,
|
|
3921
|
+
node.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)("wheel", node, e2));
|
|
3734
3922
|
},
|
|
3735
3923
|
{ passive: false }
|
|
3736
3924
|
);
|
|
@@ -3743,7 +3931,9 @@ var Scene = (_class7 = class _Scene {
|
|
|
3743
3931
|
this.clearContentGridState(node.id, el);
|
|
3744
3932
|
}
|
|
3745
3933
|
if (projection.grid) {
|
|
3934
|
+
const gridSyncStart = this._phaseTiming ? performance.now() : 0;
|
|
3746
3935
|
this.syncContentGridProjection(node, el, projection, projection.grid);
|
|
3936
|
+
if (this._phaseTiming) this._recordPhase("gridSync", performance.now() - gridSyncStart);
|
|
3747
3937
|
} else if (lines && lines.length > 0) {
|
|
3748
3938
|
const signature = JSON.stringify({
|
|
3749
3939
|
lines,
|
|
@@ -3849,21 +4039,38 @@ var Scene = (_class7 = class _Scene {
|
|
|
3849
4039
|
const signature = `${grid.revision}`;
|
|
3850
4040
|
if (el.dataset.vectoContentGrid !== signature) {
|
|
3851
4041
|
const materializeStart = typeof performance !== "undefined" ? performance.now() : 0;
|
|
3852
|
-
this.clearContentGridState(node.id, el);
|
|
3853
|
-
el.replaceChildren();
|
|
4042
|
+
this.clearContentGridState(node.id, el, false);
|
|
3854
4043
|
const projectionLines = _nullishCoalesce(projection.lines, () => ( []));
|
|
4044
|
+
const selectionLine = this.contentGridSelectionLine(el);
|
|
4045
|
+
let rebuiltSelectionLine = false;
|
|
4046
|
+
const existingLines = el.children;
|
|
3855
4047
|
for (let lineIndex = 0; lineIndex < grid.lines.length; lineIndex++) {
|
|
3856
4048
|
const gridLine = grid.lines[lineIndex];
|
|
3857
4049
|
const projectedLine = projectionLines[lineIndex];
|
|
3858
|
-
const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
3859
|
-
const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
3860
|
-
const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
4050
|
+
const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _108 => _108.lineHeight]), () => ( grid.lineHeight));
|
|
4051
|
+
const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _109 => _109.baseline]), () => ( grid.baseline));
|
|
4052
|
+
const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _110 => _110.font]), () => ( grid.font));
|
|
4053
|
+
const lineSignature = contentGridLineSignature(
|
|
4054
|
+
grid,
|
|
4055
|
+
gridLine,
|
|
4056
|
+
projectedLine,
|
|
4057
|
+
lineHeight,
|
|
4058
|
+
baseline,
|
|
4059
|
+
lineFont,
|
|
4060
|
+
lineIndex === 0
|
|
4061
|
+
);
|
|
4062
|
+
const reusable = existingLines[lineIndex];
|
|
4063
|
+
if (reusable !== void 0 && reusable.dataset.vectoGridLineSig === lineSignature && reusable.dataset.vectoGridLine === `${lineIndex}`) {
|
|
4064
|
+
continue;
|
|
4065
|
+
}
|
|
4066
|
+
if (selectionLine !== null && selectionLine === lineIndex) rebuiltSelectionLine = true;
|
|
3861
4067
|
const lineElement = document.createElement("span");
|
|
4068
|
+
lineElement.dataset.vectoGridLineSig = lineSignature;
|
|
3862
4069
|
lineElement.dir = "ltr";
|
|
3863
4070
|
lineElement.dataset.vectoGridLine = `${lineIndex}`;
|
|
3864
4071
|
lineElement.style.position = "absolute";
|
|
3865
|
-
lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
3866
|
-
lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess',
|
|
4072
|
+
lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _111 => _111.x]), () => ( 0))}px`;
|
|
4073
|
+
lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _112 => _112.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _text.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
|
|
3867
4074
|
lineElement.style.width = `${gridLine.width}px`;
|
|
3868
4075
|
lineElement.style.height = `${lineHeight}px`;
|
|
3869
4076
|
lineElement.style.whiteSpace = "pre";
|
|
@@ -3900,6 +4107,8 @@ var Scene = (_class7 = class _Scene {
|
|
|
3900
4107
|
cellElement.style.font = lineFont;
|
|
3901
4108
|
cellElement.style.lineHeight = `${lineHeight}px`;
|
|
3902
4109
|
cellElement.style.transformOrigin = "0 50%";
|
|
4110
|
+
cellElement.dataset.vectoGridFont = lineFont;
|
|
4111
|
+
cellElement.dataset.vectoGridLineHeight = `${lineHeight}px`;
|
|
3903
4112
|
lineElement.appendChild(cellElement);
|
|
3904
4113
|
logicalX += cell.advance;
|
|
3905
4114
|
}
|
|
@@ -3923,13 +4132,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
3923
4132
|
lineElement.appendChild(marker);
|
|
3924
4133
|
}
|
|
3925
4134
|
}
|
|
3926
|
-
el.
|
|
4135
|
+
const occupant = el.children[lineIndex];
|
|
4136
|
+
if (occupant) el.replaceChild(lineElement, occupant);
|
|
4137
|
+
else el.appendChild(lineElement);
|
|
4138
|
+
}
|
|
4139
|
+
while (el.children.length > grid.lines.length) {
|
|
4140
|
+
if (selectionLine !== null && selectionLine >= grid.lines.length) {
|
|
4141
|
+
rebuiltSelectionLine = true;
|
|
4142
|
+
}
|
|
4143
|
+
_optionalChain([el, 'access', _113 => _113.lastElementChild, 'optionalAccess', _114 => _114.remove, 'call', _115 => _115()]);
|
|
3927
4144
|
}
|
|
4145
|
+
if (rebuiltSelectionLine) this.releaseContentSelectionForRebuild(el);
|
|
3928
4146
|
el.dataset.vectoProjectionLines = signature;
|
|
3929
4147
|
el.dataset.vectoContentGrid = signature;
|
|
3930
4148
|
el.dataset.vectoGridCarriers = `${el.querySelectorAll("[data-vecto-grid-cell]").length}`;
|
|
3931
4149
|
if (typeof performance !== "undefined") {
|
|
3932
|
-
|
|
4150
|
+
const materializeMs = performance.now() - materializeStart;
|
|
4151
|
+
el.dataset.vectoGridMaterializeMs = `${materializeMs}`;
|
|
4152
|
+
if (this._phaseTiming) this._recordPhase("gridMaterialize", materializeMs);
|
|
3933
4153
|
}
|
|
3934
4154
|
delete el.dataset.vectoGridCalibration;
|
|
3935
4155
|
delete el.dataset.vectoGridReady;
|
|
@@ -3937,7 +4157,11 @@ var Scene = (_class7 = class _Scene {
|
|
|
3937
4157
|
const pageScaleX = this.getContentMetricScaleX();
|
|
3938
4158
|
const calibrationKey = `${signature}:${this.contentFontEpoch}:${pageScaleX.toFixed(4)}`;
|
|
3939
4159
|
if (el.dataset.vectoGridCalibration !== calibrationKey) {
|
|
4160
|
+
const calibStart = this._phaseTiming ? performance.now() : 0;
|
|
3940
4161
|
this.scheduleContentGridCalibration(node.id, el, calibrationKey, pageScaleX);
|
|
4162
|
+
if (this._phaseTiming) {
|
|
4163
|
+
this._recordPhase("gridCalibrateSchedule", performance.now() - calibStart);
|
|
4164
|
+
}
|
|
3941
4165
|
}
|
|
3942
4166
|
}
|
|
3943
4167
|
getContentMetricScaleX() {
|
|
@@ -3955,11 +4179,32 @@ var Scene = (_class7 = class _Scene {
|
|
|
3955
4179
|
scheduleContentGridCalibration(entityId, el, calibrationKey, pageScaleX) {
|
|
3956
4180
|
if (typeof requestAnimationFrame !== "function") return;
|
|
3957
4181
|
if (el.dataset.vectoGridCalibrationPending === calibrationKey) return;
|
|
4182
|
+
const stamp = `${this.contentFontEpoch}:${pageScaleX.toFixed(4)}`;
|
|
4183
|
+
if (this.contentGridCalibrationStamp !== stamp) {
|
|
4184
|
+
this.contentGridCalibrationStamp = stamp;
|
|
4185
|
+
this.contentGridCalibrationGeneration++;
|
|
4186
|
+
}
|
|
4187
|
+
const generation = `${this.contentGridCalibrationGeneration}`;
|
|
4188
|
+
const pendingCells = el.querySelectorAll(
|
|
4189
|
+
`[data-vecto-grid-cell]:not([data-vecto-grid-calib="${generation}"])`
|
|
4190
|
+
);
|
|
4191
|
+
if (pendingCells.length === 0) {
|
|
4192
|
+
el.dataset.vectoGridCalibrationSamples = "0";
|
|
4193
|
+
delete el.dataset.vectoGridCalibrationPending;
|
|
4194
|
+
const readyFrame = requestAnimationFrame(() => {
|
|
4195
|
+
this.contentGridCalibrationFrames.delete(entityId);
|
|
4196
|
+
if (!el.isConnected) return;
|
|
4197
|
+
el.dataset.vectoGridCalibration = calibrationKey;
|
|
4198
|
+
el.dataset.vectoGridReady = "true";
|
|
4199
|
+
});
|
|
4200
|
+
this.contentGridCalibrationFrames.set(entityId, readyFrame);
|
|
4201
|
+
return;
|
|
4202
|
+
}
|
|
3958
4203
|
const previous = this.contentGridCalibrationFrames.get(entityId);
|
|
3959
4204
|
if (previous !== void 0 && typeof cancelAnimationFrame === "function") {
|
|
3960
4205
|
cancelAnimationFrame(previous);
|
|
3961
4206
|
}
|
|
3962
|
-
_optionalChain([this, 'access',
|
|
4207
|
+
_optionalChain([this, 'access', _116 => _116.contentGridCalibrationProbes, 'access', _117 => _117.get, 'call', _118 => _118(entityId), 'optionalAccess', _119 => _119.remove, 'call', _120 => _120()]);
|
|
3963
4208
|
this.contentGridCalibrationProbes.delete(entityId);
|
|
3964
4209
|
const calibrationStart = typeof performance !== "undefined" ? performance.now() : 0;
|
|
3965
4210
|
const probe = document.createElement("div");
|
|
@@ -3985,18 +4230,22 @@ var Scene = (_class7 = class _Scene {
|
|
|
3985
4230
|
probe.append(probeOrigin, probeX);
|
|
3986
4231
|
const measurements = [];
|
|
3987
4232
|
const measurementsByKey = /* @__PURE__ */ new Map();
|
|
3988
|
-
|
|
4233
|
+
const scanStart = this._phaseTiming ? performance.now() : 0;
|
|
4234
|
+
for (const target of pendingCells) {
|
|
3989
4235
|
const sourceLength = Number(_nullishCoalesce(target.dataset.vectoGridSourceLength, () => ( 0)));
|
|
3990
4236
|
const targetWidth = Number(_nullishCoalesce(target.dataset.vectoGridAdvance, () => ( 0)));
|
|
3991
|
-
if (sourceLength <= 0 || targetWidth <= 0)
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4237
|
+
if (sourceLength <= 0 || targetWidth <= 0) {
|
|
4238
|
+
target.dataset.vectoGridCalib = generation;
|
|
4239
|
+
continue;
|
|
4240
|
+
}
|
|
4241
|
+
const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _121 => _121.textContent, 'optionalAccess', _122 => _122.slice, 'call', _123 => _123(0, sourceLength)]), () => ( ""));
|
|
4242
|
+
if (!sourceText) {
|
|
4243
|
+
target.dataset.vectoGridCalib = generation;
|
|
4244
|
+
continue;
|
|
4245
|
+
}
|
|
4246
|
+
const cellFont = _nullishCoalesce(target.dataset.vectoGridFont, () => ( ""));
|
|
4247
|
+
const cellLineHeight = _nullishCoalesce(target.dataset.vectoGridLineHeight, () => ( ""));
|
|
4248
|
+
const measurementKey = JSON.stringify([cellFont, cellLineHeight, targetWidth, sourceText]);
|
|
4000
4249
|
const shared = measurementsByKey.get(measurementKey);
|
|
4001
4250
|
if (shared) {
|
|
4002
4251
|
shared.targets.push(target);
|
|
@@ -4008,8 +4257,8 @@ var Scene = (_class7 = class _Scene {
|
|
|
4008
4257
|
carrier.style.left = "0";
|
|
4009
4258
|
carrier.style.top = "0";
|
|
4010
4259
|
carrier.style.whiteSpace = "pre";
|
|
4011
|
-
carrier.style.font =
|
|
4012
|
-
carrier.style.lineHeight =
|
|
4260
|
+
carrier.style.font = cellFont;
|
|
4261
|
+
carrier.style.lineHeight = cellLineHeight;
|
|
4013
4262
|
carrier.style.fontVariantLigatures = "none";
|
|
4014
4263
|
carrier.style.fontKerning = "none";
|
|
4015
4264
|
const source = document.createTextNode(sourceText);
|
|
@@ -4024,7 +4273,17 @@ var Scene = (_class7 = class _Scene {
|
|
|
4024
4273
|
measurements.push(measurement);
|
|
4025
4274
|
measurementsByKey.set(measurementKey, measurement);
|
|
4026
4275
|
}
|
|
4276
|
+
if (this._phaseTiming) this._recordPhase("calibScan", performance.now() - scanStart);
|
|
4277
|
+
if (measurements.length === 0) {
|
|
4278
|
+
el.dataset.vectoGridCalibration = calibrationKey;
|
|
4279
|
+
el.dataset.vectoGridReady = "true";
|
|
4280
|
+
el.dataset.vectoGridCalibrationSamples = "0";
|
|
4281
|
+
delete el.dataset.vectoGridCalibrationPending;
|
|
4282
|
+
return;
|
|
4283
|
+
}
|
|
4284
|
+
const appendStart = this._phaseTiming ? performance.now() : 0;
|
|
4027
4285
|
(_nullishCoalesce(_nullishCoalesce(this.a11yRoot, () => ( document.body)), () => ( document.documentElement))).appendChild(probe);
|
|
4286
|
+
if (this._phaseTiming) this._recordPhase("calibProbeBuild", performance.now() - appendStart);
|
|
4028
4287
|
el.dataset.vectoGridCalibrationSamples = `${measurements.length}`;
|
|
4029
4288
|
this.contentGridCalibrationProbes.set(entityId, probe);
|
|
4030
4289
|
el.dataset.vectoGridCalibrationPending = calibrationKey;
|
|
@@ -4068,6 +4327,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4068
4327
|
}
|
|
4069
4328
|
for (const { element, scale } of updates) {
|
|
4070
4329
|
element.style.transform = Math.abs(scale - 1) <= 1e-3 ? "" : `scaleX(${scale})`;
|
|
4330
|
+
element.dataset.vectoGridCalib = generation;
|
|
4071
4331
|
}
|
|
4072
4332
|
el.dataset.vectoGridCalibration = calibrationKey;
|
|
4073
4333
|
el.dataset.vectoGridReady = "true";
|
|
@@ -4189,12 +4449,12 @@ var Scene = (_class7 = class _Scene {
|
|
|
4189
4449
|
syncOverlayGeometry() {
|
|
4190
4450
|
const parent = this.canvas.parentElement;
|
|
4191
4451
|
if (!parent) return;
|
|
4192
|
-
const canvasRect = _optionalChain([this, 'access',
|
|
4193
|
-
const parentRect = _optionalChain([parent, 'access',
|
|
4194
|
-
const cssWidth = _optionalChain([canvasRect, 'optionalAccess',
|
|
4195
|
-
const cssHeight = _optionalChain([canvasRect, 'optionalAccess',
|
|
4196
|
-
const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess',
|
|
4197
|
-
const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess',
|
|
4452
|
+
const canvasRect = _optionalChain([this, 'access', _124 => _124.canvas, 'access', _125 => _125.getBoundingClientRect, 'optionalCall', _126 => _126()]);
|
|
4453
|
+
const parentRect = _optionalChain([parent, 'access', _127 => _127.getBoundingClientRect, 'optionalCall', _128 => _128()]);
|
|
4454
|
+
const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _129 => _129.width]) || this.canvas.clientWidth || this.width;
|
|
4455
|
+
const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _130 => _130.height]) || this.canvas.clientHeight || this.height;
|
|
4456
|
+
const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _131 => _131.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _132 => _132.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
|
|
4457
|
+
const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _133 => _133.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _134 => _134.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
|
|
4198
4458
|
const scaleX = this.width > 0 ? cssWidth / this.width : 1;
|
|
4199
4459
|
const scaleY = this.height > 0 ? cssHeight / this.height : 1;
|
|
4200
4460
|
const prev = this._overlayGeometry;
|
|
@@ -4333,7 +4593,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4333
4593
|
* (and {@link respectReducedMotion} is on). `0` means uncapped.
|
|
4334
4594
|
*/
|
|
4335
4595
|
effectiveMaxFPS() {
|
|
4336
|
-
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access',
|
|
4596
|
+
const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _135 => _135.reducedMotionQuery, 'optionalAccess', _136 => _136.matches]);
|
|
4337
4597
|
if (reduced)
|
|
4338
4598
|
return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
|
|
4339
4599
|
return this.maxFPS;
|
|
@@ -4373,7 +4633,9 @@ var Scene = (_class7 = class _Scene {
|
|
|
4373
4633
|
}
|
|
4374
4634
|
this._lastRenderTick = time;
|
|
4375
4635
|
this._lastDt = dt;
|
|
4636
|
+
const phaseClock = this._phaseTiming ? performance.now() : 0;
|
|
4376
4637
|
this.render(this.renderer, dt, time);
|
|
4638
|
+
if (this._phaseTiming) this._recordPhase("render", performance.now() - phaseClock);
|
|
4377
4639
|
this._lastFrameMs = (typeof performance !== "undefined" ? performance.now() : time) - now;
|
|
4378
4640
|
this._renderedFrames++;
|
|
4379
4641
|
const hasActiveAnimation = this.frameHadAnimation;
|
|
@@ -4383,9 +4645,13 @@ var Scene = (_class7 = class _Scene {
|
|
|
4383
4645
|
if ((hasInteractive || this.a11yElements.size > 0 || wantsContentSync) && (shouldSyncInterval || this.a11yPendingSyncAfterAnimation)) {
|
|
4384
4646
|
this.lastA11ySync = time;
|
|
4385
4647
|
if (hasInteractive || wantsContentSync) {
|
|
4648
|
+
const t0 = this._phaseTiming ? performance.now() : 0;
|
|
4386
4649
|
this.syncA11y(this.root);
|
|
4650
|
+
if (this._phaseTiming) this._recordPhase("a11ySync", performance.now() - t0);
|
|
4387
4651
|
}
|
|
4652
|
+
const t1 = this._phaseTiming ? performance.now() : 0;
|
|
4388
4653
|
this.enforceA11yDomOrder();
|
|
4654
|
+
if (this._phaseTiming) this._recordPhase("a11yOrder", performance.now() - t1);
|
|
4389
4655
|
this.a11yPendingSyncAfterAnimation = hasActiveAnimation;
|
|
4390
4656
|
} else if (hasActiveAnimation) {
|
|
4391
4657
|
this.a11yPendingSyncAfterAnimation = true;
|
|
@@ -4400,7 +4666,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4400
4666
|
* @param time - Current absolute time in milliseconds (default 0).
|
|
4401
4667
|
*/
|
|
4402
4668
|
render(renderer, dt = 0, time = 0) {
|
|
4403
|
-
if (_optionalChain([renderer, 'access',
|
|
4669
|
+
if (_optionalChain([renderer, 'access', _137 => _137.isContextLost, 'optionalCall', _138 => _138()])) return;
|
|
4404
4670
|
const isMainRenderer = renderer === this.renderer;
|
|
4405
4671
|
if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
|
|
4406
4672
|
const parentStyle = this.canvas.parentElement.style;
|
|
@@ -4526,14 +4792,14 @@ var Scene = (_class7 = class _Scene {
|
|
|
4526
4792
|
}
|
|
4527
4793
|
renderer.clear();
|
|
4528
4794
|
if (isMainRenderer) {
|
|
4529
|
-
_optionalChain([this, 'access',
|
|
4795
|
+
_optionalChain([this, 'access', _139 => _139.pointRenderer, 'optionalAccess', _140 => _140.begin, 'call', _141 => _141()]);
|
|
4530
4796
|
}
|
|
4531
4797
|
const vw = this.width;
|
|
4532
4798
|
const vh = this.height;
|
|
4533
4799
|
let walkHadAnimation = false;
|
|
4534
4800
|
let walkHadInteractive = false;
|
|
4535
4801
|
const runUpdate = (node) => {
|
|
4536
|
-
const overridesUpdate = node.update !==
|
|
4802
|
+
const overridesUpdate = node.update !== _chunkAGP4VLF4js.Entity.prototype.update;
|
|
4537
4803
|
let pending = node.hasPendingAnimations();
|
|
4538
4804
|
if (pending || overridesUpdate) {
|
|
4539
4805
|
node.update(dt, time);
|
|
@@ -4542,7 +4808,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4542
4808
|
if (pending) walkHadAnimation = true;
|
|
4543
4809
|
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
4544
4810
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
4545
|
-
if (overridesUpdate && node.hasPendingAnimations ===
|
|
4811
|
+
if (overridesUpdate && node.hasPendingAnimations === _chunkAGP4VLF4js.Entity.prototype.hasPendingAnimations) {
|
|
4546
4812
|
this._devWarn(
|
|
4547
4813
|
`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.`
|
|
4548
4814
|
);
|
|
@@ -4559,7 +4825,9 @@ var Scene = (_class7 = class _Scene {
|
|
|
4559
4825
|
updateWalk(this.root);
|
|
4560
4826
|
for (const overlay of this.overlayRoot.children) updateWalk(overlay);
|
|
4561
4827
|
}
|
|
4828
|
+
const wasmT0 = this._phaseTiming ? performance.now() : 0;
|
|
4562
4829
|
const wasmWorld = wasmMain ? this._syncWasmStore() : null;
|
|
4830
|
+
if (this._phaseTiming) this._recordPhase("transform", performance.now() - wasmT0);
|
|
4563
4831
|
const wasmSlotEntity = this._slotEntity;
|
|
4564
4832
|
const renderNode = (node, pa, pb, pc, pd, pe, pf, parentOpacity) => {
|
|
4565
4833
|
if (isMainRenderer && !wasmMain) {
|
|
@@ -4689,7 +4957,13 @@ var Scene = (_class7 = class _Scene {
|
|
|
4689
4957
|
);
|
|
4690
4958
|
}
|
|
4691
4959
|
} else {
|
|
4692
|
-
|
|
4960
|
+
if (this._phaseTiming) {
|
|
4961
|
+
const t0 = performance.now();
|
|
4962
|
+
node.render(renderer);
|
|
4963
|
+
this._recordPhase("entityPaint", performance.now() - t0);
|
|
4964
|
+
} else {
|
|
4965
|
+
node.render(renderer);
|
|
4966
|
+
}
|
|
4693
4967
|
}
|
|
4694
4968
|
}
|
|
4695
4969
|
if (node.clipChildren) {
|
|
@@ -4701,20 +4975,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
4701
4975
|
renderer.flush();
|
|
4702
4976
|
renderer.restore();
|
|
4703
4977
|
};
|
|
4978
|
+
const drawT0 = this._phaseTiming ? performance.now() : 0;
|
|
4704
4979
|
renderNode(this.root, 1, 0, 0, 1, 0, 0, 1);
|
|
4705
4980
|
for (const overlay of this.overlayRoot.children) {
|
|
4706
4981
|
renderNode(overlay, 1, 0, 0, 1, 0, 0, 1);
|
|
4707
4982
|
}
|
|
4983
|
+
if (this._phaseTiming) this._recordPhase("drawWalk", performance.now() - drawT0);
|
|
4708
4984
|
if (isMainRenderer) {
|
|
4709
4985
|
this.frameHadAnimation = walkHadAnimation;
|
|
4710
4986
|
this.frameHadInteractive = walkHadInteractive;
|
|
4711
4987
|
this.reconcilePortals();
|
|
4712
4988
|
}
|
|
4989
|
+
const flushT0 = this._phaseTiming ? performance.now() : 0;
|
|
4713
4990
|
renderer.flush();
|
|
4714
4991
|
if (isMainRenderer) {
|
|
4715
|
-
_optionalChain([this, 'access',
|
|
4992
|
+
_optionalChain([this, 'access', _142 => _142.pointRenderer, 'optionalAccess', _143 => _143.flush, 'call', _144 => _144()]);
|
|
4716
4993
|
}
|
|
4717
|
-
_optionalChain([renderer, 'access',
|
|
4994
|
+
_optionalChain([renderer, 'access', _145 => _145.present, 'optionalCall', _146 => _146()]);
|
|
4995
|
+
if (this._phaseTiming) this._recordPhase("flush", performance.now() - flushT0);
|
|
4718
4996
|
if (this._devActive) {
|
|
4719
4997
|
this._devFrameCount++;
|
|
4720
4998
|
this._devRunChecks();
|
|
@@ -4724,7 +5002,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4724
5002
|
* Export the current scene state to a lightweight, flat SVG XML string.
|
|
4725
5003
|
*/
|
|
4726
5004
|
toSVG() {
|
|
4727
|
-
const renderer = new (0,
|
|
5005
|
+
const renderer = new (0, _chunkGKSCJ6AFjs.SVGRenderer)(this.width, this.height);
|
|
4728
5006
|
this.render(renderer, 0, 0);
|
|
4729
5007
|
return renderer.toXMLString();
|
|
4730
5008
|
}
|
|
@@ -4990,6 +5268,41 @@ function intersectBounds(a, b) {
|
|
|
4990
5268
|
function pointInBounds(b, x, y) {
|
|
4991
5269
|
return x >= b.x && x <= b.x + b.width && y >= b.y && y <= b.y + b.height;
|
|
4992
5270
|
}
|
|
5271
|
+
function contentGridLineSignature(grid, line, projected, lineHeight, baseline, font, isFirstLine) {
|
|
5272
|
+
const parts = [
|
|
5273
|
+
// Line box: position, size, and the font that resolves its baseline.
|
|
5274
|
+
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _147 => _147.x]), () => ( 0))}`,
|
|
5275
|
+
`${_nullishCoalesce(_optionalChain([projected, 'optionalAccess', _148 => _148.y]), () => ( ""))}`,
|
|
5276
|
+
`${lineHeight}`,
|
|
5277
|
+
`${baseline}`,
|
|
5278
|
+
font,
|
|
5279
|
+
`${line.width}`,
|
|
5280
|
+
// The trailing hard break belongs to this line and lands in the DOM text.
|
|
5281
|
+
grid.source.slice(line.sourceEnd, line.nextSourceStart),
|
|
5282
|
+
// The basis markers are appended only to line 0, so a line moving to or from
|
|
5283
|
+
// index 0 changes its DOM even when nothing else does.
|
|
5284
|
+
isFirstLine ? "1" : "0"
|
|
5285
|
+
];
|
|
5286
|
+
if (line.cells.length === 0) {
|
|
5287
|
+
parts.push("empty");
|
|
5288
|
+
} else {
|
|
5289
|
+
for (const cell of line.cells) {
|
|
5290
|
+
parts.push(
|
|
5291
|
+
`${cell.sourceStart}`,
|
|
5292
|
+
`${cell.sourceEnd}`,
|
|
5293
|
+
`${cell.x}`,
|
|
5294
|
+
`${cell.advance}`,
|
|
5295
|
+
`${cell.level}`,
|
|
5296
|
+
cell.sourceCaretOffsets.join("."),
|
|
5297
|
+
// Source text, not `cell.glyph`: the carrier holds the original characters
|
|
5298
|
+
// (the shaped glyph is the canvas's business), so a change in shaping alone
|
|
5299
|
+
// must not invalidate a carrier, and a change in source must.
|
|
5300
|
+
grid.source.slice(cell.sourceStart, cell.sourceEnd)
|
|
5301
|
+
);
|
|
5302
|
+
}
|
|
5303
|
+
}
|
|
5304
|
+
return parts.join("");
|
|
5305
|
+
}
|
|
4993
5306
|
|
|
4994
5307
|
// src/components/TextEntity.ts
|
|
4995
5308
|
|
|
@@ -5001,20 +5314,20 @@ function defaultMeasurer() {
|
|
|
5001
5314
|
if (sharedMeasurer === void 0) sharedMeasurer = _layout.createCanvasMeasurer.call(void 0, "sans-serif");
|
|
5002
5315
|
return sharedMeasurer;
|
|
5003
5316
|
}
|
|
5004
|
-
var TextEntity = (_class8 = class extends
|
|
5317
|
+
var TextEntity = (_class8 = class extends _chunkAGP4VLF4js.Entity {
|
|
5005
5318
|
|
|
5006
5319
|
|
|
5007
5320
|
|
|
5008
5321
|
|
|
5009
|
-
|
|
5322
|
+
__init140() {this.nodes = []}
|
|
5010
5323
|
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5324
|
+
__init141() {this.fillStyle = "#94a3b8"}
|
|
5325
|
+
__init142() {this.strokeStyle = null}
|
|
5326
|
+
__init143() {this.hoveredFillStyle = "#ffffff"}
|
|
5327
|
+
__init144() {this.lineWidth = 1}
|
|
5328
|
+
__init145() {this.isHovered = false}
|
|
5016
5329
|
constructor(text, atlas, maxWidth, fontSize = 24) {
|
|
5017
|
-
super();_class8.prototype.
|
|
5330
|
+
super();_class8.prototype.__init140.call(this);_class8.prototype.__init141.call(this);_class8.prototype.__init142.call(this);_class8.prototype.__init143.call(this);_class8.prototype.__init144.call(this);_class8.prototype.__init145.call(this);;
|
|
5018
5331
|
this.text = text;
|
|
5019
5332
|
this.atlas = atlas;
|
|
5020
5333
|
this.fontSize = fontSize;
|
|
@@ -5127,17 +5440,17 @@ var TextEntity = (_class8 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5127
5440
|
}, _class8);
|
|
5128
5441
|
|
|
5129
5442
|
// src/components/GridTextEntity.ts
|
|
5130
|
-
var GridTextEntity = (_class9 = class extends
|
|
5443
|
+
var GridTextEntity = (_class9 = class extends _chunkAGP4VLF4js.Entity {
|
|
5131
5444
|
|
|
5132
|
-
|
|
5133
|
-
|
|
5445
|
+
__init146() {this.fillStyle = "#ffffff"}
|
|
5446
|
+
__init147() {this.grid = []}
|
|
5134
5447
|
// Array of rows
|
|
5135
|
-
|
|
5136
|
-
|
|
5448
|
+
__init148() {this.cols = 0}
|
|
5449
|
+
__init149() {this.rows = 0}
|
|
5137
5450
|
|
|
5138
5451
|
|
|
5139
5452
|
constructor(_atlas, fontSize = 10) {
|
|
5140
|
-
super();_class9.prototype.
|
|
5453
|
+
super();_class9.prototype.__init146.call(this);_class9.prototype.__init147.call(this);_class9.prototype.__init148.call(this);_class9.prototype.__init149.call(this);;
|
|
5141
5454
|
this.fontSize = fontSize;
|
|
5142
5455
|
this.charWidth = fontSize * 1;
|
|
5143
5456
|
this.charHeight = fontSize * 1.1;
|
|
@@ -5146,7 +5459,7 @@ var GridTextEntity = (_class9 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5146
5459
|
updateGrid(ascii) {
|
|
5147
5460
|
this.grid = ascii;
|
|
5148
5461
|
this.rows = ascii.length;
|
|
5149
|
-
this.cols = _optionalChain([ascii, 'access',
|
|
5462
|
+
this.cols = _optionalChain([ascii, 'access', _149 => _149[0], 'optionalAccess', _150 => _150.length]) || 0;
|
|
5150
5463
|
}
|
|
5151
5464
|
isPointInside(_globalX, _globalY) {
|
|
5152
5465
|
return false;
|
|
@@ -5221,7 +5534,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
5221
5534
|
const ey = py - cy;
|
|
5222
5535
|
return ex * ex + ey * ey;
|
|
5223
5536
|
}
|
|
5224
|
-
var SplineEntity = (_class10 = class extends
|
|
5537
|
+
var SplineEntity = (_class10 = class extends _chunkAGP4VLF4js.Entity {
|
|
5225
5538
|
|
|
5226
5539
|
|
|
5227
5540
|
|
|
@@ -5229,23 +5542,23 @@ var SplineEntity = (_class10 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5229
5542
|
|
|
5230
5543
|
|
|
5231
5544
|
|
|
5232
|
-
|
|
5233
|
-
|
|
5545
|
+
__init150() {this.offscreen = null}
|
|
5546
|
+
__init151() {this.baked = false}
|
|
5234
5547
|
/** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
|
|
5235
|
-
|
|
5236
|
-
|
|
5548
|
+
__init152() {this.bakedWidth = 0}
|
|
5549
|
+
__init153() {this.bakedHeight = 0}
|
|
5237
5550
|
/** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
|
|
5238
5551
|
|
|
5239
5552
|
/** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
|
|
5240
|
-
|
|
5553
|
+
__init154() {this.polylines = null}
|
|
5241
5554
|
/**
|
|
5242
5555
|
* When `true`, the renderer draws a rounded-rect outline of the entity's
|
|
5243
5556
|
* local bounds after painting the curves. Useful for drag feedback and
|
|
5244
5557
|
* debugging hit areas. Defaults to `false`.
|
|
5245
5558
|
*/
|
|
5246
|
-
|
|
5559
|
+
__init155() {this.showBounds = false}
|
|
5247
5560
|
constructor(doc, opts = {}) {
|
|
5248
|
-
super();_class10.prototype.
|
|
5561
|
+
super();_class10.prototype.__init150.call(this);_class10.prototype.__init151.call(this);_class10.prototype.__init152.call(this);_class10.prototype.__init153.call(this);_class10.prototype.__init154.call(this);_class10.prototype.__init155.call(this);;
|
|
5249
5562
|
this.doc = doc;
|
|
5250
5563
|
this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
|
|
5251
5564
|
this.cache = _nullishCoalesce(opts.cache, () => ( true));
|
|
@@ -5256,7 +5569,7 @@ var SplineEntity = (_class10 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5256
5569
|
this.width = this.bounds.width;
|
|
5257
5570
|
this.height = this.bounds.height;
|
|
5258
5571
|
const isGradient = (c) => c !== null && !Array.isArray(c);
|
|
5259
|
-
this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access',
|
|
5572
|
+
this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _151 => _151.doc, 'access', _152 => _152.equations, 'optionalAccess', _153 => _153.some, 'call', _154 => _154((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _155 => _155.doc, 'access', _156 => _156.paths, 'optionalAccess', _157 => _157.some, 'call', _158 => _158((p) => isGradient(p.color_rgb))]), () => ( false)));
|
|
5260
5573
|
this.interactive = true;
|
|
5261
5574
|
}
|
|
5262
5575
|
computeBounds() {
|
|
@@ -5496,7 +5809,7 @@ async function loadSpline(url) {
|
|
|
5496
5809
|
}
|
|
5497
5810
|
|
|
5498
5811
|
// src/components/Rect.ts
|
|
5499
|
-
var Rect = class extends
|
|
5812
|
+
var Rect = class extends _chunkAGP4VLF4js.Entity {
|
|
5500
5813
|
|
|
5501
5814
|
|
|
5502
5815
|
|
|
@@ -5545,7 +5858,7 @@ var Rect = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5545
5858
|
};
|
|
5546
5859
|
|
|
5547
5860
|
// src/components/Circle.ts
|
|
5548
|
-
var Circle = class extends
|
|
5861
|
+
var Circle = class extends _chunkAGP4VLF4js.Entity {
|
|
5549
5862
|
|
|
5550
5863
|
|
|
5551
5864
|
|
|
@@ -5605,7 +5918,7 @@ var Circle = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5605
5918
|
};
|
|
5606
5919
|
|
|
5607
5920
|
// src/components/Group.ts
|
|
5608
|
-
var Group = class extends
|
|
5921
|
+
var Group = class extends _chunkAGP4VLF4js.Entity {
|
|
5609
5922
|
constructor(...children) {
|
|
5610
5923
|
super();
|
|
5611
5924
|
if (children.length > 0) this.add(...children);
|
|
@@ -5624,21 +5937,21 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
5624
5937
|
|
|
5625
5938
|
|
|
5626
5939
|
// src/tree/DOMPortalEntity.ts
|
|
5627
|
-
var DOMPortalEntity = (_class11 = class extends
|
|
5940
|
+
var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
|
|
5628
5941
|
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5942
|
+
__init156() {this.isDOMPortal = true}
|
|
5943
|
+
__init157() {this.domListeners = []}
|
|
5944
|
+
__init158() {this.resizeObserver = null}
|
|
5945
|
+
__init159() {this.domBound = false}
|
|
5946
|
+
__init160() {this.cachedWidth = 100}
|
|
5947
|
+
__init161() {this.cachedHeight = 100}
|
|
5948
|
+
__init162() {this.lastWidth = ""}
|
|
5949
|
+
__init163() {this.lastHeight = ""}
|
|
5950
|
+
__init164() {this.lastTransform = ""}
|
|
5951
|
+
__init165() {this.lastZIndex = ""}
|
|
5952
|
+
__init166() {this.lastOpacity = ""}
|
|
5640
5953
|
constructor(domElement, width, height, id) {
|
|
5641
|
-
super(id);_class11.prototype.
|
|
5954
|
+
super(id);_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);_class11.prototype.__init163.call(this);_class11.prototype.__init164.call(this);_class11.prototype.__init165.call(this);_class11.prototype.__init166.call(this);;
|
|
5642
5955
|
this.domElement = domElement;
|
|
5643
5956
|
this.width = _nullishCoalesce(width, () => ( 0));
|
|
5644
5957
|
this.height = _nullishCoalesce(height, () => ( 0));
|
|
@@ -5680,7 +5993,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5680
5993
|
];
|
|
5681
5994
|
for (const type of events) {
|
|
5682
5995
|
const handler = (e) => {
|
|
5683
|
-
this.dispatchEvent(new (0,
|
|
5996
|
+
this.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)(type, this, e));
|
|
5684
5997
|
};
|
|
5685
5998
|
this.domElement.addEventListener(type, handler);
|
|
5686
5999
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -5691,7 +6004,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5691
6004
|
];
|
|
5692
6005
|
for (const { native, vecto } of hoverEvents) {
|
|
5693
6006
|
const handler = (e) => {
|
|
5694
|
-
this.dispatchEvent(new (0,
|
|
6007
|
+
this.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)(vecto, this, e, false));
|
|
5695
6008
|
};
|
|
5696
6009
|
this.domElement.addEventListener(native, handler);
|
|
5697
6010
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -5699,7 +6012,7 @@ var DOMPortalEntity = (_class11 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5699
6012
|
const focusEvents = ["focus", "blur"];
|
|
5700
6013
|
for (const type of focusEvents) {
|
|
5701
6014
|
const handler = (e) => {
|
|
5702
|
-
this.dispatchEvent(new (0,
|
|
6015
|
+
this.dispatchEvent(new (0, _chunkAGP4VLF4js.VectoJSEvent)(type, this, e, true));
|
|
5703
6016
|
};
|
|
5704
6017
|
this.domElement.addEventListener(type, handler, true);
|
|
5705
6018
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -5750,8 +6063,9 @@ var DOMPortalEntity = (_class11 = class extends _chunkIA3KW4CGjs.Entity {
|
|
|
5750
6063
|
}, _class11);
|
|
5751
6064
|
|
|
5752
6065
|
// src/index.ts
|
|
5753
|
-
Scene.registerWebGLPointRendererCreator(
|
|
5754
|
-
Scene.registerWebGPUParticleSystemManager(
|
|
6066
|
+
Scene.registerWebGLPointRendererCreator(_chunkGKSCJ6AFjs.createWebGLPointRenderer);
|
|
6067
|
+
Scene.registerWebGPUParticleSystemManager(_chunkGKSCJ6AFjs.WebGPUParticleSystemManager);
|
|
6068
|
+
|
|
5755
6069
|
|
|
5756
6070
|
|
|
5757
6071
|
|
|
@@ -5786,4 +6100,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkL4SWVP2Hjs.WebGPUParticleSystemM
|
|
|
5786
6100
|
|
|
5787
6101
|
|
|
5788
6102
|
|
|
5789
|
-
exports.CanvasRenderer =
|
|
6103
|
+
exports.CanvasRenderer = _chunkGKSCJ6AFjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkAGP4VLF4js.Entity; exports.GlyphRasterAtlas = _chunkGKSCJ6AFjs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkAGP4VLF4js.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 = _chunkAGP4VLF4js.SVGEntity; exports.SVGRenderer = _chunkGKSCJ6AFjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkGKSCJ6AFjs.TextRasterCache; exports.VectoJSEvent = _chunkAGP4VLF4js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkGKSCJ6AFjs.WebGPUParticleSystemManager; exports.createWebGLPointRenderer = _chunkGKSCJ6AFjs.createWebGLPointRenderer; exports.isSafeUrl = _chunkGKSCJ6AFjs.isSafeUrl; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkGKSCJ6AFjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkGKSCJ6AFjs.sanitizeUrl;
|