@vectojs/core 1.26.0 → 1.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-KHGHP2J3.js → chunk-K2UGEIT6.js} +58 -6
- package/dist/{chunk-I4WQY7CJ.mjs → chunk-TI5EMJGL.mjs} +52 -0
- package/dist/index.js +47 -10
- package/dist/index.mjs +43 -6
- package/dist/renderer/IRenderer.d.ts +22 -0
- package/dist/renderer.js +8 -2
- package/dist/renderer.mjs +9 -3
- package/dist/tree/Scene.d.ts +26 -2
- package/package.json +1 -1
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5;const __vecto_cjs_url=require("url").pathToFileURL(__filename).href;
|
|
2
2
|
|
|
3
|
+
// src/renderer/IRenderer.ts
|
|
4
|
+
var RENDERER_STYLE_PROPERTY_HINTS = {
|
|
5
|
+
globalAlpha: "setGlobalAlpha(alpha)",
|
|
6
|
+
strokeStyle: "stroke(color, lineWidth)",
|
|
7
|
+
lineWidth: "stroke(color, lineWidth)",
|
|
8
|
+
fillStyle: "fill(color) \u2014 or fillText(text, x, y, font, color)",
|
|
9
|
+
font: "fillText(text, x, y, font, color)",
|
|
10
|
+
lineCap: "stroke(color, lineWidth) (cap is backend-chosen)",
|
|
11
|
+
lineJoin: "stroke(color, lineWidth) (join is backend-chosen)",
|
|
12
|
+
globalCompositeOperation: "no equivalent \u2014 composite via a separate canvas",
|
|
13
|
+
shadowBlur: "no equivalent \u2014 draw the shadow explicitly",
|
|
14
|
+
shadowColor: "no equivalent \u2014 draw the shadow explicitly",
|
|
15
|
+
textAlign: "no equivalent \u2014 measure and offset x yourself",
|
|
16
|
+
textBaseline: "no equivalent \u2014 measure and offset y yourself"
|
|
17
|
+
};
|
|
18
|
+
var rendererDevMode = false;
|
|
19
|
+
function setRendererDevMode(active) {
|
|
20
|
+
rendererDevMode = active;
|
|
21
|
+
}
|
|
22
|
+
function isRendererDevMode() {
|
|
23
|
+
if (rendererDevMode) return true;
|
|
24
|
+
const g = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
25
|
+
if (_optionalChain([g, 'optionalAccess', _ => _.__DEV__])) return true;
|
|
26
|
+
return _optionalChain([g, 'optionalAccess', _2 => _2.process, 'optionalAccess', _3 => _3.env, 'optionalAccess', _4 => _4.NODE_ENV]) === "development";
|
|
27
|
+
}
|
|
28
|
+
function installRendererDevTraps(renderer, label) {
|
|
29
|
+
if (!isRendererDevMode()) return;
|
|
30
|
+
for (const [prop, hint] of Object.entries(RENDERER_STYLE_PROPERTY_HINTS)) {
|
|
31
|
+
if (prop in renderer) continue;
|
|
32
|
+
let stored;
|
|
33
|
+
let warned = false;
|
|
34
|
+
Object.defineProperty(renderer, prop, {
|
|
35
|
+
configurable: true,
|
|
36
|
+
enumerable: false,
|
|
37
|
+
get: () => stored,
|
|
38
|
+
set: (value) => {
|
|
39
|
+
stored = value;
|
|
40
|
+
if (warned) return;
|
|
41
|
+
warned = true;
|
|
42
|
+
console.warn(
|
|
43
|
+
`[vectojs/dev] \`${prop}\` is not a renderer property \u2014 assigning it on ${label} has no effect on what is drawn. Call \`${hint}\` instead.`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
3
50
|
// src/renderer/CanvasRenderer.ts
|
|
4
51
|
function emptyDrawCounters() {
|
|
5
52
|
return {
|
|
@@ -79,8 +126,8 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
79
126
|
constructor(canvas, size, maxDPR) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);
|
|
80
127
|
this.maxDPR = maxDPR;
|
|
81
128
|
const dpr = this.effectiveDPR();
|
|
82
|
-
this.width = _nullishCoalesce(_optionalChain([size, 'optionalAccess',
|
|
83
|
-
this.height = _nullishCoalesce(_optionalChain([size, 'optionalAccess',
|
|
129
|
+
this.width = _nullishCoalesce(_optionalChain([size, 'optionalAccess', _5 => _5.width]), () => ( (typeof window !== "undefined" ? window.innerWidth : canvas.width || 0)));
|
|
130
|
+
this.height = _nullishCoalesce(_optionalChain([size, 'optionalAccess', _6 => _6.height]), () => ( (typeof window !== "undefined" ? window.innerHeight : canvas.height || 0)));
|
|
84
131
|
canvas.width = this.width * dpr;
|
|
85
132
|
canvas.height = this.height * dpr;
|
|
86
133
|
if (canvas.style) {
|
|
@@ -92,6 +139,7 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
92
139
|
if (ctx) ctx.scale(dpr, dpr);
|
|
93
140
|
this.canvas = canvas;
|
|
94
141
|
this.setupContextLossRecovery();
|
|
142
|
+
installRendererDevTraps(this, "CanvasRenderer");
|
|
95
143
|
}
|
|
96
144
|
/** Register a callback fired after a lost 2D context is restored + re-scaled,
|
|
97
145
|
* so the owner can repaint (the restored canvas comes back cleared). */
|
|
@@ -122,7 +170,7 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
122
170
|
this.batchActive = false;
|
|
123
171
|
this.batchCount = 0;
|
|
124
172
|
this.contextLost = false;
|
|
125
|
-
_optionalChain([this, 'access',
|
|
173
|
+
_optionalChain([this, 'access', _7 => _7.contextRestoredCb, 'optionalCall', _8 => _8()]);
|
|
126
174
|
});
|
|
127
175
|
}
|
|
128
176
|
/**
|
|
@@ -491,6 +539,7 @@ var SVGRenderer = (_class2 = class {
|
|
|
491
539
|
constructor(width, height) {;_class2.prototype.__init12.call(this);_class2.prototype.__init13.call(this);_class2.prototype.__init14.call(this);_class2.prototype.__init15.call(this);_class2.prototype.__init16.call(this);_class2.prototype.__init17.call(this);_class2.prototype.__init18.call(this);_class2.prototype.__init19.call(this);_class2.prototype.__init20.call(this);_class2.prototype.__init21.call(this);_class2.prototype.__init22.call(this);_class2.prototype.__init23.call(this);_class2.prototype.__init24.call(this);_class2.prototype.__init25.call(this);_class2.prototype.__init26.call(this);_class2.prototype.__init27.call(this);_class2.prototype.__init28.call(this);_class2.prototype.__init29.call(this);_class2.prototype.__init30.call(this);_class2.prototype.__init31.call(this);_class2.prototype.__init32.call(this);_class2.prototype.__init33.call(this);_class2.prototype.__init34.call(this);
|
|
492
540
|
this.width = width;
|
|
493
541
|
this.height = height;
|
|
542
|
+
installRendererDevTraps(this, "SVGRenderer");
|
|
494
543
|
}
|
|
495
544
|
clear() {
|
|
496
545
|
this.buffer = [];
|
|
@@ -712,8 +761,8 @@ var SVGRenderer = (_class2 = class {
|
|
|
712
761
|
}
|
|
713
762
|
drawImage(source, dx, dy, dw, dh) {
|
|
714
763
|
this.flush();
|
|
715
|
-
const fromCanvas2 = typeof _optionalChain([source, 'optionalAccess',
|
|
716
|
-
const rawHref = fromCanvas2 ? source.toDataURL() : _optionalChain([source, 'optionalAccess',
|
|
764
|
+
const fromCanvas2 = typeof _optionalChain([source, 'optionalAccess', _9 => _9.toDataURL]) === "function";
|
|
765
|
+
const rawHref = fromCanvas2 ? source.toDataURL() : _optionalChain([source, 'optionalAccess', _10 => _10.src]) || "";
|
|
717
766
|
const href = fromCanvas2 && this.isSafeRasterDataUrl(rawHref) ? rawHref : sanitizeUrl(String(rawHref));
|
|
718
767
|
const transformStr = `matrix(${this.ma},${this.mb},${this.mc},${this.md},${this.me},${this.mf})`;
|
|
719
768
|
if (href) {
|
|
@@ -2285,4 +2334,7 @@ var TextRasterCache = (_class5 = class {
|
|
|
2285
2334
|
|
|
2286
2335
|
|
|
2287
2336
|
|
|
2288
|
-
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
exports.setRendererDevMode = setRendererDevMode; exports.isRendererDevMode = isRendererDevMode; exports.installRendererDevTraps = installRendererDevTraps; exports.CanvasRenderer = CanvasRenderer; exports.sanitizeUrl = sanitizeUrl; exports.isSafeUrl = isSafeUrl; exports.SVGRenderer = SVGRenderer; exports.parseColorToRGBA = parseColorToRGBA; exports.createWebGLPointRenderer = createWebGLPointRenderer; exports.WebGPUParticleSystemManager = WebGPUParticleSystemManager; exports.GlyphRasterAtlas = GlyphRasterAtlas; exports.TextRasterCache = TextRasterCache;
|
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
// src/renderer/IRenderer.ts
|
|
2
|
+
var RENDERER_STYLE_PROPERTY_HINTS = {
|
|
3
|
+
globalAlpha: "setGlobalAlpha(alpha)",
|
|
4
|
+
strokeStyle: "stroke(color, lineWidth)",
|
|
5
|
+
lineWidth: "stroke(color, lineWidth)",
|
|
6
|
+
fillStyle: "fill(color) \u2014 or fillText(text, x, y, font, color)",
|
|
7
|
+
font: "fillText(text, x, y, font, color)",
|
|
8
|
+
lineCap: "stroke(color, lineWidth) (cap is backend-chosen)",
|
|
9
|
+
lineJoin: "stroke(color, lineWidth) (join is backend-chosen)",
|
|
10
|
+
globalCompositeOperation: "no equivalent \u2014 composite via a separate canvas",
|
|
11
|
+
shadowBlur: "no equivalent \u2014 draw the shadow explicitly",
|
|
12
|
+
shadowColor: "no equivalent \u2014 draw the shadow explicitly",
|
|
13
|
+
textAlign: "no equivalent \u2014 measure and offset x yourself",
|
|
14
|
+
textBaseline: "no equivalent \u2014 measure and offset y yourself"
|
|
15
|
+
};
|
|
16
|
+
var rendererDevMode = false;
|
|
17
|
+
function setRendererDevMode(active) {
|
|
18
|
+
rendererDevMode = active;
|
|
19
|
+
}
|
|
20
|
+
function isRendererDevMode() {
|
|
21
|
+
if (rendererDevMode) return true;
|
|
22
|
+
const g = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
23
|
+
if (g?.__DEV__) return true;
|
|
24
|
+
return g?.process?.env?.NODE_ENV === "development";
|
|
25
|
+
}
|
|
26
|
+
function installRendererDevTraps(renderer, label) {
|
|
27
|
+
if (!isRendererDevMode()) return;
|
|
28
|
+
for (const [prop, hint] of Object.entries(RENDERER_STYLE_PROPERTY_HINTS)) {
|
|
29
|
+
if (prop in renderer) continue;
|
|
30
|
+
let stored;
|
|
31
|
+
let warned = false;
|
|
32
|
+
Object.defineProperty(renderer, prop, {
|
|
33
|
+
configurable: true,
|
|
34
|
+
enumerable: false,
|
|
35
|
+
get: () => stored,
|
|
36
|
+
set: (value) => {
|
|
37
|
+
stored = value;
|
|
38
|
+
if (warned) return;
|
|
39
|
+
warned = true;
|
|
40
|
+
console.warn(
|
|
41
|
+
`[vectojs/dev] \`${prop}\` is not a renderer property \u2014 assigning it on ${label} has no effect on what is drawn. Call \`${hint}\` instead.`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
1
48
|
// src/renderer/CanvasRenderer.ts
|
|
2
49
|
function emptyDrawCounters() {
|
|
3
50
|
return {
|
|
@@ -90,6 +137,7 @@ var CanvasRenderer = class _CanvasRenderer {
|
|
|
90
137
|
if (ctx) ctx.scale(dpr, dpr);
|
|
91
138
|
this.canvas = canvas;
|
|
92
139
|
this.setupContextLossRecovery();
|
|
140
|
+
installRendererDevTraps(this, "CanvasRenderer");
|
|
93
141
|
}
|
|
94
142
|
/** Register a callback fired after a lost 2D context is restored + re-scaled,
|
|
95
143
|
* so the owner can repaint (the restored canvas comes back cleared). */
|
|
@@ -489,6 +537,7 @@ var SVGRenderer = class {
|
|
|
489
537
|
constructor(width, height) {
|
|
490
538
|
this.width = width;
|
|
491
539
|
this.height = height;
|
|
540
|
+
installRendererDevTraps(this, "SVGRenderer");
|
|
492
541
|
}
|
|
493
542
|
clear() {
|
|
494
543
|
this.buffer = [];
|
|
@@ -2274,6 +2323,9 @@ var TextRasterCache = class {
|
|
|
2274
2323
|
};
|
|
2275
2324
|
|
|
2276
2325
|
export {
|
|
2326
|
+
setRendererDevMode,
|
|
2327
|
+
isRendererDevMode,
|
|
2328
|
+
installRendererDevTraps,
|
|
2277
2329
|
CanvasRenderer,
|
|
2278
2330
|
sanitizeUrl,
|
|
2279
2331
|
isSafeUrl,
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var _chunkK2UGEIT6js = require('./chunk-K2UGEIT6.js');
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
|
|
@@ -2840,10 +2843,26 @@ var Scene = (_class7 = class _Scene {
|
|
|
2840
2843
|
//
|
|
2841
2844
|
// Checks run once every ~120 frames (~2s at 60fps) to keep overhead
|
|
2842
2845
|
// negligible even when dev mode is on.
|
|
2843
|
-
|
|
2844
|
-
|
|
2846
|
+
static __initStatic5() {this._devMode = false}
|
|
2847
|
+
/**
|
|
2848
|
+
* Toggle development-mode runtime warnings globally.
|
|
2849
|
+
*
|
|
2850
|
+
* An accessor rather than a plain field so the renderer layer learns about it
|
|
2851
|
+
* immediately: renderers cannot import `Scene` (the dependency runs
|
|
2852
|
+
* `Scene → renderer`), and their diagnostics are installed per instance at
|
|
2853
|
+
* construction. A plain field would only reach them the next time a `Scene`
|
|
2854
|
+
* happened to be built, which made a directly-constructed `CanvasRenderer`
|
|
2855
|
+
* silently untrapped.
|
|
2856
|
+
*/
|
|
2857
|
+
static get devMode() {
|
|
2858
|
+
return _Scene._devMode;
|
|
2859
|
+
}
|
|
2860
|
+
static set devMode(active) {
|
|
2861
|
+
_Scene._devMode = active;
|
|
2862
|
+
_chunkK2UGEIT6js.setRendererDevMode.call(void 0, active);
|
|
2863
|
+
}
|
|
2845
2864
|
static _devModeDetected() {
|
|
2846
|
-
if (_Scene.
|
|
2865
|
+
if (_Scene._devMode) return true;
|
|
2847
2866
|
const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
2848
2867
|
if (_optionalChain([gp, 'optionalAccess', _41 => _41.__DEV__])) return true;
|
|
2849
2868
|
if (_optionalChain([gp, 'optionalAccess', _42 => _42.process, 'optionalAccess', _43 => _43.env, 'optionalAccess', _44 => _44.NODE_ENV]) === "development") return true;
|
|
@@ -2952,6 +2971,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2952
2971
|
this.readingDirection = _nullishCoalesce(options.readingDirection, () => ( "ltr"));
|
|
2953
2972
|
this.renderMode = _nullishCoalesce(options.renderMode, () => ( "always"));
|
|
2954
2973
|
this._devActive = _Scene._devModeDetected();
|
|
2974
|
+
_chunkK2UGEIT6js.setRendererDevMode.call(void 0, this._devActive);
|
|
2955
2975
|
this._warnUnknownOptions(options);
|
|
2956
2976
|
this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
2957
2977
|
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
@@ -2979,7 +2999,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2979
2999
|
if (options.renderer) {
|
|
2980
3000
|
this.renderer = options.renderer;
|
|
2981
3001
|
} else {
|
|
2982
|
-
this.renderer = new (0,
|
|
3002
|
+
this.renderer = new (0, _chunkK2UGEIT6js.CanvasRenderer)(
|
|
2983
3003
|
canvas,
|
|
2984
3004
|
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
2985
3005
|
this.maxDPR
|
|
@@ -3620,10 +3640,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
3620
3640
|
* resume when it returns — instead of running the full update/render every
|
|
3621
3641
|
* frame for a scene nobody can see. No-op (stays "on screen") where
|
|
3622
3642
|
* `IntersectionObserver` is unavailable, so SSR/jsdom behavior is unchanged.
|
|
3643
|
+
*
|
|
3644
|
+
* Also a no-op for a canvas that is not in the document. An offscreen canvas
|
|
3645
|
+
* used purely as a texture source — `@vectojs/three`'s `ThreeAdapter` wraps
|
|
3646
|
+
* one in a `CanvasTexture`, and the same pattern shows up in any
|
|
3647
|
+
* render-to-texture setup — is never appended anywhere, and an
|
|
3648
|
+
* `IntersectionObserver` reports a detached element as not intersecting.
|
|
3649
|
+
* Observing it would therefore set `_canvasOnScreen = false` on the first
|
|
3650
|
+
* callback, and since {@link loop} returns without rescheduling in that
|
|
3651
|
+
* state, the loop would stop permanently: the only resume path is an
|
|
3652
|
+
* `isIntersecting` transition, which a detached element can never produce.
|
|
3653
|
+
* Such a canvas is always "visible" as far as this scene is concerned,
|
|
3654
|
+
* because whether its output is seen depends on the consumer sampling the
|
|
3655
|
+
* texture, which this scene cannot observe.
|
|
3623
3656
|
*/
|
|
3624
3657
|
watchCanvasVisibility() {
|
|
3625
3658
|
if (this._canvasObserver || typeof IntersectionObserver === "undefined") return;
|
|
3626
3659
|
if (!this.canvas || typeof this.canvas.getBoundingClientRect !== "function") return;
|
|
3660
|
+
if (this.canvas.isConnected === false) return;
|
|
3627
3661
|
this._canvasObserver = new IntersectionObserver((entries) => {
|
|
3628
3662
|
const entry = entries[entries.length - 1];
|
|
3629
3663
|
if (!entry) return;
|
|
@@ -4054,7 +4088,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
4054
4088
|
this.syncOptionalAttribute(
|
|
4055
4089
|
el,
|
|
4056
4090
|
"href",
|
|
4057
|
-
attrs.href === void 0 ? void 0 :
|
|
4091
|
+
attrs.href === void 0 ? void 0 : _chunkK2UGEIT6js.sanitizeUrl.call(void 0, attrs.href)
|
|
4058
4092
|
);
|
|
4059
4093
|
this.syncOptionalAttribute(el, "target", attrs.target);
|
|
4060
4094
|
}
|
|
@@ -5489,7 +5523,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
5489
5523
|
* Export the current scene state to a lightweight, flat SVG XML string.
|
|
5490
5524
|
*/
|
|
5491
5525
|
toSVG() {
|
|
5492
|
-
const renderer = new (0,
|
|
5526
|
+
const renderer = new (0, _chunkK2UGEIT6js.SVGRenderer)(this.width, this.height);
|
|
5493
5527
|
this.render(renderer, 0, 0);
|
|
5494
5528
|
return renderer.toXMLString();
|
|
5495
5529
|
}
|
|
@@ -6550,8 +6584,11 @@ var DOMPortalEntity = (_class11 = class extends _chunkZ3HFY75Rjs.Entity {
|
|
|
6550
6584
|
}, _class11);
|
|
6551
6585
|
|
|
6552
6586
|
// src/index.ts
|
|
6553
|
-
Scene.registerWebGLPointRendererCreator(
|
|
6554
|
-
Scene.registerWebGPUParticleSystemManager(
|
|
6587
|
+
Scene.registerWebGLPointRendererCreator(_chunkK2UGEIT6js.createWebGLPointRenderer);
|
|
6588
|
+
Scene.registerWebGPUParticleSystemManager(_chunkK2UGEIT6js.WebGPUParticleSystemManager);
|
|
6589
|
+
|
|
6590
|
+
|
|
6591
|
+
|
|
6555
6592
|
|
|
6556
6593
|
|
|
6557
6594
|
|
|
@@ -6592,4 +6629,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkKHGHP2J3js.WebGPUParticleSystemM
|
|
|
6592
6629
|
|
|
6593
6630
|
|
|
6594
6631
|
|
|
6595
|
-
exports.CanvasRenderer =
|
|
6632
|
+
exports.CanvasRenderer = _chunkK2UGEIT6js.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkZ3HFY75Rjs.Entity; exports.GlyphRasterAtlas = _chunkK2UGEIT6js.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkZ3HFY75Rjs.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 = _chunkZ3HFY75Rjs.SVGEntity; exports.SVGRenderer = _chunkK2UGEIT6js.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkK2UGEIT6js.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkZ3HFY75Rjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkK2UGEIT6js.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.createWebGLPointRenderer = _chunkK2UGEIT6js.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.installRendererDevTraps = _chunkK2UGEIT6js.installRendererDevTraps; exports.isRendererDevMode = _chunkK2UGEIT6js.isRendererDevMode; exports.isSafeUrl = _chunkK2UGEIT6js.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkK2UGEIT6js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkK2UGEIT6js.sanitizeUrl; exports.setRendererDevMode = _chunkK2UGEIT6js.setRendererDevMode;
|
package/dist/index.mjs
CHANGED
|
@@ -5,10 +5,13 @@ import {
|
|
|
5
5
|
TextRasterCache,
|
|
6
6
|
WebGPUParticleSystemManager,
|
|
7
7
|
createWebGLPointRenderer,
|
|
8
|
+
installRendererDevTraps,
|
|
9
|
+
isRendererDevMode,
|
|
8
10
|
isSafeUrl,
|
|
9
11
|
parseColorToRGBA,
|
|
10
|
-
sanitizeUrl
|
|
11
|
-
|
|
12
|
+
sanitizeUrl,
|
|
13
|
+
setRendererDevMode
|
|
14
|
+
} from "./chunk-TI5EMJGL.mjs";
|
|
12
15
|
import {
|
|
13
16
|
Entity,
|
|
14
17
|
MSDFTextEntity,
|
|
@@ -2839,10 +2842,26 @@ var Scene = class _Scene {
|
|
|
2839
2842
|
//
|
|
2840
2843
|
// Checks run once every ~120 frames (~2s at 60fps) to keep overhead
|
|
2841
2844
|
// negligible even when dev mode is on.
|
|
2842
|
-
|
|
2843
|
-
|
|
2845
|
+
static _devMode = false;
|
|
2846
|
+
/**
|
|
2847
|
+
* Toggle development-mode runtime warnings globally.
|
|
2848
|
+
*
|
|
2849
|
+
* An accessor rather than a plain field so the renderer layer learns about it
|
|
2850
|
+
* immediately: renderers cannot import `Scene` (the dependency runs
|
|
2851
|
+
* `Scene → renderer`), and their diagnostics are installed per instance at
|
|
2852
|
+
* construction. A plain field would only reach them the next time a `Scene`
|
|
2853
|
+
* happened to be built, which made a directly-constructed `CanvasRenderer`
|
|
2854
|
+
* silently untrapped.
|
|
2855
|
+
*/
|
|
2856
|
+
static get devMode() {
|
|
2857
|
+
return _Scene._devMode;
|
|
2858
|
+
}
|
|
2859
|
+
static set devMode(active) {
|
|
2860
|
+
_Scene._devMode = active;
|
|
2861
|
+
setRendererDevMode(active);
|
|
2862
|
+
}
|
|
2844
2863
|
static _devModeDetected() {
|
|
2845
|
-
if (_Scene.
|
|
2864
|
+
if (_Scene._devMode) return true;
|
|
2846
2865
|
const gp = typeof globalThis !== "undefined" ? globalThis : void 0;
|
|
2847
2866
|
if (gp?.__DEV__) return true;
|
|
2848
2867
|
if (gp?.process?.env?.NODE_ENV === "development") return true;
|
|
@@ -2951,6 +2970,7 @@ var Scene = class _Scene {
|
|
|
2951
2970
|
this.readingDirection = options.readingDirection ?? "ltr";
|
|
2952
2971
|
this.renderMode = options.renderMode ?? "always";
|
|
2953
2972
|
this._devActive = _Scene._devModeDetected();
|
|
2973
|
+
setRendererDevMode(this._devActive);
|
|
2954
2974
|
this._warnUnknownOptions(options);
|
|
2955
2975
|
this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
2956
2976
|
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
@@ -3619,10 +3639,24 @@ var Scene = class _Scene {
|
|
|
3619
3639
|
* resume when it returns — instead of running the full update/render every
|
|
3620
3640
|
* frame for a scene nobody can see. No-op (stays "on screen") where
|
|
3621
3641
|
* `IntersectionObserver` is unavailable, so SSR/jsdom behavior is unchanged.
|
|
3642
|
+
*
|
|
3643
|
+
* Also a no-op for a canvas that is not in the document. An offscreen canvas
|
|
3644
|
+
* used purely as a texture source — `@vectojs/three`'s `ThreeAdapter` wraps
|
|
3645
|
+
* one in a `CanvasTexture`, and the same pattern shows up in any
|
|
3646
|
+
* render-to-texture setup — is never appended anywhere, and an
|
|
3647
|
+
* `IntersectionObserver` reports a detached element as not intersecting.
|
|
3648
|
+
* Observing it would therefore set `_canvasOnScreen = false` on the first
|
|
3649
|
+
* callback, and since {@link loop} returns without rescheduling in that
|
|
3650
|
+
* state, the loop would stop permanently: the only resume path is an
|
|
3651
|
+
* `isIntersecting` transition, which a detached element can never produce.
|
|
3652
|
+
* Such a canvas is always "visible" as far as this scene is concerned,
|
|
3653
|
+
* because whether its output is seen depends on the consumer sampling the
|
|
3654
|
+
* texture, which this scene cannot observe.
|
|
3622
3655
|
*/
|
|
3623
3656
|
watchCanvasVisibility() {
|
|
3624
3657
|
if (this._canvasObserver || typeof IntersectionObserver === "undefined") return;
|
|
3625
3658
|
if (!this.canvas || typeof this.canvas.getBoundingClientRect !== "function") return;
|
|
3659
|
+
if (this.canvas.isConnected === false) return;
|
|
3626
3660
|
this._canvasObserver = new IntersectionObserver((entries) => {
|
|
3627
3661
|
const entry = entries[entries.length - 1];
|
|
3628
3662
|
if (!entry) return;
|
|
@@ -6585,10 +6619,13 @@ export {
|
|
|
6585
6619
|
beginVectoUserTiming,
|
|
6586
6620
|
createWebGLPointRenderer,
|
|
6587
6621
|
endVectoUserTiming,
|
|
6622
|
+
installRendererDevTraps,
|
|
6623
|
+
isRendererDevMode,
|
|
6588
6624
|
isSafeUrl,
|
|
6589
6625
|
loadSpline,
|
|
6590
6626
|
measureVectoUserTiming,
|
|
6591
6627
|
parseColorToRGBA,
|
|
6592
6628
|
polySegmentToBezier,
|
|
6593
|
-
sanitizeUrl
|
|
6629
|
+
sanitizeUrl,
|
|
6630
|
+
setRendererDevMode
|
|
6594
6631
|
};
|
|
@@ -299,3 +299,25 @@ export interface IRenderer {
|
|
|
299
299
|
*/
|
|
300
300
|
onContextRestored?(cb: () => void): void;
|
|
301
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Publish dev-mode state to the renderer layer. Called by `Scene`; also usable
|
|
304
|
+
* directly when a renderer is constructed without one.
|
|
305
|
+
*/
|
|
306
|
+
export declare function setRendererDevMode(active: boolean): void;
|
|
307
|
+
/** Whether renderer dev diagnostics are currently enabled. */
|
|
308
|
+
export declare function isRendererDevMode(): boolean;
|
|
309
|
+
/**
|
|
310
|
+
* Install dev-mode-only accessors that warn when Canvas2D style *properties* are
|
|
311
|
+
* assigned on a renderer instead of calling the corresponding method.
|
|
312
|
+
*
|
|
313
|
+
* Call once per renderer instance, from its constructor. No-ops outside dev
|
|
314
|
+
* mode, so the accessors never exist in production.
|
|
315
|
+
* Each trapped property warns on its **first** write only — a per-frame
|
|
316
|
+
* assignment would otherwise flood the console at 240fps — and then stores and
|
|
317
|
+
* returns the value like a plain field, so a warned write is never a hard break
|
|
318
|
+
* for code that assigns and reads back.
|
|
319
|
+
*
|
|
320
|
+
* Skips any property the instance genuinely defines, so a backend that really
|
|
321
|
+
* does expose one keeps its own behavior.
|
|
322
|
+
*/
|
|
323
|
+
export declare function installRendererDevTraps(renderer: object, label: string): void;
|
package/dist/renderer.js
CHANGED
|
@@ -7,13 +7,19 @@
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var _chunkKHGHP2J3js = require('./chunk-KHGHP2J3.js');
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
|
|
13
|
+
var _chunkK2UGEIT6js = require('./chunk-K2UGEIT6.js');
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
exports.CanvasRenderer = _chunkK2UGEIT6js.CanvasRenderer; exports.GlyphRasterAtlas = _chunkK2UGEIT6js.GlyphRasterAtlas; exports.SVGRenderer = _chunkK2UGEIT6js.SVGRenderer; exports.TextRasterCache = _chunkK2UGEIT6js.TextRasterCache; exports.WebGPUParticleSystemManager = _chunkK2UGEIT6js.WebGPUParticleSystemManager; exports.createWebGLPointRenderer = _chunkK2UGEIT6js.createWebGLPointRenderer; exports.installRendererDevTraps = _chunkK2UGEIT6js.installRendererDevTraps; exports.isRendererDevMode = _chunkK2UGEIT6js.isRendererDevMode; exports.parseColorToRGBA = _chunkK2UGEIT6js.parseColorToRGBA; exports.setRendererDevMode = _chunkK2UGEIT6js.setRendererDevMode;
|
package/dist/renderer.mjs
CHANGED
|
@@ -5,8 +5,11 @@ import {
|
|
|
5
5
|
TextRasterCache,
|
|
6
6
|
WebGPUParticleSystemManager,
|
|
7
7
|
createWebGLPointRenderer,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
installRendererDevTraps,
|
|
9
|
+
isRendererDevMode,
|
|
10
|
+
parseColorToRGBA,
|
|
11
|
+
setRendererDevMode
|
|
12
|
+
} from "./chunk-TI5EMJGL.mjs";
|
|
10
13
|
export {
|
|
11
14
|
CanvasRenderer,
|
|
12
15
|
GlyphRasterAtlas,
|
|
@@ -14,5 +17,8 @@ export {
|
|
|
14
17
|
TextRasterCache,
|
|
15
18
|
WebGPUParticleSystemManager,
|
|
16
19
|
createWebGLPointRenderer,
|
|
17
|
-
|
|
20
|
+
installRendererDevTraps,
|
|
21
|
+
isRendererDevMode,
|
|
22
|
+
parseColorToRGBA,
|
|
23
|
+
setRendererDevMode
|
|
18
24
|
};
|
package/dist/tree/Scene.d.ts
CHANGED
|
@@ -979,8 +979,19 @@ export declare class Scene {
|
|
|
979
979
|
private pointerEventTarget;
|
|
980
980
|
private hasWarnedZeroSize;
|
|
981
981
|
private fontLoadHandler;
|
|
982
|
-
|
|
983
|
-
|
|
982
|
+
private static _devMode;
|
|
983
|
+
/**
|
|
984
|
+
* Toggle development-mode runtime warnings globally.
|
|
985
|
+
*
|
|
986
|
+
* An accessor rather than a plain field so the renderer layer learns about it
|
|
987
|
+
* immediately: renderers cannot import `Scene` (the dependency runs
|
|
988
|
+
* `Scene → renderer`), and their diagnostics are installed per instance at
|
|
989
|
+
* construction. A plain field would only reach them the next time a `Scene`
|
|
990
|
+
* happened to be built, which made a directly-constructed `CanvasRenderer`
|
|
991
|
+
* silently untrapped.
|
|
992
|
+
*/
|
|
993
|
+
static get devMode(): boolean;
|
|
994
|
+
static set devMode(active: boolean);
|
|
984
995
|
private static _devModeDetected;
|
|
985
996
|
private _devActive;
|
|
986
997
|
private _devFrameCount;
|
|
@@ -1157,6 +1168,19 @@ export declare class Scene {
|
|
|
1157
1168
|
* resume when it returns — instead of running the full update/render every
|
|
1158
1169
|
* frame for a scene nobody can see. No-op (stays "on screen") where
|
|
1159
1170
|
* `IntersectionObserver` is unavailable, so SSR/jsdom behavior is unchanged.
|
|
1171
|
+
*
|
|
1172
|
+
* Also a no-op for a canvas that is not in the document. An offscreen canvas
|
|
1173
|
+
* used purely as a texture source — `@vectojs/three`'s `ThreeAdapter` wraps
|
|
1174
|
+
* one in a `CanvasTexture`, and the same pattern shows up in any
|
|
1175
|
+
* render-to-texture setup — is never appended anywhere, and an
|
|
1176
|
+
* `IntersectionObserver` reports a detached element as not intersecting.
|
|
1177
|
+
* Observing it would therefore set `_canvasOnScreen = false` on the first
|
|
1178
|
+
* callback, and since {@link loop} returns without rescheduling in that
|
|
1179
|
+
* state, the loop would stop permanently: the only resume path is an
|
|
1180
|
+
* `isIntersecting` transition, which a detached element can never produce.
|
|
1181
|
+
* Such a canvas is always "visible" as far as this scene is concerned,
|
|
1182
|
+
* because whether its output is seen depends on the consumer sampling the
|
|
1183
|
+
* texture, which this scene cannot observe.
|
|
1160
1184
|
*/
|
|
1161
1185
|
private watchCanvasVisibility;
|
|
1162
1186
|
/**
|