@vectojs/core 1.9.2 → 1.11.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.
@@ -710,6 +710,25 @@ var Entity = (_class4 = class {
710
710
  handlers.forEach((h) => h(payload));
711
711
  }
712
712
  }
713
+ /**
714
+ * Programmatically focus the entity's projected a11y shadow element, if one
715
+ * exists. After `scene.add(entity)` the shadow element is typically created
716
+ * on the next a11y sync (within one animation frame), so this method retries
717
+ * once on the next rAF if the element isn't immediately available — matching
718
+ * the timing pattern the prior workaround described in findings.md achieved
719
+ * with `requestAnimationFrame(() => document.getElementById(id)?.focus())`.
720
+ */
721
+ focus() {
722
+ const el = _optionalChain([this, 'access', _57 => _57.scene, 'optionalAccess', _58 => _58.getA11yElement, 'call', _59 => _59(this.id)]);
723
+ if (el) {
724
+ el.focus();
725
+ return;
726
+ }
727
+ requestAnimationFrame(() => {
728
+ const retry = _optionalChain([this, 'access', _60 => _60.scene, 'optionalAccess', _61 => _61.getA11yElement, 'call', _62 => _62(this.id)]);
729
+ if (retry) retry.focus();
730
+ });
731
+ }
713
732
  /** Run one node's listeners for the event, honoring stopImmediatePropagation. */
714
733
  fireListeners(node, map, event) {
715
734
  const handlers = map.get(event.type);
@@ -1141,7 +1160,7 @@ var MSDFTextEntity = (_class6 = class extends Entity {
1141
1160
  if (res.seqId < this.lastRenderedSeqId) return;
1142
1161
  this.lastRenderedSeqId = res.seqId;
1143
1162
  this.layoutResult = res;
1144
- _optionalChain([this, 'access', _57 => _57.scene, 'optionalAccess', _58 => _58.markDirty, 'call', _59 => _59()]);
1163
+ _optionalChain([this, 'access', _63 => _63.scene, 'optionalAccess', _64 => _64.markDirty, 'call', _65 => _65()]);
1145
1164
  }
1146
1165
  });
1147
1166
  }
@@ -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
- const dpr = getDevicePixelRatio();
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 = getDevicePixelRatio();
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
- return {
1047
+ const renderer = {
1048
+ maxDPR: void 0,
1032
1049
  resize(width, height) {
1033
1050
  logicalW = width;
1034
1051
  logicalH = height;
1035
- dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio || 1 : 1;
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
@@ -710,6 +710,25 @@ var Entity = class {
710
710
  handlers.forEach((h) => h(payload));
711
711
  }
712
712
  }
713
+ /**
714
+ * Programmatically focus the entity's projected a11y shadow element, if one
715
+ * exists. After `scene.add(entity)` the shadow element is typically created
716
+ * on the next a11y sync (within one animation frame), so this method retries
717
+ * once on the next rAF if the element isn't immediately available — matching
718
+ * the timing pattern the prior workaround described in findings.md achieved
719
+ * with `requestAnimationFrame(() => document.getElementById(id)?.focus())`.
720
+ */
721
+ focus() {
722
+ const el = this.scene?.getA11yElement(this.id);
723
+ if (el) {
724
+ el.focus();
725
+ return;
726
+ }
727
+ requestAnimationFrame(() => {
728
+ const retry = this.scene?.getA11yElement(this.id);
729
+ if (retry) retry.focus();
730
+ });
731
+ }
713
732
  /** Run one node's listeners for the event, honoring stopImmediatePropagation. */
714
733
  fireListeners(node, map, event) {
715
734
  const handlers = map.get(event.type);
@@ -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
- const dpr = getDevicePixelRatio();
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 = getDevicePixelRatio();
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
- return {
1047
+ const renderer = {
1048
+ maxDPR: void 0,
1032
1049
  resize(width, height) {
1033
1050
  logicalW = width;
1034
1051
  logicalH = height;
1035
- dpr = typeof devicePixelRatio !== "undefined" ? devicePixelRatio || 1 : 1;
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