@vectojs/core 1.9.1 → 1.10.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-BPMNCGU7.js → chunk-ORCPCIJ7.js} +24 -5
- package/dist/{chunk-WT2XZHJQ.mjs → chunk-XZEPHCDZ.mjs} +24 -5
- package/dist/index.js +22 -13
- package/dist/index.mjs +13 -4
- package/dist/renderer/CanvasRenderer.d.ts +13 -1
- package/dist/renderer/WebGLPointRenderer.d.ts +12 -0
- package/dist/renderer.js +2 -2
- package/dist/renderer.mjs +1 -1
- package/dist/tree/DOMPortalEntity.d.ts +1 -1
- package/dist/tree/Scene.d.ts +17 -0
- package/package.json +1 -1
|
@@ -7,6 +7,15 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Cap on the effective device pixel ratio applied by the constructor and
|
|
12
|
+
* {@link resize}. `undefined` (default) uses the real, uncapped
|
|
13
|
+
* `devicePixelRatio` — unchanged from prior versions. Set directly, or via
|
|
14
|
+
* the constructor's third argument; `Scene` (see `SceneOptions.maxDPR`)
|
|
15
|
+
* keeps this in sync on every {@link resize} call, since the real DPR can
|
|
16
|
+
* change at runtime (e.g. a window dragged between displays).
|
|
17
|
+
*/
|
|
18
|
+
|
|
10
19
|
/**
|
|
11
20
|
* Max circles per batched `fill()`. A single Canvas 2D `fill()` over a path is
|
|
12
21
|
* superlinear in sub-path count, so an unbounded batch is *slower* than many
|
|
@@ -27,9 +36,11 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
27
36
|
* fullscreen canvas and sizes to the window — pass this for embedded /
|
|
28
37
|
* custom-container canvases (the Scene does when `disableWindowResize` is
|
|
29
38
|
* set) so the canvas's own dimensions aren't clobbered by the window's.
|
|
39
|
+
* @param maxDPR - See {@link maxDPR}.
|
|
30
40
|
*/
|
|
31
|
-
constructor(canvas, size) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
|
|
32
|
-
|
|
41
|
+
constructor(canvas, size, maxDPR) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);
|
|
42
|
+
this.maxDPR = maxDPR;
|
|
43
|
+
const dpr = this.effectiveDPR();
|
|
33
44
|
this.width = _nullishCoalesce(_optionalChain([size, 'optionalAccess', _ => _.width]), () => ( (typeof window !== "undefined" ? window.innerWidth : canvas.width || 0)));
|
|
34
45
|
this.height = _nullishCoalesce(_optionalChain([size, 'optionalAccess', _2 => _2.height]), () => ( (typeof window !== "undefined" ? window.innerHeight : canvas.height || 0)));
|
|
35
46
|
canvas.width = this.width * dpr;
|
|
@@ -51,6 +62,11 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
51
62
|
getContext() {
|
|
52
63
|
return this.ctx;
|
|
53
64
|
}
|
|
65
|
+
/** Real `devicePixelRatio`, clamped to {@link maxDPR} when set. */
|
|
66
|
+
effectiveDPR() {
|
|
67
|
+
const real = getDevicePixelRatio();
|
|
68
|
+
return this.maxDPR !== void 0 ? Math.min(real, this.maxDPR) : real;
|
|
69
|
+
}
|
|
54
70
|
/**
|
|
55
71
|
* Resize the backing canvas buffer and re-apply DPR scaling.
|
|
56
72
|
*
|
|
@@ -60,7 +76,7 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
60
76
|
* @param height - New logical height in CSS pixels.
|
|
61
77
|
*/
|
|
62
78
|
resize(width, height) {
|
|
63
|
-
const dpr =
|
|
79
|
+
const dpr = this.effectiveDPR();
|
|
64
80
|
this.width = width;
|
|
65
81
|
this.height = height;
|
|
66
82
|
this.ctx.canvas.width = width * dpr;
|
|
@@ -1028,11 +1044,13 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1028
1044
|
gl.bindVertexArray(null);
|
|
1029
1045
|
glyphCount = 0;
|
|
1030
1046
|
};
|
|
1031
|
-
|
|
1047
|
+
const renderer = {
|
|
1048
|
+
maxDPR: void 0,
|
|
1032
1049
|
resize(width, height) {
|
|
1033
1050
|
logicalW = width;
|
|
1034
1051
|
logicalH = height;
|
|
1035
|
-
|
|
1052
|
+
const realDpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio || 1 : 1;
|
|
1053
|
+
dpr = renderer.maxDPR !== void 0 ? Math.min(realDpr, renderer.maxDPR) : realDpr;
|
|
1036
1054
|
canvas.width = Math.round(width * dpr);
|
|
1037
1055
|
canvas.height = Math.round(height * dpr);
|
|
1038
1056
|
canvas.style.width = `${width}px`;
|
|
@@ -1290,6 +1308,7 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1290
1308
|
if (msdfTexture) gl.deleteTexture(msdfTexture);
|
|
1291
1309
|
}
|
|
1292
1310
|
};
|
|
1311
|
+
return renderer;
|
|
1293
1312
|
}
|
|
1294
1313
|
|
|
1295
1314
|
// src/renderer/WebGPUParticleSystemManager.ts
|
|
@@ -7,6 +7,15 @@ var CanvasRenderer = class _CanvasRenderer {
|
|
|
7
7
|
ctx;
|
|
8
8
|
width;
|
|
9
9
|
height;
|
|
10
|
+
/**
|
|
11
|
+
* Cap on the effective device pixel ratio applied by the constructor and
|
|
12
|
+
* {@link resize}. `undefined` (default) uses the real, uncapped
|
|
13
|
+
* `devicePixelRatio` — unchanged from prior versions. Set directly, or via
|
|
14
|
+
* the constructor's third argument; `Scene` (see `SceneOptions.maxDPR`)
|
|
15
|
+
* keeps this in sync on every {@link resize} call, since the real DPR can
|
|
16
|
+
* change at runtime (e.g. a window dragged between displays).
|
|
17
|
+
*/
|
|
18
|
+
maxDPR;
|
|
10
19
|
/**
|
|
11
20
|
* Max circles per batched `fill()`. A single Canvas 2D `fill()` over a path is
|
|
12
21
|
* superlinear in sub-path count, so an unbounded batch is *slower* than many
|
|
@@ -27,9 +36,11 @@ var CanvasRenderer = class _CanvasRenderer {
|
|
|
27
36
|
* fullscreen canvas and sizes to the window — pass this for embedded /
|
|
28
37
|
* custom-container canvases (the Scene does when `disableWindowResize` is
|
|
29
38
|
* set) so the canvas's own dimensions aren't clobbered by the window's.
|
|
39
|
+
* @param maxDPR - See {@link maxDPR}.
|
|
30
40
|
*/
|
|
31
|
-
constructor(canvas, size) {
|
|
32
|
-
|
|
41
|
+
constructor(canvas, size, maxDPR) {
|
|
42
|
+
this.maxDPR = maxDPR;
|
|
43
|
+
const dpr = this.effectiveDPR();
|
|
33
44
|
this.width = size?.width ?? (typeof window !== "undefined" ? window.innerWidth : canvas.width || 0);
|
|
34
45
|
this.height = size?.height ?? (typeof window !== "undefined" ? window.innerHeight : canvas.height || 0);
|
|
35
46
|
canvas.width = this.width * dpr;
|
|
@@ -51,6 +62,11 @@ var CanvasRenderer = class _CanvasRenderer {
|
|
|
51
62
|
getContext() {
|
|
52
63
|
return this.ctx;
|
|
53
64
|
}
|
|
65
|
+
/** Real `devicePixelRatio`, clamped to {@link maxDPR} when set. */
|
|
66
|
+
effectiveDPR() {
|
|
67
|
+
const real = getDevicePixelRatio();
|
|
68
|
+
return this.maxDPR !== void 0 ? Math.min(real, this.maxDPR) : real;
|
|
69
|
+
}
|
|
54
70
|
/**
|
|
55
71
|
* Resize the backing canvas buffer and re-apply DPR scaling.
|
|
56
72
|
*
|
|
@@ -60,7 +76,7 @@ var CanvasRenderer = class _CanvasRenderer {
|
|
|
60
76
|
* @param height - New logical height in CSS pixels.
|
|
61
77
|
*/
|
|
62
78
|
resize(width, height) {
|
|
63
|
-
const dpr =
|
|
79
|
+
const dpr = this.effectiveDPR();
|
|
64
80
|
this.width = width;
|
|
65
81
|
this.height = height;
|
|
66
82
|
this.ctx.canvas.width = width * dpr;
|
|
@@ -1028,11 +1044,13 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1028
1044
|
gl.bindVertexArray(null);
|
|
1029
1045
|
glyphCount = 0;
|
|
1030
1046
|
};
|
|
1031
|
-
|
|
1047
|
+
const renderer = {
|
|
1048
|
+
maxDPR: void 0,
|
|
1032
1049
|
resize(width, height) {
|
|
1033
1050
|
logicalW = width;
|
|
1034
1051
|
logicalH = height;
|
|
1035
|
-
|
|
1052
|
+
const realDpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio || 1 : 1;
|
|
1053
|
+
dpr = renderer.maxDPR !== void 0 ? Math.min(realDpr, renderer.maxDPR) : realDpr;
|
|
1036
1054
|
canvas.width = Math.round(width * dpr);
|
|
1037
1055
|
canvas.height = Math.round(height * dpr);
|
|
1038
1056
|
canvas.style.width = `${width}px`;
|
|
@@ -1290,6 +1308,7 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1290
1308
|
if (msdfTexture) gl.deleteTexture(msdfTexture);
|
|
1291
1309
|
}
|
|
1292
1310
|
};
|
|
1311
|
+
return renderer;
|
|
1293
1312
|
}
|
|
1294
1313
|
|
|
1295
1314
|
// src/renderer/WebGPUParticleSystemManager.ts
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var _chunkBA5HUUDFjs = require('./chunk-BA5HUUDF.js');
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var _chunkORCPCIJ7js = require('./chunk-ORCPCIJ7.js');
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
@@ -708,6 +708,8 @@ var Scene = (_class2 = class _Scene {
|
|
|
708
708
|
|
|
709
709
|
|
|
710
710
|
__init44() {this.disableWindowResize = false}
|
|
711
|
+
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
712
|
+
|
|
711
713
|
// WebGPU properties
|
|
712
714
|
__init45() {this.destroyed = false}
|
|
713
715
|
__init46() {this.device = null}
|
|
@@ -737,6 +739,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
737
739
|
this.canvas = canvas;
|
|
738
740
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
739
741
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
742
|
+
this.maxDPR = options.maxDPR;
|
|
740
743
|
if (this.disableWindowResize) {
|
|
741
744
|
const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _23 => _23.style, 'optionalAccess', _24 => _24.width]));
|
|
742
745
|
const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _25 => _25.style, 'optionalAccess', _26 => _26.height]));
|
|
@@ -775,9 +778,10 @@ var Scene = (_class2 = class _Scene {
|
|
|
775
778
|
if (options.renderer) {
|
|
776
779
|
this.renderer = options.renderer;
|
|
777
780
|
} else {
|
|
778
|
-
this.renderer = new (0,
|
|
781
|
+
this.renderer = new (0, _chunkORCPCIJ7js.CanvasRenderer)(
|
|
779
782
|
canvas,
|
|
780
|
-
this.disableWindowResize ? { width: this.width, height: this.height } : void 0
|
|
783
|
+
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
784
|
+
this.maxDPR
|
|
781
785
|
);
|
|
782
786
|
}
|
|
783
787
|
if (typeof document !== "undefined") {
|
|
@@ -903,6 +907,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
903
907
|
if (canvas.parentElement) canvas.parentElement.appendChild(gl);
|
|
904
908
|
const pr = _Scene.webglCreator ? _Scene.webglCreator(gl) : null;
|
|
905
909
|
if (pr) {
|
|
910
|
+
pr.maxDPR = this.maxDPR;
|
|
906
911
|
pr.resize(this.width, this.height);
|
|
907
912
|
this.glCanvas = gl;
|
|
908
913
|
this.pointRenderer = pr;
|
|
@@ -1409,7 +1414,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
1409
1414
|
this.syncOptionalAttribute(
|
|
1410
1415
|
el,
|
|
1411
1416
|
"href",
|
|
1412
|
-
attrs.href === void 0 ? void 0 :
|
|
1417
|
+
attrs.href === void 0 ? void 0 : _chunkORCPCIJ7js.sanitizeUrl.call(void 0, attrs.href)
|
|
1413
1418
|
);
|
|
1414
1419
|
this.syncOptionalAttribute(el, "target", attrs.target);
|
|
1415
1420
|
}
|
|
@@ -2419,7 +2424,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
2419
2424
|
* Export the current scene state to a lightweight, flat SVG XML string.
|
|
2420
2425
|
*/
|
|
2421
2426
|
toSVG() {
|
|
2422
|
-
const renderer = new (0,
|
|
2427
|
+
const renderer = new (0, _chunkORCPCIJ7js.SVGRenderer)(this.width, this.height);
|
|
2423
2428
|
this.render(renderer, 0, 0);
|
|
2424
2429
|
return renderer.toXMLString();
|
|
2425
2430
|
}
|
|
@@ -2431,9 +2436,13 @@ var Scene = (_class2 = class _Scene {
|
|
|
2431
2436
|
this.height = height;
|
|
2432
2437
|
this.contentFontEpoch++;
|
|
2433
2438
|
if (typeof this.renderer.resize === "function") {
|
|
2439
|
+
if ("maxDPR" in this.renderer) this.renderer.maxDPR = this.maxDPR;
|
|
2434
2440
|
this.renderer.resize(width, height);
|
|
2435
2441
|
}
|
|
2436
|
-
|
|
2442
|
+
if (this.pointRenderer) {
|
|
2443
|
+
this.pointRenderer.maxDPR = this.maxDPR;
|
|
2444
|
+
this.pointRenderer.resize(width, height);
|
|
2445
|
+
}
|
|
2437
2446
|
if (this.gpuCanvas) {
|
|
2438
2447
|
this.gpuCanvas.width = width;
|
|
2439
2448
|
this.gpuCanvas.height = height;
|
|
@@ -2766,7 +2775,7 @@ var GridTextEntity = (_class4 = class extends _chunkGKLTTGBRjs.Entity {
|
|
|
2766
2775
|
updateGrid(ascii) {
|
|
2767
2776
|
this.grid = ascii;
|
|
2768
2777
|
this.rows = ascii.length;
|
|
2769
|
-
this.cols = _optionalChain([ascii, 'access',
|
|
2778
|
+
this.cols = _optionalChain([ascii, 'access', _99 => _99[0], 'optionalAccess', _100 => _100.length]) || 0;
|
|
2770
2779
|
}
|
|
2771
2780
|
isPointInside(_globalX, _globalY) {
|
|
2772
2781
|
return false;
|
|
@@ -2876,7 +2885,7 @@ var SplineEntity = (_class5 = class extends _chunkGKLTTGBRjs.Entity {
|
|
|
2876
2885
|
this.width = this.bounds.width;
|
|
2877
2886
|
this.height = this.bounds.height;
|
|
2878
2887
|
const isGradient = (c) => c !== null && !Array.isArray(c);
|
|
2879
|
-
this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access',
|
|
2888
|
+
this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _101 => _101.doc, 'access', _102 => _102.equations, 'optionalAccess', _103 => _103.some, 'call', _104 => _104((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _105 => _105.doc, 'access', _106 => _106.paths, 'optionalAccess', _107 => _107.some, 'call', _108 => _108((p) => isGradient(p.color_rgb))]), () => ( false)));
|
|
2880
2889
|
this.interactive = true;
|
|
2881
2890
|
}
|
|
2882
2891
|
computeBounds() {
|
|
@@ -3296,7 +3305,7 @@ var SpatialHashGrid = (_class6 = class {
|
|
|
3296
3305
|
const keys = this.entityCells.get(id);
|
|
3297
3306
|
if (!keys) return;
|
|
3298
3307
|
for (const key of keys) {
|
|
3299
|
-
_optionalChain([this, 'access',
|
|
3308
|
+
_optionalChain([this, 'access', _109 => _109.grid, 'access', _110 => _110.get, 'call', _111 => _111(key), 'optionalAccess', _112 => _112.delete, 'call', _113 => _113(id)]);
|
|
3300
3309
|
}
|
|
3301
3310
|
this.entityCells.delete(id);
|
|
3302
3311
|
}
|
|
@@ -3407,7 +3416,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkGKLTTGBRjs.Entity {
|
|
|
3407
3416
|
if (!local) return false;
|
|
3408
3417
|
return local.x >= 0 && local.x <= w && local.y >= 0 && local.y <= h;
|
|
3409
3418
|
}
|
|
3410
|
-
add(
|
|
3419
|
+
add(..._children) {
|
|
3411
3420
|
console.warn(`DOMPortalEntity (${this.id}) is a leaf node. Child entities are not supported.`);
|
|
3412
3421
|
return this;
|
|
3413
3422
|
}
|
|
@@ -3432,8 +3441,8 @@ var DOMPortalEntity = (_class7 = class extends _chunkGKLTTGBRjs.Entity {
|
|
|
3432
3441
|
}, _class7);
|
|
3433
3442
|
|
|
3434
3443
|
// src/index.ts
|
|
3435
|
-
Scene.registerWebGLPointRendererCreator(
|
|
3436
|
-
Scene.registerWebGPUParticleSystemManager(
|
|
3444
|
+
Scene.registerWebGLPointRendererCreator(_chunkORCPCIJ7js.createWebGLPointRenderer);
|
|
3445
|
+
Scene.registerWebGPUParticleSystemManager(_chunkORCPCIJ7js.WebGPUParticleSystemManager);
|
|
3437
3446
|
|
|
3438
3447
|
|
|
3439
3448
|
|
|
@@ -3484,4 +3493,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkBPMNCGU7js.WebGPUParticleSystemM
|
|
|
3484
3493
|
|
|
3485
3494
|
|
|
3486
3495
|
|
|
3487
|
-
exports.ArabicShaper = _chunk4AR425ARjs.ArabicShaper; exports.BidiResolver = _chunk4AR425ARjs.BidiResolver; exports.CanvasRenderer =
|
|
3496
|
+
exports.ArabicShaper = _chunk4AR425ARjs.ArabicShaper; exports.BidiResolver = _chunk4AR425ARjs.BidiResolver; exports.CanvasRenderer = _chunkORCPCIJ7js.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkGKLTTGBRjs.Easing; exports.Entity = _chunkGKLTTGBRjs.Entity; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.LayoutEngine = _chunkBA5HUUDFjs.LayoutEngine; exports.LayoutResultBuffer = _chunkBA5HUUDFjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunk4AR425ARjs.LayoutWorkerManager; exports.MSDFFont = _chunkGKLTTGBRjs.MSDFFont; exports.MSDFTextEntity = _chunkGKLTTGBRjs.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.Rect = Rect; exports.SVGEntity = _chunkGKLTTGBRjs.SVGEntity; exports.SVGRenderer = _chunkORCPCIJ7js.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkGKLTTGBRjs.SpringDriver; exports.SpringPhysics = _chunkGKLTTGBRjs.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkGKLTTGBRjs.TweenDriver; exports.VectoJSEvent = _chunkGKLTTGBRjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkORCPCIJ7js.WebGPUParticleSystemManager; exports.clearCssLineBoxMetrics = _chunkGKLTTGBRjs.clearCssLineBoxMetrics; exports.computeLineSegments = _chunkBA5HUUDFjs.computeLineSegments; exports.createCanvasMeasurer = _chunkBA5HUUDFjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkORCPCIJ7js.createWebGLPointRenderer; exports.cssLineBoxBaseline = _chunkGKLTTGBRjs.cssLineBoxBaseline; exports.isSafeUrl = _chunkORCPCIJ7js.isSafeUrl; exports.isTweenConfig = _chunkGKLTTGBRjs.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkORCPCIJ7js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.prepareContentGrid = _chunkGKLTTGBRjs.prepareContentGrid; exports.sanitizeUrl = _chunkORCPCIJ7js.sanitizeUrl;
|
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isSafeUrl,
|
|
13
13
|
parseColorToRGBA,
|
|
14
14
|
sanitizeUrl
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-XZEPHCDZ.mjs";
|
|
16
16
|
import {
|
|
17
17
|
Easing,
|
|
18
18
|
Entity,
|
|
@@ -708,6 +708,8 @@ var Scene = class _Scene {
|
|
|
708
708
|
width;
|
|
709
709
|
height;
|
|
710
710
|
disableWindowResize = false;
|
|
711
|
+
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
712
|
+
maxDPR;
|
|
711
713
|
// WebGPU properties
|
|
712
714
|
destroyed = false;
|
|
713
715
|
device = null;
|
|
@@ -737,6 +739,7 @@ var Scene = class _Scene {
|
|
|
737
739
|
this.canvas = canvas;
|
|
738
740
|
this.debugA11y = options.debugA11y ?? false;
|
|
739
741
|
this.disableWindowResize = options.disableWindowResize ?? false;
|
|
742
|
+
this.maxDPR = options.maxDPR;
|
|
740
743
|
if (this.disableWindowResize) {
|
|
741
744
|
const styleWidth = parseInlinePx(canvas.style?.width);
|
|
742
745
|
const styleHeight = parseInlinePx(canvas.style?.height);
|
|
@@ -777,7 +780,8 @@ var Scene = class _Scene {
|
|
|
777
780
|
} else {
|
|
778
781
|
this.renderer = new CanvasRenderer(
|
|
779
782
|
canvas,
|
|
780
|
-
this.disableWindowResize ? { width: this.width, height: this.height } : void 0
|
|
783
|
+
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
784
|
+
this.maxDPR
|
|
781
785
|
);
|
|
782
786
|
}
|
|
783
787
|
if (typeof document !== "undefined") {
|
|
@@ -903,6 +907,7 @@ var Scene = class _Scene {
|
|
|
903
907
|
if (canvas.parentElement) canvas.parentElement.appendChild(gl);
|
|
904
908
|
const pr = _Scene.webglCreator ? _Scene.webglCreator(gl) : null;
|
|
905
909
|
if (pr) {
|
|
910
|
+
pr.maxDPR = this.maxDPR;
|
|
906
911
|
pr.resize(this.width, this.height);
|
|
907
912
|
this.glCanvas = gl;
|
|
908
913
|
this.pointRenderer = pr;
|
|
@@ -2431,9 +2436,13 @@ var Scene = class _Scene {
|
|
|
2431
2436
|
this.height = height;
|
|
2432
2437
|
this.contentFontEpoch++;
|
|
2433
2438
|
if (typeof this.renderer.resize === "function") {
|
|
2439
|
+
if ("maxDPR" in this.renderer) this.renderer.maxDPR = this.maxDPR;
|
|
2434
2440
|
this.renderer.resize(width, height);
|
|
2435
2441
|
}
|
|
2436
|
-
this.pointRenderer
|
|
2442
|
+
if (this.pointRenderer) {
|
|
2443
|
+
this.pointRenderer.maxDPR = this.maxDPR;
|
|
2444
|
+
this.pointRenderer.resize(width, height);
|
|
2445
|
+
}
|
|
2437
2446
|
if (this.gpuCanvas) {
|
|
2438
2447
|
this.gpuCanvas.width = width;
|
|
2439
2448
|
this.gpuCanvas.height = height;
|
|
@@ -3407,7 +3416,7 @@ var DOMPortalEntity = class extends Entity {
|
|
|
3407
3416
|
if (!local) return false;
|
|
3408
3417
|
return local.x >= 0 && local.x <= w && local.y >= 0 && local.y <= h;
|
|
3409
3418
|
}
|
|
3410
|
-
add(
|
|
3419
|
+
add(..._children) {
|
|
3411
3420
|
console.warn(`DOMPortalEntity (${this.id}) is a leaf node. Child entities are not supported.`);
|
|
3412
3421
|
return this;
|
|
3413
3422
|
}
|
|
@@ -3,6 +3,15 @@ export declare class CanvasRenderer implements IRenderer {
|
|
|
3
3
|
private ctx;
|
|
4
4
|
private width;
|
|
5
5
|
private height;
|
|
6
|
+
/**
|
|
7
|
+
* Cap on the effective device pixel ratio applied by the constructor and
|
|
8
|
+
* {@link resize}. `undefined` (default) uses the real, uncapped
|
|
9
|
+
* `devicePixelRatio` — unchanged from prior versions. Set directly, or via
|
|
10
|
+
* the constructor's third argument; `Scene` (see `SceneOptions.maxDPR`)
|
|
11
|
+
* keeps this in sync on every {@link resize} call, since the real DPR can
|
|
12
|
+
* change at runtime (e.g. a window dragged between displays).
|
|
13
|
+
*/
|
|
14
|
+
maxDPR?: number;
|
|
6
15
|
/**
|
|
7
16
|
* Max circles per batched `fill()`. A single Canvas 2D `fill()` over a path is
|
|
8
17
|
* superlinear in sub-path count, so an unbounded batch is *slower* than many
|
|
@@ -21,11 +30,12 @@ export declare class CanvasRenderer implements IRenderer {
|
|
|
21
30
|
* fullscreen canvas and sizes to the window — pass this for embedded /
|
|
22
31
|
* custom-container canvases (the Scene does when `disableWindowResize` is
|
|
23
32
|
* set) so the canvas's own dimensions aren't clobbered by the window's.
|
|
33
|
+
* @param maxDPR - See {@link maxDPR}.
|
|
24
34
|
*/
|
|
25
35
|
constructor(canvas: HTMLCanvasElement, size?: {
|
|
26
36
|
width: number;
|
|
27
37
|
height: number;
|
|
28
|
-
});
|
|
38
|
+
}, maxDPR?: number);
|
|
29
39
|
/**
|
|
30
40
|
* Expose the underlying `CanvasRenderingContext2D` for operations not
|
|
31
41
|
* covered by the {@link IRenderer} interface.
|
|
@@ -33,6 +43,8 @@ export declare class CanvasRenderer implements IRenderer {
|
|
|
33
43
|
* @returns The raw 2D rendering context.
|
|
34
44
|
*/
|
|
35
45
|
getContext(): CanvasRenderingContext2D;
|
|
46
|
+
/** Real `devicePixelRatio`, clamped to {@link maxDPR} when set. */
|
|
47
|
+
private effectiveDPR;
|
|
36
48
|
/**
|
|
37
49
|
* Resize the backing canvas buffer and re-apply DPR scaling.
|
|
38
50
|
*
|
|
@@ -7,6 +7,18 @@
|
|
|
7
7
|
export interface PointRenderer {
|
|
8
8
|
/** Resize the backing buffer + GL viewport to a logical `w × h` (DPR applied). */
|
|
9
9
|
resize(width: number, height: number): void;
|
|
10
|
+
/**
|
|
11
|
+
* Cap on the effective device pixel ratio applied by {@link resize}.
|
|
12
|
+
* `undefined` (default) uses the real, uncapped `devicePixelRatio`. Set
|
|
13
|
+
* before calling `resize()` for it to take effect on that call (matches
|
|
14
|
+
* {@link import('../tree/Scene').SceneOptions.maxDPR} — `Scene` sets this
|
|
15
|
+
* once at construction and again before every `resize()` call, since a
|
|
16
|
+
* factory function has no other way to receive the option: the WebGL point
|
|
17
|
+
* layer's creator is a plain `(canvas) => PointRenderer` registered once by
|
|
18
|
+
* `@vectojs/core`'s module init, with no room for a per-Scene constructor
|
|
19
|
+
* argument).
|
|
20
|
+
*/
|
|
21
|
+
maxDPR?: number;
|
|
10
22
|
/** Begin a frame: reset the accumulated primitive buffers. */
|
|
11
23
|
begin(): void;
|
|
12
24
|
/** Add one circle in world (CSS-pixel) coordinates; `alpha` multiplies the color's. */
|
package/dist/renderer.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkORCPCIJ7js = require('./chunk-ORCPCIJ7.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
exports.CanvasRenderer =
|
|
14
|
+
exports.CanvasRenderer = _chunkORCPCIJ7js.CanvasRenderer; exports.SVGRenderer = _chunkORCPCIJ7js.SVGRenderer; exports.WebGPUParticleSystemManager = _chunkORCPCIJ7js.WebGPUParticleSystemManager; exports.createWebGLPointRenderer = _chunkORCPCIJ7js.createWebGLPointRenderer; exports.parseColorToRGBA = _chunkORCPCIJ7js.parseColorToRGBA;
|
package/dist/renderer.mjs
CHANGED
|
@@ -13,7 +13,7 @@ export declare class DOMPortalEntity extends Entity {
|
|
|
13
13
|
lastOpacity: string;
|
|
14
14
|
constructor(domElement: HTMLElement, width?: number, height?: number, id?: string);
|
|
15
15
|
isPointInside(globalX: number, globalY: number): boolean;
|
|
16
|
-
add(
|
|
16
|
+
add(..._children: Entity[]): this;
|
|
17
17
|
render(): void;
|
|
18
18
|
destroy(): void;
|
|
19
19
|
}
|
package/dist/tree/Scene.d.ts
CHANGED
|
@@ -70,6 +70,21 @@ export interface SceneOptions {
|
|
|
70
70
|
* Useful when Vecto is running inside a custom layout container or offscreen canvas.
|
|
71
71
|
*/
|
|
72
72
|
disableWindowResize?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Cap the effective device pixel ratio used to size the Canvas2D and WebGL
|
|
75
|
+
* point-layer backing stores. `undefined` (default) reads the real,
|
|
76
|
+
* uncapped `window.devicePixelRatio` — unchanged from prior versions.
|
|
77
|
+
* Backing-store render cost scales with `logical size × dpr²`, so a
|
|
78
|
+
* full-screen HiDPI scene (`pointBackend: 'webgl'` in particular) can
|
|
79
|
+
* overrun its frame budget on a DPR-3 display while running fine on the
|
|
80
|
+
* DPR-1 dev machine it was tuned on (findings.md, 2026-07-16). `maxDPR: 2`
|
|
81
|
+
* keeps the display retina-crisp (2x already exceeds what most eyes
|
|
82
|
+
* resolve) while roughly halving the backing-store pixel count at DPR 3.
|
|
83
|
+
* Applied at construction and re-applied on every {@link resize} call
|
|
84
|
+
* (including the automatic window-resize listener), since the real DPR
|
|
85
|
+
* can change at runtime (a window dragged between displays).
|
|
86
|
+
*/
|
|
87
|
+
maxDPR?: number;
|
|
73
88
|
/**
|
|
74
89
|
* Enable automatic throttling to 2 FPS when the scene is static (no active transitions
|
|
75
90
|
* and not marked dirty) to save power/CPU. Default is `true`.
|
|
@@ -196,6 +211,8 @@ export declare class Scene {
|
|
|
196
211
|
width: number;
|
|
197
212
|
height: number;
|
|
198
213
|
private disableWindowResize;
|
|
214
|
+
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
215
|
+
maxDPR?: number;
|
|
199
216
|
private destroyed;
|
|
200
217
|
private device;
|
|
201
218
|
private deviceLost;
|