@vectojs/core 1.35.3 → 1.36.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-CHDJEHML.mjs → chunk-QJC4VZ2E.mjs} +2 -2
- package/dist/{chunk-XHPUCU5P.js → chunk-XE6K7T5S.js} +2 -2
- package/dist/index.js +167 -156
- package/dist/index.mjs +17 -6
- package/dist/text/MSDFTextEntity.d.ts +2 -2
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/ComputeParticleEntity.d.ts +2 -2
- package/dist/tree/Scene.d.ts +29 -7
- package/package.json +1 -1
|
@@ -1241,8 +1241,8 @@ var MSDFTextEntity = class extends Entity {
|
|
|
1241
1241
|
*
|
|
1242
1242
|
* Measured on Chromium and Firefox (2026-07-31) with a 600 ms atlas: the
|
|
1243
1243
|
* scene's own rAF loop never uploaded a decoded atlas in EITHER render mode.
|
|
1244
|
-
* `onDemand` skips idle frames outright; `always` throttles to
|
|
1245
|
-
* idle, so whether it recovers is down to whether a throttled tick happens to
|
|
1244
|
+
* `onDemand` skips idle frames outright; `always` throttles to the idle FPS
|
|
1245
|
+
* floor when idle, so whether it recovers is down to whether a throttled tick happens to
|
|
1246
1246
|
* land after the decode — Chromium got one, Firefox did not. Neither is a
|
|
1247
1247
|
* mechanism, which is why this listener exists rather than relying on the
|
|
1248
1248
|
* frame loop to come back around.
|
|
@@ -1243,8 +1243,8 @@ var MSDFTextEntity = (_class3 = class extends Entity {
|
|
|
1243
1243
|
*
|
|
1244
1244
|
* Measured on Chromium and Firefox (2026-07-31) with a 600 ms atlas: the
|
|
1245
1245
|
* scene's own rAF loop never uploaded a decoded atlas in EITHER render mode.
|
|
1246
|
-
* `onDemand` skips idle frames outright; `always` throttles to
|
|
1247
|
-
* idle, so whether it recovers is down to whether a throttled tick happens to
|
|
1246
|
+
* `onDemand` skips idle frames outright; `always` throttles to the idle FPS
|
|
1247
|
+
* floor when idle, so whether it recovers is down to whether a throttled tick happens to
|
|
1248
1248
|
* land after the decode — Chromium got one, Firefox did not. Neither is a
|
|
1249
1249
|
* mechanism, which is why this listener exists rather than relying on the
|
|
1250
1250
|
* frame loop to come back around.
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var _chunkMO24PVGTjs = require('./chunk-MO24PVGT.js');
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
var
|
|
22
|
+
var _chunkXE6K7T5Sjs = require('./chunk-XE6K7T5S.js');
|
|
23
23
|
|
|
24
24
|
// src/tree/ComputeParticleEntity.ts
|
|
25
25
|
var PARTICLE_STRIDE_FLOATS = 8;
|
|
@@ -31,7 +31,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
|
|
|
31
31
|
var PARTICLE_OFFSET_ORIGIN_Y = 5;
|
|
32
32
|
var PARTICLE_OFFSET_SIZE = 6;
|
|
33
33
|
var PARTICLE_OFFSET_LIFE = 7;
|
|
34
|
-
var ComputeParticleEntity = (_class = class extends
|
|
34
|
+
var ComputeParticleEntity = (_class = class extends _chunkXE6K7T5Sjs.Entity {
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
|
|
@@ -179,8 +179,8 @@ var ComputeParticleEntity = (_class = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
179
179
|
* render-tree walk, but this entity is still a normal tree member that
|
|
180
180
|
* walk visits — without this override, the base `Entity.hasPendingAnimations()`
|
|
181
181
|
* (always `false`) is what Scene sees, so `renderMode: 'always'`'s idle
|
|
182
|
-
* auto-throttle drops the WHOLE scene to
|
|
183
|
-
* the tree is animating, even while thousands of particles are visibly
|
|
182
|
+
* auto-throttle drops the WHOLE scene to the idle FPS floor the instant
|
|
183
|
+
* nothing else in the tree is animating, even while thousands of particles are visibly
|
|
184
184
|
* drifting or spring-settling. A spring+damping system asymptotically
|
|
185
185
|
* approaches zero velocity but never reaches it exactly, so this checks
|
|
186
186
|
* against a small epsilon rather than `!== 0` — otherwise this would
|
|
@@ -3436,6 +3436,7 @@ var SCENE_OPTION_KEYS = [
|
|
|
3436
3436
|
"contentSemanticMargin",
|
|
3437
3437
|
"debugA11y",
|
|
3438
3438
|
"disableWindowResize",
|
|
3439
|
+
"idleFPS",
|
|
3439
3440
|
"maxDPR",
|
|
3440
3441
|
"maxFPS",
|
|
3441
3442
|
"particleBackend",
|
|
@@ -3864,29 +3865,38 @@ var Scene = (_class15 = class _Scene {
|
|
|
3864
3865
|
if (value) this._dirty.mark(void 0, this.currentFrame);
|
|
3865
3866
|
else this._dirty.clear();
|
|
3866
3867
|
}
|
|
3867
|
-
/**
|
|
3868
|
+
/**
|
|
3869
|
+
* Whether to throttle the `'always'` loop when the scene is static to save
|
|
3870
|
+
* power. The idle floor is {@link Scene.idleFPS} (default 60).
|
|
3871
|
+
*/
|
|
3868
3872
|
__init90() {this.autoThrottle = true}
|
|
3873
|
+
/**
|
|
3874
|
+
* Frame-rate floor for an idle `'always'` scene when {@link Scene.autoThrottle}
|
|
3875
|
+
* is on. Default `60`. Set `2` for the legacy aggressive idle sleep, `0` to
|
|
3876
|
+
* keep the scene's `maxFPS` cadence while idle.
|
|
3877
|
+
*/
|
|
3878
|
+
__init91() {this.idleFPS = 60}
|
|
3869
3879
|
// --- Frame telemetry (read via `frameStats`) ---------------------------
|
|
3870
3880
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
3871
|
-
|
|
3881
|
+
__init92() {this._lastFrameMs = 0}
|
|
3872
3882
|
/** Rolling exponential average of rendered-frame intervals, in ms. */
|
|
3873
|
-
|
|
3883
|
+
__init93() {this._avgFrameIntervalMs = 0}
|
|
3874
3884
|
/** dt (ms) handed to the last rendered frame. */
|
|
3875
|
-
|
|
3885
|
+
__init94() {this._lastDt = 0}
|
|
3876
3886
|
/** Count of frames actually rendered since the loop started. */
|
|
3877
|
-
|
|
3887
|
+
__init95() {this._renderedFrames = 0}
|
|
3878
3888
|
/** Count of rAF ticks skipped (idle / capped) since the loop started. */
|
|
3879
|
-
|
|
3889
|
+
__init96() {this._skippedFrames = 0}
|
|
3880
3890
|
/** `time` of the previous *rendered* frame, for interval measurement. */
|
|
3881
|
-
|
|
3891
|
+
__init97() {this._lastRenderTick = 0}
|
|
3882
3892
|
/**
|
|
3883
3893
|
* Frame-rate cap (power saving). `0` = uncapped (native refresh). When set,
|
|
3884
3894
|
* the loop renders at most `maxFPS` times per second; animations still run,
|
|
3885
3895
|
* just less often. See {@link SceneOptions.maxFPS}.
|
|
3886
3896
|
*/
|
|
3887
|
-
|
|
3897
|
+
__init98() {this.maxFPS = 60}
|
|
3888
3898
|
/** Whether the OS prefers-reduced-motion setting auto-caps the loop. */
|
|
3889
|
-
|
|
3899
|
+
__init99() {this.respectReducedMotion = true}
|
|
3890
3900
|
/**
|
|
3891
3901
|
* Reading direction for accessibility tab/traversal order (`'ltr'` default,
|
|
3892
3902
|
* `'rtl'`). Controls the inline sort within a visual row in
|
|
@@ -3902,15 +3912,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
3902
3912
|
this.a11yOrder.markNeedsReorder();
|
|
3903
3913
|
}
|
|
3904
3914
|
}
|
|
3905
|
-
|
|
3915
|
+
__init100() {this._readingDirection = "ltr"}
|
|
3906
3916
|
/** Cached media-query list; `.matches` is read live each frame. */
|
|
3907
|
-
|
|
3917
|
+
__init101() {this.reducedMotionQuery = null}
|
|
3908
3918
|
/** Cached `(forced-colors: active)` query (Windows High Contrast etc.). A
|
|
3909
3919
|
* canvas gets NO automatic forced-colors treatment from the browser (it's
|
|
3910
3920
|
* opaque pixels), so components must read {@link forcedColors} and repaint
|
|
3911
3921
|
* with system colors themselves; a change listener repaints idle scenes. */
|
|
3912
|
-
|
|
3913
|
-
|
|
3922
|
+
__init102() {this.forcedColorsQuery = null}
|
|
3923
|
+
__init103() {this.forcedColorsChangeHandler = null}
|
|
3914
3924
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
3915
3925
|
get prefersReducedMotion() {
|
|
3916
3926
|
return this.respectReducedMotion && !!_optionalChain([this, 'access', _93 => _93.reducedMotionQuery, 'optionalAccess', _94 => _94.matches]);
|
|
@@ -3931,19 +3941,19 @@ var Scene = (_class15 = class _Scene {
|
|
|
3931
3941
|
* Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
|
|
3932
3942
|
* frame. See {@link SceneOptions.a11ySyncInterval}.
|
|
3933
3943
|
*/
|
|
3934
|
-
|
|
3944
|
+
__init104() {this.a11ySyncInterval = 0}
|
|
3935
3945
|
/** Timestamp of the last a11y sync, for throttling. */
|
|
3936
|
-
|
|
3946
|
+
__init105() {this.lastA11ySync = -Infinity}
|
|
3937
3947
|
/** True if we skipped an a11y sync during animation and need to sync when at rest. */
|
|
3938
|
-
|
|
3948
|
+
__init106() {this.a11yPendingSyncAfterAnimation = false}
|
|
3939
3949
|
// A11y / Automation Layer. `null` in non-DOM (SSR/Node) environments — the
|
|
3940
3950
|
// whole projection degrades to a no-op so the engine's logic stays usable
|
|
3941
3951
|
// server-side (e.g. headless layout / vector export) without jsdom.
|
|
3942
3952
|
|
|
3943
|
-
|
|
3953
|
+
__init107() {this.a11yElements = /* @__PURE__ */ new Map()}
|
|
3944
3954
|
// --- domain: content-projection — projected DOM, sync state, calibration, selection ---
|
|
3945
3955
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
3946
|
-
|
|
3956
|
+
__init108() {this.contentElements = /* @__PURE__ */ new Map()}
|
|
3947
3957
|
/**
|
|
3948
3958
|
* What the last completed content-projection sync was built from, per entity.
|
|
3949
3959
|
*
|
|
@@ -3952,9 +3962,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
3952
3962
|
* build. Only populated for entities that opt in via
|
|
3953
3963
|
* {@link Entity.getContentEpoch}. (carryctx CTX-0199)
|
|
3954
3964
|
*/
|
|
3955
|
-
|
|
3965
|
+
__init109() {this.contentSyncState = /* @__PURE__ */ new Map()}
|
|
3956
3966
|
/** Invalidates grid font calibration after browser font availability changes. */
|
|
3957
|
-
|
|
3967
|
+
__init110() {this.contentFontEpoch = 0}
|
|
3958
3968
|
/**
|
|
3959
3969
|
* Bumped whenever the viewport itself changes shape, which re-tiers blocks
|
|
3960
3970
|
* without moving any of them.
|
|
@@ -3967,7 +3977,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
3967
3977
|
* carriers it no longer needs. Scrolling needs no such epoch: it moves the root,
|
|
3968
3978
|
* so every block's parent world transform changes and the check fails honestly.
|
|
3969
3979
|
*/
|
|
3970
|
-
|
|
3980
|
+
__init111() {this.contentViewportEpoch = 0}
|
|
3971
3981
|
/**
|
|
3972
3982
|
* One-entry memo for a parent's world transform, held as scalars.
|
|
3973
3983
|
*
|
|
@@ -3982,16 +3992,16 @@ var Scene = (_class15 = class _Scene {
|
|
|
3982
3992
|
* sync, so a memo can never survive into a frame in which the parent has
|
|
3983
3993
|
* moved.
|
|
3984
3994
|
*/
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3995
|
+
__init112() {this._pwNode = null}
|
|
3996
|
+
__init113() {this._pwSerial = -1}
|
|
3997
|
+
__init114() {this._pwa = 1}
|
|
3998
|
+
__init115() {this._pwb = 0}
|
|
3999
|
+
__init116() {this._pwc = 0}
|
|
4000
|
+
__init117() {this._pwd = 1}
|
|
4001
|
+
__init118() {this._pwe = 0}
|
|
4002
|
+
__init119() {this._pwf = 0}
|
|
3993
4003
|
/** Incremented once per top-level `syncA11y`, invalidating `_pwNode`. */
|
|
3994
|
-
|
|
4004
|
+
__init120() {this._syncSerial = 0}
|
|
3995
4005
|
/**
|
|
3996
4006
|
* Disables the settled-walk fast path in {@link syncContentProjection}.
|
|
3997
4007
|
*
|
|
@@ -4003,38 +4013,38 @@ var Scene = (_class15 = class _Scene {
|
|
|
4003
4013
|
* Not part of the public API and not documented as an option: turning it on only
|
|
4004
4014
|
* makes a settled document slower, never more correct.
|
|
4005
4015
|
*/
|
|
4006
|
-
|
|
4016
|
+
__init121() {this.disableSettledFastPath = false}
|
|
4007
4017
|
/** Cached Canvas-to-client scale for the current font/viewport epoch. */
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4018
|
+
__init122() {this.contentMetricScaleEpoch = -1}
|
|
4019
|
+
__init123() {this.contentMetricScaleX = 1}
|
|
4020
|
+
__init124() {this.contentProjectionEnabled = true}
|
|
4011
4021
|
// Virtualization margin (px) for the content-projection CARRIER band;
|
|
4012
4022
|
// `undefined` → one viewport height, resolved at sync time. `Infinity` is
|
|
4013
4023
|
// unsupported here: it unwindows every carrier, which is O(total glyphs).
|
|
4014
|
-
|
|
4024
|
+
__init125() {this.contentProjectionMargin = void 0}
|
|
4015
4025
|
// Virtualization margin (px) for the SEMANTIC tier — whether a block has
|
|
4016
4026
|
// any projected DOM. `undefined` → falls back to contentProjectionMargin, so
|
|
4017
4027
|
// the default keeps one gate. `Infinity` = every block keeps resident text.
|
|
4018
|
-
|
|
4028
|
+
__init126() {this.contentSemanticMargin = void 0}
|
|
4019
4029
|
// How many coarse-tier blocks may be MATERIALIZED per sync, spreading the
|
|
4020
4030
|
// resident tier's document-open cost across frames. `Infinity` = one
|
|
4021
4031
|
// synchronous pass.
|
|
4022
|
-
|
|
4032
|
+
__init127() {this.contentSemanticBudget = DEFAULT_CONTENT_SEMANTIC_BUDGET}
|
|
4023
4033
|
// Remaining materializations in the CURRENT sync. Reset at the start of each
|
|
4024
4034
|
// a11y walk; decremented per coarse block that creates its element.
|
|
4025
|
-
|
|
4035
|
+
__init128() {this.contentSemanticBudgetLeft = 0}
|
|
4026
4036
|
// Set when a sync deferred at least one block, so the scene knows to keep
|
|
4027
4037
|
// drawing frames until the resident tier is complete. Without it a static
|
|
4028
4038
|
// scene in `onDemand` mode would stop rendering with the document half
|
|
4029
4039
|
// materialized and never finish.
|
|
4030
|
-
|
|
4031
|
-
|
|
4040
|
+
__init129() {this.contentSemanticDeferred = false}
|
|
4041
|
+
__init130() {this.contentSelectionEndListener = null}
|
|
4032
4042
|
// --- domain: render-scheduler — per-frame walk flags ---
|
|
4033
4043
|
// Animation/interactive flags collected during the render walk (tree-walk
|
|
4034
4044
|
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
4035
4045
|
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
4036
|
-
|
|
4037
|
-
|
|
4046
|
+
__init131() {this.frameHadAnimation = true}
|
|
4047
|
+
__init132() {this.frameHadInteractive = true}
|
|
4038
4048
|
// --- domain: context-and-resize — resize handler, DPR query, canvas observer ---
|
|
4039
4049
|
|
|
4040
4050
|
/** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
|
|
@@ -4042,15 +4052,15 @@ var Scene = (_class15 = class _Scene {
|
|
|
4042
4052
|
* can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
|
|
4043
4053
|
* A resolution media query only fires when leaving its exact value, so the
|
|
4044
4054
|
* handler re-arms a fresh query for the new DPR each time. */
|
|
4045
|
-
|
|
4055
|
+
__init133() {this.dprMediaQuery = null}
|
|
4046
4056
|
/** For embedded (`disableWindowResize`) scenes: observes the canvas element so
|
|
4047
4057
|
* a CSS/layout-driven size change re-runs `resize()`. A window `resize`
|
|
4048
4058
|
* listener never fires for these (the window isn't what changed), so without
|
|
4049
4059
|
* this an embedded canvas stayed at its initial size forever. */
|
|
4050
|
-
|
|
4051
|
-
|
|
4060
|
+
__init134() {this.canvasResizeObserver = null}
|
|
4061
|
+
__init135() {this.dprChangeHandler = null}
|
|
4052
4062
|
// --- domain: a11y-projection — focus, overlay geometry, DOM ordering, portals ---
|
|
4053
|
-
|
|
4063
|
+
__init136() {this.focusedA11yElement = null}
|
|
4054
4064
|
/**
|
|
4055
4065
|
* Canvas box geometry: the CSS↔logical mapping, overlay layer alignment, and
|
|
4056
4066
|
* the DPR math (extraction 5, `DEC-0024`).
|
|
@@ -4077,7 +4087,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4077
4087
|
/** Shadow elements the pointer is currently inside. Lets a removal that happens
|
|
4078
4088
|
* mid-hover synthesize the `pointerleave` the browser never sends for a
|
|
4079
4089
|
* detached element, so the entity doesn't keep its hover state. */
|
|
4080
|
-
|
|
4090
|
+
__init137() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
|
|
4081
4091
|
/**
|
|
4082
4092
|
* Entity ids the application has pinned via {@link requestA11yProjection}.
|
|
4083
4093
|
*
|
|
@@ -4085,13 +4095,13 @@ var Scene = (_class15 = class _Scene {
|
|
|
4085
4095
|
* a stale id simply never matches. Cleared per-entity by
|
|
4086
4096
|
* {@link releaseA11yProjection}.
|
|
4087
4097
|
*/
|
|
4088
|
-
|
|
4098
|
+
__init138() {this.a11yProjectionRequests = /* @__PURE__ */ new Set()}
|
|
4089
4099
|
/** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
|
|
4090
4100
|
* pruned (virtualization/streaming/removal) while it holds focus, we move
|
|
4091
4101
|
* focus here instead of letting the browser drop it to <body> — keeping the
|
|
4092
4102
|
* screen-reader virtual cursor inside the scene's a11y region. */
|
|
4093
|
-
|
|
4094
|
-
|
|
4103
|
+
__init139() {this.focusSentinel = null}
|
|
4104
|
+
__init140() {this.caretBlinkTimer = null}
|
|
4095
4105
|
/**
|
|
4096
4106
|
* The projected DOM's ordering engine — the reorder flag, the per-pass scratch
|
|
4097
4107
|
* collections, the visual reading-order sort and the cursor-based
|
|
@@ -4101,7 +4111,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4101
4111
|
* delegate here; the collect-and-prune walk stays behind because it needs
|
|
4102
4112
|
* {@link shouldProjectA11y} and the focus/caret state.
|
|
4103
4113
|
*/
|
|
4104
|
-
|
|
4114
|
+
__init141() {this.a11yOrder = new A11yProjectionManager()}
|
|
4105
4115
|
/**
|
|
4106
4116
|
* The content projection's selection preservation and grid calibration
|
|
4107
4117
|
* (extraction 3, `DEC-0022`).
|
|
@@ -4153,11 +4163,11 @@ var Scene = (_class15 = class _Scene {
|
|
|
4153
4163
|
set a11yNeedsReorder(value) {
|
|
4154
4164
|
this.a11yOrder.needsReorder = value;
|
|
4155
4165
|
}
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4166
|
+
__init142() {this.portalRoot = null}
|
|
4167
|
+
__init143() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
|
|
4168
|
+
__init144() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
|
|
4169
|
+
__init145() {this.portalEntities = /* @__PURE__ */ new Map()}
|
|
4170
|
+
__init146() {this.renderOrderCounter = 0}
|
|
4161
4171
|
// --- domain: render-scheduler — authoritative frame counter ---
|
|
4162
4172
|
/**
|
|
4163
4173
|
* Monotonic render-frame counter, bumped once per authoritative `render()`
|
|
@@ -4167,7 +4177,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4167
4177
|
* back to the ancestor walk. Public for the same reason `Entity._getTrig`/
|
|
4168
4178
|
* `_setWorldCache` are: it is a cross-class render-internal contract.
|
|
4169
4179
|
*/
|
|
4170
|
-
|
|
4180
|
+
__init147() {this.currentFrame = 0}
|
|
4171
4181
|
// --- domain: wasm-backend-facade — EXTRACTED (see scene/WasmBackendFacade.ts) ---
|
|
4172
4182
|
/**
|
|
4173
4183
|
* The four invisible WASM accelerators and the resident transform store.
|
|
@@ -4237,8 +4247,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4237
4247
|
// Stays on `Scene`: it walks `root` *and* `overlayRoot` for entities the
|
|
4238
4248
|
// render walk consumes, so only its cache key is store state. The facade owns
|
|
4239
4249
|
// the key; the walk stays here.
|
|
4240
|
-
|
|
4241
|
-
|
|
4250
|
+
__init148() {this._computeEntities = []}
|
|
4251
|
+
__init149() {this._computeEntitiesVersion = -1}
|
|
4242
4252
|
/** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
|
|
4243
4253
|
* it. Called by `Entity.add`/`remove` (topology changes only). */
|
|
4244
4254
|
markStructureChanged() {
|
|
@@ -4477,7 +4487,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4477
4487
|
get animBatchedLastFrame() {
|
|
4478
4488
|
return this._wasmBackend.animBatchedLastFrame;
|
|
4479
4489
|
}
|
|
4480
|
-
|
|
4490
|
+
__init150() {this.animGate = {
|
|
4481
4491
|
spring: 128,
|
|
4482
4492
|
tween: 256,
|
|
4483
4493
|
mixed: 128
|
|
@@ -4592,25 +4602,25 @@ var Scene = (_class15 = class _Scene {
|
|
|
4592
4602
|
* sync, so retaining the order prevents a newly opened overlay from spending
|
|
4593
4603
|
* its first frame below previously projected controls.
|
|
4594
4604
|
*/
|
|
4595
|
-
|
|
4605
|
+
__init151() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
|
|
4596
4606
|
// --- domain: context-and-resize — GL/GPU canvases, device state, pointer, size warnings ---
|
|
4597
4607
|
// Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4608
|
+
__init152() {this.pointRenderer = null}
|
|
4609
|
+
__init153() {this.glCanvas = null}
|
|
4610
|
+
__init154() {this.glContextLostHandler = null}
|
|
4611
|
+
__init155() {this.glContextRestoredHandler = null}
|
|
4602
4612
|
|
|
4603
4613
|
|
|
4604
4614
|
|
|
4605
|
-
|
|
4615
|
+
__init156() {this.disableWindowResize = false}
|
|
4606
4616
|
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
4607
4617
|
|
|
4608
4618
|
// WebGPU properties
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4619
|
+
__init157() {this.destroyed = false}
|
|
4620
|
+
__init158() {this.device = null}
|
|
4621
|
+
__init159() {this.deviceLost = false}
|
|
4622
|
+
__init160() {this.particleBackend = "auto"}
|
|
4623
|
+
__init161() {this._webgpuDisabled = false}
|
|
4614
4624
|
get webgpuDisabled() {
|
|
4615
4625
|
return this._webgpuDisabled || this.particleBackend === "cpu";
|
|
4616
4626
|
}
|
|
@@ -4638,21 +4648,21 @@ var Scene = (_class15 = class _Scene {
|
|
|
4638
4648
|
set webgpuDisabled(value) {
|
|
4639
4649
|
this._webgpuDisabled = value;
|
|
4640
4650
|
}
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4651
|
+
__init162() {this.recoveryTimerId = null}
|
|
4652
|
+
__init163() {this.manager = null}
|
|
4653
|
+
__init164() {this.initializingWebGPU = false}
|
|
4654
|
+
__init165() {this.gpuCanvas = null}
|
|
4655
|
+
__init166() {this.gpuContext = null}
|
|
4646
4656
|
/** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4657
|
+
__init167() {this.gpuHasContent = false}
|
|
4658
|
+
__init168() {this.mouseX = -9999}
|
|
4659
|
+
__init169() {this.mouseY = -9999}
|
|
4660
|
+
__init170() {this.pointerMoveListener = null}
|
|
4661
|
+
__init171() {this.pointerLeaveListener = null}
|
|
4652
4662
|
/** Element the pointer listeners are bound to (parent container if present,
|
|
4653
4663
|
* else the canvas). Stored so `destroy()` detaches from the same element. */
|
|
4654
|
-
|
|
4655
|
-
|
|
4664
|
+
__init172() {this.pointerEventTarget = null}
|
|
4665
|
+
__init173() {this.hasWarnedZeroSize = false}
|
|
4656
4666
|
/**
|
|
4657
4667
|
* Latch for {@link Scene.resize}'s invalid-dimension warning.
|
|
4658
4668
|
*
|
|
@@ -4662,8 +4672,8 @@ var Scene = (_class15 = class _Scene {
|
|
|
4662
4672
|
* because `resize()` is commonly driven from a `ResizeObserver`, which would
|
|
4663
4673
|
* otherwise warn on every frame of a drag.
|
|
4664
4674
|
*/
|
|
4665
|
-
|
|
4666
|
-
|
|
4675
|
+
__init174() {this.hasWarnedInvalidResize = false}
|
|
4676
|
+
__init175() {this.fontLoadHandler = null}
|
|
4667
4677
|
// --- domain: scene-facade — dev-mode diagnostics ---
|
|
4668
4678
|
// ── Dev-mode warning infrastructure ──────────────────────────────
|
|
4669
4679
|
//
|
|
@@ -4698,7 +4708,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4698
4708
|
return false;
|
|
4699
4709
|
}
|
|
4700
4710
|
|
|
4701
|
-
|
|
4711
|
+
__init176() {this._devFrameCount = 0}
|
|
4702
4712
|
_devWarn(message) {
|
|
4703
4713
|
if (!this._devActive) return;
|
|
4704
4714
|
console.warn(`[vectojs/dev] ${message}`);
|
|
@@ -4776,7 +4786,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4776
4786
|
walkProjections(this.root);
|
|
4777
4787
|
}
|
|
4778
4788
|
// --- domain: scene-facade — construction (wires every collaborator) ---
|
|
4779
|
-
constructor(canvas, options = {}) {;_class15.prototype.__init83.call(this);_class15.prototype.__init84.call(this);_class15.prototype.__init85.call(this);_class15.prototype.__init86.call(this);_class15.prototype.__init87.call(this);_class15.prototype.__init88.call(this);_class15.prototype.__init89.call(this);_class15.prototype.__init90.call(this);_class15.prototype.__init91.call(this);_class15.prototype.__init92.call(this);_class15.prototype.__init93.call(this);_class15.prototype.__init94.call(this);_class15.prototype.__init95.call(this);_class15.prototype.__init96.call(this);_class15.prototype.__init97.call(this);_class15.prototype.__init98.call(this);_class15.prototype.__init99.call(this);_class15.prototype.__init100.call(this);_class15.prototype.__init101.call(this);_class15.prototype.__init102.call(this);_class15.prototype.__init103.call(this);_class15.prototype.__init104.call(this);_class15.prototype.__init105.call(this);_class15.prototype.__init106.call(this);_class15.prototype.__init107.call(this);_class15.prototype.__init108.call(this);_class15.prototype.__init109.call(this);_class15.prototype.__init110.call(this);_class15.prototype.__init111.call(this);_class15.prototype.__init112.call(this);_class15.prototype.__init113.call(this);_class15.prototype.__init114.call(this);_class15.prototype.__init115.call(this);_class15.prototype.__init116.call(this);_class15.prototype.__init117.call(this);_class15.prototype.__init118.call(this);_class15.prototype.__init119.call(this);_class15.prototype.__init120.call(this);_class15.prototype.__init121.call(this);_class15.prototype.__init122.call(this);_class15.prototype.__init123.call(this);_class15.prototype.__init124.call(this);_class15.prototype.__init125.call(this);_class15.prototype.__init126.call(this);_class15.prototype.__init127.call(this);_class15.prototype.__init128.call(this);_class15.prototype.__init129.call(this);_class15.prototype.__init130.call(this);_class15.prototype.__init131.call(this);_class15.prototype.__init132.call(this);_class15.prototype.__init133.call(this);_class15.prototype.__init134.call(this);_class15.prototype.__init135.call(this);_class15.prototype.__init136.call(this);_class15.prototype.__init137.call(this);_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);_class15.prototype.__init140.call(this);_class15.prototype.__init141.call(this);_class15.prototype.__init142.call(this);_class15.prototype.__init143.call(this);_class15.prototype.__init144.call(this);_class15.prototype.__init145.call(this);_class15.prototype.__init146.call(this);_class15.prototype.__init147.call(this);_class15.prototype.__init148.call(this);_class15.prototype.__init149.call(this);_class15.prototype.__init150.call(this);_class15.prototype.__init151.call(this);_class15.prototype.__init152.call(this);_class15.prototype.__init153.call(this);_class15.prototype.__init154.call(this);_class15.prototype.__init155.call(this);_class15.prototype.__init156.call(this);_class15.prototype.__init157.call(this);_class15.prototype.__init158.call(this);_class15.prototype.__init159.call(this);_class15.prototype.__init160.call(this);_class15.prototype.__init161.call(this);_class15.prototype.__init162.call(this);_class15.prototype.__init163.call(this);_class15.prototype.__init164.call(this);_class15.prototype.__init165.call(this);_class15.prototype.__init166.call(this);_class15.prototype.__init167.call(this);_class15.prototype.__init168.call(this);_class15.prototype.__init169.call(this);_class15.prototype.__init170.call(this);_class15.prototype.__init171.call(this);_class15.prototype.__init172.call(this);_class15.prototype.__init173.call(this);_class15.prototype.__init174.call(this);_class15.prototype.__init175.call(this);
|
|
4789
|
+
constructor(canvas, options = {}) {;_class15.prototype.__init83.call(this);_class15.prototype.__init84.call(this);_class15.prototype.__init85.call(this);_class15.prototype.__init86.call(this);_class15.prototype.__init87.call(this);_class15.prototype.__init88.call(this);_class15.prototype.__init89.call(this);_class15.prototype.__init90.call(this);_class15.prototype.__init91.call(this);_class15.prototype.__init92.call(this);_class15.prototype.__init93.call(this);_class15.prototype.__init94.call(this);_class15.prototype.__init95.call(this);_class15.prototype.__init96.call(this);_class15.prototype.__init97.call(this);_class15.prototype.__init98.call(this);_class15.prototype.__init99.call(this);_class15.prototype.__init100.call(this);_class15.prototype.__init101.call(this);_class15.prototype.__init102.call(this);_class15.prototype.__init103.call(this);_class15.prototype.__init104.call(this);_class15.prototype.__init105.call(this);_class15.prototype.__init106.call(this);_class15.prototype.__init107.call(this);_class15.prototype.__init108.call(this);_class15.prototype.__init109.call(this);_class15.prototype.__init110.call(this);_class15.prototype.__init111.call(this);_class15.prototype.__init112.call(this);_class15.prototype.__init113.call(this);_class15.prototype.__init114.call(this);_class15.prototype.__init115.call(this);_class15.prototype.__init116.call(this);_class15.prototype.__init117.call(this);_class15.prototype.__init118.call(this);_class15.prototype.__init119.call(this);_class15.prototype.__init120.call(this);_class15.prototype.__init121.call(this);_class15.prototype.__init122.call(this);_class15.prototype.__init123.call(this);_class15.prototype.__init124.call(this);_class15.prototype.__init125.call(this);_class15.prototype.__init126.call(this);_class15.prototype.__init127.call(this);_class15.prototype.__init128.call(this);_class15.prototype.__init129.call(this);_class15.prototype.__init130.call(this);_class15.prototype.__init131.call(this);_class15.prototype.__init132.call(this);_class15.prototype.__init133.call(this);_class15.prototype.__init134.call(this);_class15.prototype.__init135.call(this);_class15.prototype.__init136.call(this);_class15.prototype.__init137.call(this);_class15.prototype.__init138.call(this);_class15.prototype.__init139.call(this);_class15.prototype.__init140.call(this);_class15.prototype.__init141.call(this);_class15.prototype.__init142.call(this);_class15.prototype.__init143.call(this);_class15.prototype.__init144.call(this);_class15.prototype.__init145.call(this);_class15.prototype.__init146.call(this);_class15.prototype.__init147.call(this);_class15.prototype.__init148.call(this);_class15.prototype.__init149.call(this);_class15.prototype.__init150.call(this);_class15.prototype.__init151.call(this);_class15.prototype.__init152.call(this);_class15.prototype.__init153.call(this);_class15.prototype.__init154.call(this);_class15.prototype.__init155.call(this);_class15.prototype.__init156.call(this);_class15.prototype.__init157.call(this);_class15.prototype.__init158.call(this);_class15.prototype.__init159.call(this);_class15.prototype.__init160.call(this);_class15.prototype.__init161.call(this);_class15.prototype.__init162.call(this);_class15.prototype.__init163.call(this);_class15.prototype.__init164.call(this);_class15.prototype.__init165.call(this);_class15.prototype.__init166.call(this);_class15.prototype.__init167.call(this);_class15.prototype.__init168.call(this);_class15.prototype.__init169.call(this);_class15.prototype.__init170.call(this);_class15.prototype.__init171.call(this);_class15.prototype.__init172.call(this);_class15.prototype.__init173.call(this);_class15.prototype.__init174.call(this);_class15.prototype.__init175.call(this);_class15.prototype.__init176.call(this);
|
|
4780
4790
|
this.canvas = canvas;
|
|
4781
4791
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
4782
4792
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
@@ -4795,6 +4805,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4795
4805
|
this.maxFPS = _nullishCoalesce(options.maxFPS, () => ( (isTest ? 0 : 60)));
|
|
4796
4806
|
this.respectReducedMotion = _nullishCoalesce(options.respectReducedMotion, () => ( true));
|
|
4797
4807
|
this.autoThrottle = _nullishCoalesce(options.autoThrottle, () => ( true));
|
|
4808
|
+
this.idleFPS = _nullishCoalesce(options.idleFPS, () => ( 60));
|
|
4798
4809
|
this.phases.userTiming = _nullishCoalesce(options.userTiming, () => ( false));
|
|
4799
4810
|
this.particleBackend = _nullishCoalesce(options.particleBackend, () => ( "auto"));
|
|
4800
4811
|
this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
|
|
@@ -4813,7 +4824,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4813
4824
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
4814
4825
|
_optionalChain([this, 'access', _118 => _118.forcedColorsQuery, 'access', _119 => _119.addEventListener, 'optionalCall', _120 => _120("change", this.forcedColorsChangeHandler)]);
|
|
4815
4826
|
}
|
|
4816
|
-
this.root = new class RootEntity extends
|
|
4827
|
+
this.root = new class RootEntity extends _chunkXE6K7T5Sjs.Entity {
|
|
4817
4828
|
isPointInside() {
|
|
4818
4829
|
return false;
|
|
4819
4830
|
}
|
|
@@ -4823,7 +4834,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4823
4834
|
}("root");
|
|
4824
4835
|
this.root._scene = this;
|
|
4825
4836
|
this._wasmBackend = new WasmBackendFacade(this.root);
|
|
4826
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
4837
|
+
this.overlayRoot = new class OverlayRoot extends _chunkXE6K7T5Sjs.Entity {
|
|
4827
4838
|
isPointInside() {
|
|
4828
4839
|
return false;
|
|
4829
4840
|
}
|
|
@@ -5143,7 +5154,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5143
5154
|
}
|
|
5144
5155
|
if (this.hoveredA11yElements.has(el)) {
|
|
5145
5156
|
this.hoveredA11yElements.delete(el);
|
|
5146
|
-
node.dispatchEvent(new (0,
|
|
5157
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("pointerleave", node, void 0, false));
|
|
5147
5158
|
}
|
|
5148
5159
|
this.preserveFocusOnRemoval(el);
|
|
5149
5160
|
el.remove();
|
|
@@ -5734,20 +5745,20 @@ var Scene = (_class15 = class _Scene {
|
|
|
5734
5745
|
el.style.background = "transparent";
|
|
5735
5746
|
}
|
|
5736
5747
|
el.addEventListener("click", (e) => {
|
|
5737
|
-
node.dispatchEvent(new (0,
|
|
5748
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("click", node, e));
|
|
5738
5749
|
});
|
|
5739
5750
|
el.addEventListener("dblclick", (e) => {
|
|
5740
|
-
node.dispatchEvent(new (0,
|
|
5751
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("dblclick", node, e));
|
|
5741
5752
|
});
|
|
5742
5753
|
el.addEventListener("mouseenter", (e) => {
|
|
5743
5754
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
5744
5755
|
this.hoveredA11yElements.add(el);
|
|
5745
|
-
node.dispatchEvent(new (0,
|
|
5756
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("hover", node, e, false));
|
|
5746
5757
|
});
|
|
5747
5758
|
el.addEventListener("mouseleave", (e) => {
|
|
5748
5759
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
5749
5760
|
this.hoveredA11yElements.delete(el);
|
|
5750
|
-
node.dispatchEvent(new (0,
|
|
5761
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("pointerleave", node, e, false));
|
|
5751
5762
|
});
|
|
5752
5763
|
const capEl = el;
|
|
5753
5764
|
const releasePointer = (event) => {
|
|
@@ -5763,24 +5774,24 @@ var Scene = (_class15 = class _Scene {
|
|
|
5763
5774
|
};
|
|
5764
5775
|
el.addEventListener("pointerdown", (e) => {
|
|
5765
5776
|
if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
|
|
5766
|
-
node.dispatchEvent(new (0,
|
|
5777
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("pointerdown", node, e));
|
|
5767
5778
|
});
|
|
5768
5779
|
el.addEventListener("pointerup", (e) => {
|
|
5769
5780
|
releasePointer(e);
|
|
5770
|
-
node.dispatchEvent(new (0,
|
|
5781
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("pointerup", node, e));
|
|
5771
5782
|
});
|
|
5772
5783
|
el.addEventListener("pointercancel", (e) => {
|
|
5773
5784
|
releasePointer(e);
|
|
5774
|
-
node.dispatchEvent(new (0,
|
|
5785
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("pointercancel", node, e));
|
|
5775
5786
|
});
|
|
5776
5787
|
el.addEventListener(
|
|
5777
5788
|
"pointermove",
|
|
5778
|
-
(e) => node.dispatchEvent(new (0,
|
|
5789
|
+
(e) => node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("pointermove", node, e))
|
|
5779
5790
|
);
|
|
5780
5791
|
el.addEventListener(
|
|
5781
5792
|
"wheel",
|
|
5782
5793
|
(e) => {
|
|
5783
|
-
node.dispatchEvent(new (0,
|
|
5794
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("wheel", node, e));
|
|
5784
5795
|
},
|
|
5785
5796
|
{ passive: false }
|
|
5786
5797
|
);
|
|
@@ -5805,10 +5816,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
5805
5816
|
);
|
|
5806
5817
|
emitInitialScroll = emitScroll;
|
|
5807
5818
|
el.addEventListener("keydown", (e) => {
|
|
5808
|
-
node.dispatchEvent(new (0,
|
|
5819
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("keydown", node, e));
|
|
5809
5820
|
});
|
|
5810
5821
|
el.addEventListener("keyup", (e) => {
|
|
5811
|
-
node.dispatchEvent(new (0,
|
|
5822
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("keyup", node, e));
|
|
5812
5823
|
});
|
|
5813
5824
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
5814
5825
|
const input = el;
|
|
@@ -5874,7 +5885,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5874
5885
|
el.addEventListener("keydown", (e) => {
|
|
5875
5886
|
if (e.key === "Enter" || e.key === " ") {
|
|
5876
5887
|
e.preventDefault();
|
|
5877
|
-
node.dispatchEvent(new (0,
|
|
5888
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("click", node, e));
|
|
5878
5889
|
}
|
|
5879
5890
|
});
|
|
5880
5891
|
}
|
|
@@ -6311,7 +6322,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6311
6322
|
el.addEventListener(
|
|
6312
6323
|
"wheel",
|
|
6313
6324
|
(e2) => {
|
|
6314
|
-
node.dispatchEvent(new (0,
|
|
6325
|
+
node.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)("wheel", node, e2));
|
|
6315
6326
|
},
|
|
6316
6327
|
{ passive: false }
|
|
6317
6328
|
);
|
|
@@ -6740,7 +6751,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6740
6751
|
let cap = this.effectiveMaxFPS();
|
|
6741
6752
|
const isIdle = !this.dirty && !this.frameHadAnimation && !this.contentSemanticDeferred;
|
|
6742
6753
|
if (isIdle && this.autoThrottle && this.renderMode === "always" && this.maxFPS > 0) {
|
|
6743
|
-
cap = Math.min(cap,
|
|
6754
|
+
cap = Math.min(cap, this.idleFPS);
|
|
6744
6755
|
}
|
|
6745
6756
|
if (cap > 0 && time - this.lastTime < 1e3 / cap - 1) {
|
|
6746
6757
|
this._skippedFrames++;
|
|
@@ -6980,7 +6991,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6980
6991
|
let walkHadAnimation = false;
|
|
6981
6992
|
let walkHadInteractive = false;
|
|
6982
6993
|
const runUpdate = (node) => {
|
|
6983
|
-
const overridesUpdate = node.update !==
|
|
6994
|
+
const overridesUpdate = node.update !== _chunkXE6K7T5Sjs.Entity.prototype.update;
|
|
6984
6995
|
let pending = node.hasPendingAnimations();
|
|
6985
6996
|
if (pending || overridesUpdate) {
|
|
6986
6997
|
node.update(dt, time);
|
|
@@ -6989,9 +7000,9 @@ var Scene = (_class15 = class _Scene {
|
|
|
6989
7000
|
if (pending) walkHadAnimation = true;
|
|
6990
7001
|
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
6991
7002
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
6992
|
-
if (overridesUpdate && node.hasPendingAnimations ===
|
|
7003
|
+
if (overridesUpdate && node.hasPendingAnimations === _chunkXE6K7T5Sjs.Entity.prototype.hasPendingAnimations) {
|
|
6993
7004
|
this._devWarn(
|
|
6994
|
-
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to
|
|
7005
|
+
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to slow the animation. Override hasPendingAnimations() to return true while motion is in flight.`
|
|
6995
7006
|
);
|
|
6996
7007
|
}
|
|
6997
7008
|
}
|
|
@@ -7415,20 +7426,20 @@ function defaultMeasurer() {
|
|
|
7415
7426
|
sharedMeasurer ??= _layout.resolveGlyphMeasurer.call(void 0, "sans-serif");
|
|
7416
7427
|
return sharedMeasurer;
|
|
7417
7428
|
}
|
|
7418
|
-
var TextEntity = (_class16 = class extends
|
|
7429
|
+
var TextEntity = (_class16 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
7419
7430
|
|
|
7420
7431
|
|
|
7421
7432
|
|
|
7422
7433
|
|
|
7423
|
-
|
|
7434
|
+
__init177() {this.nodes = []}
|
|
7424
7435
|
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7436
|
+
__init178() {this.fillStyle = "#94a3b8"}
|
|
7437
|
+
__init179() {this.strokeStyle = null}
|
|
7438
|
+
__init180() {this.hoveredFillStyle = "#ffffff"}
|
|
7439
|
+
__init181() {this.lineWidth = 1}
|
|
7440
|
+
__init182() {this.isHovered = false}
|
|
7430
7441
|
/** Bumped by {@link applyLayout}; read by `Scene` to skip an unchanged sync. */
|
|
7431
|
-
|
|
7442
|
+
__init183() {this.contentEpoch = 0}
|
|
7432
7443
|
/**
|
|
7433
7444
|
* Visual lines with real canvas geometry, rebuilt by {@link applyLayout}
|
|
7434
7445
|
* exactly when `this.nodes` changes.
|
|
@@ -7440,9 +7451,9 @@ var TextEntity = (_class16 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
7440
7451
|
* ~0.35 em per line for a 24 px font, Firefox). Per-line carriers pin the DOM
|
|
7441
7452
|
* baseline to the canvas baseline by construction, same as `ui/Text`.
|
|
7442
7453
|
*/
|
|
7443
|
-
|
|
7454
|
+
__init184() {this.projectionLines = []}
|
|
7444
7455
|
constructor(text, atlas, maxWidth, fontSize = 24) {
|
|
7445
|
-
super();_class16.prototype.
|
|
7456
|
+
super();_class16.prototype.__init177.call(this);_class16.prototype.__init178.call(this);_class16.prototype.__init179.call(this);_class16.prototype.__init180.call(this);_class16.prototype.__init181.call(this);_class16.prototype.__init182.call(this);_class16.prototype.__init183.call(this);_class16.prototype.__init184.call(this);;
|
|
7446
7457
|
this.text = text;
|
|
7447
7458
|
this.atlas = atlas;
|
|
7448
7459
|
this.fontSize = fontSize;
|
|
@@ -7619,17 +7630,17 @@ var TextEntity = (_class16 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
7619
7630
|
}, _class16);
|
|
7620
7631
|
|
|
7621
7632
|
// src/components/GridTextEntity.ts
|
|
7622
|
-
var GridTextEntity = (_class17 = class extends
|
|
7633
|
+
var GridTextEntity = (_class17 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
7623
7634
|
|
|
7624
|
-
|
|
7625
|
-
|
|
7635
|
+
__init185() {this.fillStyle = "#ffffff"}
|
|
7636
|
+
__init186() {this.grid = []}
|
|
7626
7637
|
// Array of rows
|
|
7627
|
-
|
|
7628
|
-
|
|
7638
|
+
__init187() {this.cols = 0}
|
|
7639
|
+
__init188() {this.rows = 0}
|
|
7629
7640
|
|
|
7630
7641
|
|
|
7631
7642
|
constructor(_atlas, fontSize = 10) {
|
|
7632
|
-
super();_class17.prototype.
|
|
7643
|
+
super();_class17.prototype.__init185.call(this);_class17.prototype.__init186.call(this);_class17.prototype.__init187.call(this);_class17.prototype.__init188.call(this);;
|
|
7633
7644
|
this.fontSize = fontSize;
|
|
7634
7645
|
this.charWidth = fontSize * 1;
|
|
7635
7646
|
this.charHeight = fontSize * 1.1;
|
|
@@ -7713,7 +7724,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
7713
7724
|
const ey = py - cy;
|
|
7714
7725
|
return ex * ex + ey * ey;
|
|
7715
7726
|
}
|
|
7716
|
-
var SplineEntity = (_class18 = class extends
|
|
7727
|
+
var SplineEntity = (_class18 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
7717
7728
|
|
|
7718
7729
|
|
|
7719
7730
|
|
|
@@ -7721,17 +7732,17 @@ var SplineEntity = (_class18 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
7721
7732
|
|
|
7722
7733
|
|
|
7723
7734
|
|
|
7724
|
-
|
|
7725
|
-
|
|
7735
|
+
__init189() {this.offscreen = null}
|
|
7736
|
+
__init190() {this.baked = false}
|
|
7726
7737
|
/** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
|
|
7727
|
-
|
|
7728
|
-
|
|
7738
|
+
__init191() {this.bakedWidth = 0}
|
|
7739
|
+
__init192() {this.bakedHeight = 0}
|
|
7729
7740
|
/**
|
|
7730
7741
|
* Device-pixel ratio the bitmap was rasterized at. Tracked so a DPR change
|
|
7731
7742
|
* (browser zoom, a monitor move, a renderer whose clamp changed) re-bakes
|
|
7732
7743
|
* instead of blitting a bitmap at the wrong device density forever.
|
|
7733
7744
|
*/
|
|
7734
|
-
|
|
7745
|
+
__init193() {this.bakedDPR = 0}
|
|
7735
7746
|
/**
|
|
7736
7747
|
* Gradient strokes can't be baked to a solid-color bitmap; they render
|
|
7737
7748
|
* per-frame. Derived from `_doc`, so it is NOT readonly — assigning a new
|
|
@@ -7739,7 +7750,7 @@ var SplineEntity = (_class18 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
7739
7750
|
*/
|
|
7740
7751
|
|
|
7741
7752
|
/** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
|
|
7742
|
-
|
|
7753
|
+
__init194() {this.polylines = null}
|
|
7743
7754
|
/**
|
|
7744
7755
|
* The spline document to render. Assigning a new document invalidates all
|
|
7745
7756
|
* caches (baked canvas, flattened polylines, bounds).
|
|
@@ -7773,9 +7784,9 @@ var SplineEntity = (_class18 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
7773
7784
|
* local bounds after painting the curves. Useful for drag feedback and
|
|
7774
7785
|
* debugging hit areas. Defaults to `false`.
|
|
7775
7786
|
*/
|
|
7776
|
-
|
|
7787
|
+
__init195() {this.showBounds = false}
|
|
7777
7788
|
constructor(doc, opts = {}) {
|
|
7778
|
-
super();_class18.prototype.
|
|
7789
|
+
super();_class18.prototype.__init189.call(this);_class18.prototype.__init190.call(this);_class18.prototype.__init191.call(this);_class18.prototype.__init192.call(this);_class18.prototype.__init193.call(this);_class18.prototype.__init194.call(this);_class18.prototype.__init195.call(this);;
|
|
7779
7790
|
this._doc = doc;
|
|
7780
7791
|
this._lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
|
|
7781
7792
|
this.cache = _nullishCoalesce(opts.cache, () => ( true));
|
|
@@ -8041,7 +8052,7 @@ async function loadSpline(url) {
|
|
|
8041
8052
|
}
|
|
8042
8053
|
|
|
8043
8054
|
// src/components/Rect.ts
|
|
8044
|
-
var Rect = class extends
|
|
8055
|
+
var Rect = class extends _chunkXE6K7T5Sjs.Entity {
|
|
8045
8056
|
|
|
8046
8057
|
|
|
8047
8058
|
|
|
@@ -8097,7 +8108,7 @@ var Rect = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
8097
8108
|
};
|
|
8098
8109
|
|
|
8099
8110
|
// src/components/Circle.ts
|
|
8100
|
-
var Circle = class extends
|
|
8111
|
+
var Circle = class extends _chunkXE6K7T5Sjs.Entity {
|
|
8101
8112
|
|
|
8102
8113
|
|
|
8103
8114
|
|
|
@@ -8161,7 +8172,7 @@ var Circle = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
8161
8172
|
};
|
|
8162
8173
|
|
|
8163
8174
|
// src/components/Group.ts
|
|
8164
|
-
var Group = class extends
|
|
8175
|
+
var Group = class extends _chunkXE6K7T5Sjs.Entity {
|
|
8165
8176
|
constructor(...children) {
|
|
8166
8177
|
super();
|
|
8167
8178
|
if (children.length > 0) this.add(...children);
|
|
@@ -8180,21 +8191,21 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
8180
8191
|
|
|
8181
8192
|
|
|
8182
8193
|
// src/tree/DOMPortalEntity.ts
|
|
8183
|
-
var DOMPortalEntity = (_class19 = class extends
|
|
8194
|
+
var DOMPortalEntity = (_class19 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
8184
8195
|
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
+
__init196() {this.isDOMPortal = true}
|
|
8197
|
+
__init197() {this.domListeners = []}
|
|
8198
|
+
__init198() {this.resizeObserver = null}
|
|
8199
|
+
__init199() {this.domBound = false}
|
|
8200
|
+
__init200() {this.cachedWidth = 100}
|
|
8201
|
+
__init201() {this.cachedHeight = 100}
|
|
8202
|
+
__init202() {this.lastWidth = ""}
|
|
8203
|
+
__init203() {this.lastHeight = ""}
|
|
8204
|
+
__init204() {this.lastTransform = ""}
|
|
8205
|
+
__init205() {this.lastZIndex = ""}
|
|
8206
|
+
__init206() {this.lastOpacity = ""}
|
|
8196
8207
|
constructor(domElement, width, height, id) {
|
|
8197
|
-
super(id);_class19.prototype.
|
|
8208
|
+
super(id);_class19.prototype.__init196.call(this);_class19.prototype.__init197.call(this);_class19.prototype.__init198.call(this);_class19.prototype.__init199.call(this);_class19.prototype.__init200.call(this);_class19.prototype.__init201.call(this);_class19.prototype.__init202.call(this);_class19.prototype.__init203.call(this);_class19.prototype.__init204.call(this);_class19.prototype.__init205.call(this);_class19.prototype.__init206.call(this);;
|
|
8198
8209
|
this.domElement = domElement;
|
|
8199
8210
|
this.width = _nullishCoalesce(width, () => ( 0));
|
|
8200
8211
|
this.height = _nullishCoalesce(height, () => ( 0));
|
|
@@ -8236,7 +8247,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
8236
8247
|
];
|
|
8237
8248
|
for (const type of events) {
|
|
8238
8249
|
const handler = (e) => {
|
|
8239
|
-
this.dispatchEvent(new (0,
|
|
8250
|
+
this.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)(type, this, e));
|
|
8240
8251
|
};
|
|
8241
8252
|
this.domElement.addEventListener(type, handler);
|
|
8242
8253
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -8247,7 +8258,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
8247
8258
|
];
|
|
8248
8259
|
for (const { native, vecto } of hoverEvents) {
|
|
8249
8260
|
const handler = (e) => {
|
|
8250
|
-
this.dispatchEvent(new (0,
|
|
8261
|
+
this.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)(vecto, this, e, false));
|
|
8251
8262
|
};
|
|
8252
8263
|
this.domElement.addEventListener(native, handler);
|
|
8253
8264
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -8255,7 +8266,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkXHPUCU5Pjs.Entity {
|
|
|
8255
8266
|
const focusEvents = ["focus", "blur"];
|
|
8256
8267
|
for (const type of focusEvents) {
|
|
8257
8268
|
const handler = (e) => {
|
|
8258
|
-
this.dispatchEvent(new (0,
|
|
8269
|
+
this.dispatchEvent(new (0, _chunkXE6K7T5Sjs.VectoJSEvent)(type, this, e, true));
|
|
8259
8270
|
};
|
|
8260
8271
|
this.domElement.addEventListener(type, handler, true);
|
|
8261
8272
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -8353,4 +8364,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkMO24PVGTjs.WebGPUParticleSystemM
|
|
|
8353
8364
|
|
|
8354
8365
|
|
|
8355
8366
|
|
|
8356
|
-
exports.CanvasRenderer = _chunkMO24PVGTjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DEFAULT_CONTENT_SEMANTIC_BUDGET = DEFAULT_CONTENT_SEMANTIC_BUDGET; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity =
|
|
8367
|
+
exports.CanvasRenderer = _chunkMO24PVGTjs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DEFAULT_CONTENT_SEMANTIC_BUDGET = DEFAULT_CONTENT_SEMANTIC_BUDGET; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkXE6K7T5Sjs.Entity; exports.GlyphRasterAtlas = _chunkMO24PVGTjs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkXE6K7T5Sjs.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.SCENE_OPTION_KEYS = SCENE_OPTION_KEYS; exports.SVGEntity = _chunkXE6K7T5Sjs.SVGEntity; exports.SVGRenderer = _chunkMO24PVGTjs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkMO24PVGTjs.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkXE6K7T5Sjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkMO24PVGTjs.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.contentLineInHint = _chunkXE6K7T5Sjs.contentLineInHint; exports.createWebGLPointRenderer = _chunkMO24PVGTjs.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.installRendererDevTraps = _chunkMO24PVGTjs.installRendererDevTraps; exports.isRendererDevMode = _chunkMO24PVGTjs.isRendererDevMode; exports.isSafeUrl = _chunkMO24PVGTjs.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkMO24PVGTjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkMO24PVGTjs.sanitizeUrl; exports.setRendererDevMode = _chunkMO24PVGTjs.setRendererDevMode;
|
package/dist/index.mjs
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
SVGEntity,
|
|
19
19
|
VectoJSEvent,
|
|
20
20
|
contentLineInHint
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-QJC4VZ2E.mjs";
|
|
22
22
|
|
|
23
23
|
// src/tree/ComputeParticleEntity.ts
|
|
24
24
|
var PARTICLE_STRIDE_FLOATS = 8;
|
|
@@ -178,8 +178,8 @@ var ComputeParticleEntity = class extends Entity {
|
|
|
178
178
|
* render-tree walk, but this entity is still a normal tree member that
|
|
179
179
|
* walk visits — without this override, the base `Entity.hasPendingAnimations()`
|
|
180
180
|
* (always `false`) is what Scene sees, so `renderMode: 'always'`'s idle
|
|
181
|
-
* auto-throttle drops the WHOLE scene to
|
|
182
|
-
* the tree is animating, even while thousands of particles are visibly
|
|
181
|
+
* auto-throttle drops the WHOLE scene to the idle FPS floor the instant
|
|
182
|
+
* nothing else in the tree is animating, even while thousands of particles are visibly
|
|
183
183
|
* drifting or spring-settling. A spring+damping system asymptotically
|
|
184
184
|
* approaches zero velocity but never reaches it exactly, so this checks
|
|
185
185
|
* against a small epsilon rather than `!== 0` — otherwise this would
|
|
@@ -3435,6 +3435,7 @@ var SCENE_OPTION_KEYS = [
|
|
|
3435
3435
|
"contentSemanticMargin",
|
|
3436
3436
|
"debugA11y",
|
|
3437
3437
|
"disableWindowResize",
|
|
3438
|
+
"idleFPS",
|
|
3438
3439
|
"maxDPR",
|
|
3439
3440
|
"maxFPS",
|
|
3440
3441
|
"particleBackend",
|
|
@@ -3863,8 +3864,17 @@ var Scene = class _Scene {
|
|
|
3863
3864
|
if (value) this._dirty.mark(void 0, this.currentFrame);
|
|
3864
3865
|
else this._dirty.clear();
|
|
3865
3866
|
}
|
|
3866
|
-
/**
|
|
3867
|
+
/**
|
|
3868
|
+
* Whether to throttle the `'always'` loop when the scene is static to save
|
|
3869
|
+
* power. The idle floor is {@link Scene.idleFPS} (default 60).
|
|
3870
|
+
*/
|
|
3867
3871
|
autoThrottle = true;
|
|
3872
|
+
/**
|
|
3873
|
+
* Frame-rate floor for an idle `'always'` scene when {@link Scene.autoThrottle}
|
|
3874
|
+
* is on. Default `60`. Set `2` for the legacy aggressive idle sleep, `0` to
|
|
3875
|
+
* keep the scene's `maxFPS` cadence while idle.
|
|
3876
|
+
*/
|
|
3877
|
+
idleFPS = 60;
|
|
3868
3878
|
// --- Frame telemetry (read via `frameStats`) ---------------------------
|
|
3869
3879
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
3870
3880
|
_lastFrameMs = 0;
|
|
@@ -4794,6 +4804,7 @@ var Scene = class _Scene {
|
|
|
4794
4804
|
this.maxFPS = options.maxFPS ?? (isTest ? 0 : 60);
|
|
4795
4805
|
this.respectReducedMotion = options.respectReducedMotion ?? true;
|
|
4796
4806
|
this.autoThrottle = options.autoThrottle ?? true;
|
|
4807
|
+
this.idleFPS = options.idleFPS ?? 60;
|
|
4797
4808
|
this.phases.userTiming = options.userTiming ?? false;
|
|
4798
4809
|
this.particleBackend = options.particleBackend ?? "auto";
|
|
4799
4810
|
this.a11ySyncInterval = options.a11ySyncInterval ?? 0;
|
|
@@ -6739,7 +6750,7 @@ var Scene = class _Scene {
|
|
|
6739
6750
|
let cap = this.effectiveMaxFPS();
|
|
6740
6751
|
const isIdle = !this.dirty && !this.frameHadAnimation && !this.contentSemanticDeferred;
|
|
6741
6752
|
if (isIdle && this.autoThrottle && this.renderMode === "always" && this.maxFPS > 0) {
|
|
6742
|
-
cap = Math.min(cap,
|
|
6753
|
+
cap = Math.min(cap, this.idleFPS);
|
|
6743
6754
|
}
|
|
6744
6755
|
if (cap > 0 && time - this.lastTime < 1e3 / cap - 1) {
|
|
6745
6756
|
this._skippedFrames++;
|
|
@@ -6990,7 +7001,7 @@ var Scene = class _Scene {
|
|
|
6990
7001
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
6991
7002
|
if (overridesUpdate && node.hasPendingAnimations === Entity.prototype.hasPendingAnimations) {
|
|
6992
7003
|
this._devWarn(
|
|
6993
|
-
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to
|
|
7004
|
+
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to slow the animation. Override hasPendingAnimations() to return true while motion is in flight.`
|
|
6994
7005
|
);
|
|
6995
7006
|
}
|
|
6996
7007
|
}
|
|
@@ -59,8 +59,8 @@ export declare class MSDFTextEntity extends Entity {
|
|
|
59
59
|
*
|
|
60
60
|
* Measured on Chromium and Firefox (2026-07-31) with a 600 ms atlas: the
|
|
61
61
|
* scene's own rAF loop never uploaded a decoded atlas in EITHER render mode.
|
|
62
|
-
* `onDemand` skips idle frames outright; `always` throttles to
|
|
63
|
-
* idle, so whether it recovers is down to whether a throttled tick happens to
|
|
62
|
+
* `onDemand` skips idle frames outright; `always` throttles to the idle FPS
|
|
63
|
+
* floor when idle, so whether it recovers is down to whether a throttled tick happens to
|
|
64
64
|
* land after the decode — Chromium got one, Firefox did not. Neither is a
|
|
65
65
|
* mechanism, which is why this listener exists rather than relying on the
|
|
66
66
|
* frame loop to come back around.
|
package/dist/text.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkXE6K7T5Sjs = require('./chunk-XE6K7T5S.js');
|
|
6
6
|
|
|
7
7
|
// src/text/index.ts
|
|
8
8
|
var _text = require('@vectojs/text'); _createStarExport(_text);
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
exports.MSDFTextEntity =
|
|
12
|
+
exports.MSDFTextEntity = _chunkXE6K7T5Sjs.MSDFTextEntity; exports.SVGEntity = _chunkXE6K7T5Sjs.SVGEntity;
|
package/dist/text.mjs
CHANGED
|
@@ -113,8 +113,8 @@ export declare class ComputeParticleEntity extends Entity {
|
|
|
113
113
|
* render-tree walk, but this entity is still a normal tree member that
|
|
114
114
|
* walk visits — without this override, the base `Entity.hasPendingAnimations()`
|
|
115
115
|
* (always `false`) is what Scene sees, so `renderMode: 'always'`'s idle
|
|
116
|
-
* auto-throttle drops the WHOLE scene to
|
|
117
|
-
* the tree is animating, even while thousands of particles are visibly
|
|
116
|
+
* auto-throttle drops the WHOLE scene to the idle FPS floor the instant
|
|
117
|
+
* nothing else in the tree is animating, even while thousands of particles are visibly
|
|
118
118
|
* drifting or spring-settling. A spring+damping system asymptotically
|
|
119
119
|
* approaches zero velocity but never reaches it exactly, so this checks
|
|
120
120
|
* against a small epsilon rather than `!== 0` — otherwise this would
|
package/dist/tree/Scene.d.ts
CHANGED
|
@@ -98,10 +98,22 @@ export interface SceneOptions {
|
|
|
98
98
|
*/
|
|
99
99
|
maxDPR?: number;
|
|
100
100
|
/**
|
|
101
|
-
* Enable automatic throttling
|
|
102
|
-
* and not marked dirty) to save power/CPU.
|
|
101
|
+
* Enable automatic throttling of the `'always'` loop when the scene is
|
|
102
|
+
* static (no active transitions and not marked dirty) to save power/CPU.
|
|
103
|
+
* The idle floor is 60 FPS by default; raise or lower it with
|
|
104
|
+
* {@link SceneOptions.idleFPS}. Default is `true`.
|
|
103
105
|
*/
|
|
104
106
|
autoThrottle?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Frame-rate floor for an idle `'always'` scene when
|
|
109
|
+
* {@link SceneOptions.autoThrottle} is on. Default `60` — an idle scene
|
|
110
|
+
* keeps animating smoothly instead of stuttering at the old 2 FPS floor.
|
|
111
|
+
* Set e.g. `2` to restore the aggressive deep sleep for battery-critical
|
|
112
|
+
* scenes (the developer's explicit choice); `0` means "keep the scene's
|
|
113
|
+
* `maxFPS` cadence while idle". Ignored when `autoThrottle` is `false` or
|
|
114
|
+
* `renderMode` is `'onDemand'` (onDemand already renders zero idle frames).
|
|
115
|
+
*/
|
|
116
|
+
idleFPS?: number;
|
|
105
117
|
/**
|
|
106
118
|
* Emit User Timing marks and measures for render phases. Default `false`.
|
|
107
119
|
* Intended for short profiler captures; enable only while collecting one.
|
|
@@ -196,8 +208,9 @@ export interface SceneOptions {
|
|
|
196
208
|
readingDirection?: 'ltr' | 'rtl';
|
|
197
209
|
/**
|
|
198
210
|
* When to repaint:
|
|
199
|
-
* - `'always'` (default): drive a continuous rAF loop, throttling to
|
|
200
|
-
*
|
|
211
|
+
* - `'always'` (default): drive a continuous rAF loop, throttling to the
|
|
212
|
+
* {@link SceneOptions.idleFPS} floor (default 60) while the scene is idle
|
|
213
|
+
* if {@link SceneOptions.autoThrottle} is on.
|
|
201
214
|
* - `'onDemand'`: paint only after {@link Scene.markDirty} (or an active
|
|
202
215
|
* transition), so a genuinely static scene costs zero frames.
|
|
203
216
|
*
|
|
@@ -217,14 +230,14 @@ export interface SceneOptions {
|
|
|
217
230
|
* plain untranspiled JS, gets no diagnostic at all. `renderMode` was a public
|
|
218
231
|
* field with no matching option for several releases, and four `@vectojs` demos
|
|
219
232
|
* shipped `new Scene(canvas, { renderMode: 'onDemand' })` — reading correctly,
|
|
220
|
-
* doing nothing, and sitting on the
|
|
233
|
+
* doing nothing, and sitting on the idle FPS floor.
|
|
221
234
|
*
|
|
222
235
|
* Kept as a literal rather than derived from a type: `keyof SceneOptions` does
|
|
223
236
|
* not survive to runtime, so this list is the only form a constructor can check
|
|
224
237
|
* against. A new option must be added here too — the test suite asserts the two
|
|
225
238
|
* stay in sync.
|
|
226
239
|
*/
|
|
227
|
-
export declare const SCENE_OPTION_KEYS: readonly ['a11ySyncInterval', 'autoThrottle', 'contentProjection', 'contentProjectionMargin', 'contentSemanticBudget', 'contentSemanticMargin', 'debugA11y', 'disableWindowResize', 'maxDPR', 'maxFPS', 'particleBackend', 'pointBackend', 'readingDirection', 'renderer', 'renderMode', 'respectReducedMotion', 'userTiming'];
|
|
240
|
+
export declare const SCENE_OPTION_KEYS: readonly ['a11ySyncInterval', 'autoThrottle', 'contentProjection', 'contentProjectionMargin', 'contentSemanticBudget', 'contentSemanticMargin', 'debugA11y', 'disableWindowResize', 'idleFPS', 'maxDPR', 'maxFPS', 'particleBackend', 'pointBackend', 'readingDirection', 'renderer', 'renderMode', 'respectReducedMotion', 'userTiming'];
|
|
228
241
|
/** Frame-rate the loop is capped to when the OS requests reduced motion. */
|
|
229
242
|
export declare const REDUCED_MOTION_FPS = 30;
|
|
230
243
|
export type { AcceleratorReason, AcceleratorStatus, AcceleratorReport };
|
|
@@ -406,8 +419,17 @@ export declare class Scene {
|
|
|
406
419
|
*/
|
|
407
420
|
private get dirty();
|
|
408
421
|
private set dirty(value);
|
|
409
|
-
/**
|
|
422
|
+
/**
|
|
423
|
+
* Whether to throttle the `'always'` loop when the scene is static to save
|
|
424
|
+
* power. The idle floor is {@link Scene.idleFPS} (default 60).
|
|
425
|
+
*/
|
|
410
426
|
autoThrottle: boolean;
|
|
427
|
+
/**
|
|
428
|
+
* Frame-rate floor for an idle `'always'` scene when {@link Scene.autoThrottle}
|
|
429
|
+
* is on. Default `60`. Set `2` for the legacy aggressive idle sleep, `0` to
|
|
430
|
+
* keep the scene's `maxFPS` cadence while idle.
|
|
431
|
+
*/
|
|
432
|
+
idleFPS: number;
|
|
411
433
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
412
434
|
private _lastFrameMs;
|
|
413
435
|
/** Rolling exponential average of rendered-frame intervals, in ms. */
|