@vectojs/core 1.38.1 → 1.39.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-QVTCKWDO.mjs → chunk-7PYD5UDX.mjs} +93 -43
- package/dist/{chunk-ZYYP2M5D.js → chunk-KRUDTGNR.js} +168 -76
- package/dist/{chunk-SRXU3ZXK.js → chunk-POPXUPKR.js} +141 -91
- package/dist/{chunk-LWEMD34D.mjs → chunk-RUM2KEDI.mjs} +119 -27
- package/dist/index.js +686 -395
- package/dist/index.mjs +372 -81
- package/dist/renderer/CanvasRenderer.d.ts +6 -0
- package/dist/renderer/SVGRenderer.d.ts +17 -2
- package/dist/renderer/WebGPUParticleSystemManager.d.ts +2 -0
- package/dist/renderer.js +2 -2
- package/dist/renderer.mjs +1 -1
- package/dist/text/MSDFTextEntity.d.ts +0 -1
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +8 -2
- package/dist/tree/Scene.d.ts +106 -0
- package/dist/tree/scene/A11yProjectionManager.d.ts +12 -0
- package/dist/tree/scene/HitTester.d.ts +14 -2
- package/dist/tree/scene/WasmBackendFacade.d.ts +17 -0
- package/dist/tree/scene/keyboard.d.ts +56 -0
- package/dist/wasm/backend.d.ts +7 -7
- package/dist/wasm/vectojs_core.wasm +0 -0
- package/package.json +5 -5
|
@@ -109,17 +109,28 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
109
109
|
__init7() {this.batchCount = 0}
|
|
110
110
|
__init8() {this._cachedFont = ""}
|
|
111
111
|
__init9() {this._cachedFill = ""}
|
|
112
|
+
// Stroke-side counterparts of the fill/font caches, read by stroke()'s
|
|
113
|
+
// style-elision branch. Reset wherever the context state can change behind
|
|
114
|
+
// our back: restore(), resize(), contextrestored, dispose().
|
|
115
|
+
__init10() {this._cachedStroke = ""}
|
|
116
|
+
__init11() {this._cachedLineWidth = -1}
|
|
117
|
+
__init12() {this._cachedLineCap = ""}
|
|
118
|
+
__init13() {this._cachedLineJoin = ""}
|
|
119
|
+
// Context-loss listeners, held for removal in dispose() so a canvas that
|
|
120
|
+
// outlives the renderer cannot retain it through these closures.
|
|
121
|
+
|
|
122
|
+
|
|
112
123
|
/** Backend discriminator; see {@link IRenderer.kind}. */
|
|
113
|
-
|
|
124
|
+
__init14() {this.kind = "canvas2d"}
|
|
114
125
|
/**
|
|
115
126
|
* Draw counters, allocated only once counting is enabled.
|
|
116
127
|
*
|
|
117
128
|
* Null when off, so the guard on every op is a single null test and an inactive
|
|
118
129
|
* renderer carries no counter object at all.
|
|
119
130
|
*/
|
|
120
|
-
|
|
131
|
+
__init15() {this.counters = null}
|
|
121
132
|
/** Accumulated primitive area, kept separately so the ratio is derived on read. */
|
|
122
|
-
|
|
133
|
+
__init16() {this.drawnArea = 0}
|
|
123
134
|
/**
|
|
124
135
|
* @param canvas - The target canvas. Its backing store is resized to the
|
|
125
136
|
* logical size × devicePixelRatio.
|
|
@@ -129,7 +140,7 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
129
140
|
* set) so the canvas's own dimensions aren't clobbered by the window's.
|
|
130
141
|
* @param maxDPR - See {@link maxDPR}.
|
|
131
142
|
*/
|
|
132
|
-
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);_class.prototype.__init12.call(this);
|
|
143
|
+
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);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);
|
|
133
144
|
this.maxDPR = maxDPR;
|
|
134
145
|
const dpr = this.effectiveDPR();
|
|
135
146
|
this.appliedDPR = dpr;
|
|
@@ -162,11 +173,11 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
162
173
|
*/
|
|
163
174
|
setupContextLossRecovery() {
|
|
164
175
|
if (typeof this.canvas.addEventListener !== "function") return;
|
|
165
|
-
this.
|
|
176
|
+
this._onContextLost = (e) => {
|
|
166
177
|
e.preventDefault();
|
|
167
178
|
this.contextLost = true;
|
|
168
|
-
}
|
|
169
|
-
this.
|
|
179
|
+
};
|
|
180
|
+
this._onContextRestored = () => {
|
|
170
181
|
const ctx = this.canvas.getContext("2d");
|
|
171
182
|
if (!ctx) return;
|
|
172
183
|
this.ctx = ctx;
|
|
@@ -176,11 +187,17 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
176
187
|
ctx.scale(restoredDPR, restoredDPR);
|
|
177
188
|
this._cachedFont = "";
|
|
178
189
|
this._cachedFill = "";
|
|
190
|
+
this._cachedStroke = "";
|
|
191
|
+
this._cachedLineWidth = -1;
|
|
192
|
+
this._cachedLineCap = "";
|
|
193
|
+
this._cachedLineJoin = "";
|
|
179
194
|
this.batchActive = false;
|
|
180
195
|
this.batchCount = 0;
|
|
181
196
|
this.contextLost = false;
|
|
182
197
|
_optionalChain([this, 'access', _8 => _8.contextRestoredCb, 'optionalCall', _9 => _9()]);
|
|
183
|
-
}
|
|
198
|
+
};
|
|
199
|
+
this.canvas.addEventListener("contextlost", this._onContextLost);
|
|
200
|
+
this.canvas.addEventListener("contextrestored", this._onContextRestored);
|
|
184
201
|
}
|
|
185
202
|
/**
|
|
186
203
|
* Expose the underlying `CanvasRenderingContext2D` for operations not
|
|
@@ -230,11 +247,17 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
230
247
|
this.height = height;
|
|
231
248
|
this.ctx.canvas.width = width * dpr;
|
|
232
249
|
this.ctx.canvas.height = height * dpr;
|
|
233
|
-
this.ctx.canvas.style
|
|
234
|
-
|
|
250
|
+
if (this.ctx.canvas.style) {
|
|
251
|
+
this.ctx.canvas.style.width = `${width}px`;
|
|
252
|
+
this.ctx.canvas.style.height = `${height}px`;
|
|
253
|
+
}
|
|
235
254
|
this.ctx.scale(dpr, dpr);
|
|
236
255
|
this._cachedFont = "";
|
|
237
256
|
this._cachedFill = "";
|
|
257
|
+
this._cachedStroke = "";
|
|
258
|
+
this._cachedLineWidth = -1;
|
|
259
|
+
this._cachedLineCap = "";
|
|
260
|
+
this._cachedLineJoin = "";
|
|
238
261
|
this.batchActive = false;
|
|
239
262
|
this.batchCount = 0;
|
|
240
263
|
}
|
|
@@ -288,6 +311,10 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
288
311
|
this.ctx.restore();
|
|
289
312
|
this._cachedFont = "";
|
|
290
313
|
this._cachedFill = "";
|
|
314
|
+
this._cachedStroke = "";
|
|
315
|
+
this._cachedLineWidth = -1;
|
|
316
|
+
this._cachedLineCap = "";
|
|
317
|
+
this._cachedLineJoin = "";
|
|
291
318
|
}
|
|
292
319
|
/** @inheritdoc */
|
|
293
320
|
translate(x, y) {
|
|
@@ -412,10 +439,17 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
412
439
|
stroke(color, lineWidth = 1) {
|
|
413
440
|
this.flush();
|
|
414
441
|
if (this.counters) this.counters.strokes++;
|
|
415
|
-
this.
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
442
|
+
if (this._cachedStroke !== color || this._cachedLineWidth !== lineWidth || this._cachedLineCap !== "round" || this._cachedLineJoin !== "round") {
|
|
443
|
+
if (this.counters) this.counters.stateSwitches++;
|
|
444
|
+
this.ctx.strokeStyle = color;
|
|
445
|
+
this.ctx.lineWidth = lineWidth;
|
|
446
|
+
this.ctx.lineCap = "round";
|
|
447
|
+
this.ctx.lineJoin = "round";
|
|
448
|
+
this._cachedStroke = color;
|
|
449
|
+
this._cachedLineWidth = lineWidth;
|
|
450
|
+
this._cachedLineCap = "round";
|
|
451
|
+
this._cachedLineJoin = "round";
|
|
452
|
+
}
|
|
419
453
|
this.ctx.stroke();
|
|
420
454
|
}
|
|
421
455
|
/** @inheritdoc */
|
|
@@ -454,6 +488,17 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
454
488
|
this.batchActive = false;
|
|
455
489
|
this._cachedFont = "";
|
|
456
490
|
this._cachedFill = "";
|
|
491
|
+
this._cachedStroke = "";
|
|
492
|
+
this._cachedLineWidth = -1;
|
|
493
|
+
this._cachedLineCap = "";
|
|
494
|
+
this._cachedLineJoin = "";
|
|
495
|
+
if (typeof this.canvas.removeEventListener === "function") {
|
|
496
|
+
if (this._onContextLost) this.canvas.removeEventListener("contextlost", this._onContextLost);
|
|
497
|
+
if (this._onContextRestored)
|
|
498
|
+
this.canvas.removeEventListener("contextrestored", this._onContextRestored);
|
|
499
|
+
}
|
|
500
|
+
this._onContextLost = void 0;
|
|
501
|
+
this._onContextRestored = void 0;
|
|
457
502
|
}
|
|
458
503
|
}, _class.__initStatic(), _class);
|
|
459
504
|
|
|
@@ -476,9 +521,13 @@ function hasSafeSchemeOrIsRelative(url) {
|
|
|
476
521
|
return SAFE_SCHEMES.has(`${candidate.toLowerCase()}:`);
|
|
477
522
|
}
|
|
478
523
|
var CHAR_REF = /&(?:#\d+|#x[\da-f]+|colon|tab|newline);/i;
|
|
524
|
+
var MAX_CODE_POINT = 1114111;
|
|
525
|
+
function decodeCodePoint(value) {
|
|
526
|
+
return value <= MAX_CODE_POINT ? String.fromCodePoint(value) : "\uFFFD";
|
|
527
|
+
}
|
|
479
528
|
function decodeCharacterReferences(value) {
|
|
480
529
|
if (value.indexOf("&") < 0 || !CHAR_REF.test(value)) return value;
|
|
481
|
-
return value.replace(/&#x([\da-f]+);/gi, (_, hex) =>
|
|
530
|
+
return value.replace(/&#x([\da-f]+);/gi, (_, hex) => decodeCodePoint(parseInt(hex, 16))).replace(/&#(\d+);/g, (_, dec) => decodeCodePoint(parseInt(dec, 10))).replace(/:/gi, ":").replace(/&tab;/gi, " ").replace(/&newline;/gi, "\n");
|
|
482
531
|
}
|
|
483
532
|
function sanitizeUrl(href) {
|
|
484
533
|
if (typeof href !== "string") return "";
|
|
@@ -545,44 +594,47 @@ function fontFamilyFromShorthand(font, sizeToken) {
|
|
|
545
594
|
}
|
|
546
595
|
var SVGRenderer = (_class2 = class {
|
|
547
596
|
/** Backend discriminator; see {@link IRenderer.kind}. */
|
|
548
|
-
|
|
597
|
+
__init17() {this.kind = "svg"}
|
|
549
598
|
|
|
550
599
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
600
|
+
__init18() {this.buffer = []}
|
|
601
|
+
__init19() {this.defsBuffer = []}
|
|
602
|
+
__init20() {this.currentPath = []}
|
|
554
603
|
// Inline matrix states (3x3 representation)
|
|
555
604
|
// [a, b, c, d, e, f] corresponding to:
|
|
556
605
|
// | a c e |
|
|
557
606
|
// | b d f |
|
|
558
607
|
// | 0 0 1 |
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
608
|
+
__init21() {this.mStack = []}
|
|
609
|
+
__init22() {this.ma = 1}
|
|
610
|
+
__init23() {this.mb = 0}
|
|
611
|
+
__init24() {this.mc = 0}
|
|
612
|
+
__init25() {this.md = 1}
|
|
613
|
+
__init26() {this.me = 0}
|
|
614
|
+
__init27() {this.mf = 0}
|
|
566
615
|
// Alpha stack
|
|
567
|
-
|
|
568
|
-
|
|
616
|
+
__init28() {this.alphaStack = []}
|
|
617
|
+
__init29() {this.globalAlpha = 1}
|
|
569
618
|
// Clipping stack
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
619
|
+
__init30() {this.clipDepthStack = []}
|
|
620
|
+
__init31() {this.clipDepth = 0}
|
|
621
|
+
__init32() {this.clipCounter = 0}
|
|
573
622
|
// uniquely identifies clipPaths
|
|
574
623
|
// Batch circles states (local coordinates)
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
624
|
+
__init33() {this.batchCircles = []}
|
|
625
|
+
__init34() {this.batchMatrix = [1, 0, 0, 1, 0, 0]}
|
|
626
|
+
__init35() {this.batchColor = ""}
|
|
627
|
+
__init36() {this.batchAlpha = 1}
|
|
628
|
+
__init37() {this.batchActive = false}
|
|
580
629
|
// Cache for generated gradient defs
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
630
|
+
__init38() {this.gradientCounter = 0}
|
|
631
|
+
__init39() {this.gradientCache = /* @__PURE__ */ new Map()}
|
|
632
|
+
/** Root font size used to resolve `em`/`rem` font sizes (default 16px). */
|
|
633
|
+
|
|
634
|
+
constructor(width, height, options) {;_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);_class2.prototype.__init35.call(this);_class2.prototype.__init36.call(this);_class2.prototype.__init37.call(this);_class2.prototype.__init38.call(this);_class2.prototype.__init39.call(this);
|
|
584
635
|
this.width = width;
|
|
585
636
|
this.height = height;
|
|
637
|
+
this.rootFontSize = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _10 => _10.rootFontSize]), () => ( 16));
|
|
586
638
|
installRendererDevTraps(this, "SVGRenderer");
|
|
587
639
|
}
|
|
588
640
|
clear() {
|
|
@@ -770,12 +822,22 @@ var SVGRenderer = (_class2 = class {
|
|
|
770
822
|
`<path d="${dStr}" transform="${transformStr}" fill="none" stroke="${strokeVal}" stroke-width="${lineWidth}" stroke-opacity="${this.globalAlpha}" />`
|
|
771
823
|
);
|
|
772
824
|
}
|
|
825
|
+
/**
|
|
826
|
+
* Emit a `<text>` element for a text run.
|
|
827
|
+
*
|
|
828
|
+
* Font-size unit handling: `px` sizes pass through; `em` and `rem` are both
|
|
829
|
+
* scaled against the renderer's `rootFontSize` (constructor option, default
|
|
830
|
+
* 16 — matching the browser default, not necessarily the host page's root,
|
|
831
|
+
* so pass `{ rootFontSize }` when exporting against a non-default root).
|
|
832
|
+
* A percentage size (`'100% Inter'`) has no absolute meaning in this
|
|
833
|
+
* context and silently falls back to the default 16px font size.
|
|
834
|
+
*/
|
|
773
835
|
fillText(text, x, y, font, color) {
|
|
774
836
|
this.flush();
|
|
775
837
|
const sizeToken = parseFontSizeToken(font);
|
|
776
838
|
let fontSize = sizeToken ? sizeToken.value : 16;
|
|
777
|
-
if (sizeToken && sizeToken.unit
|
|
778
|
-
fontSize = fontSize *
|
|
839
|
+
if (sizeToken && (sizeToken.unit === "em" || sizeToken.unit === "rem")) {
|
|
840
|
+
fontSize = fontSize * this.rootFontSize;
|
|
779
841
|
}
|
|
780
842
|
const lowerFont = font.toLowerCase();
|
|
781
843
|
const fontStyle = lowerFont.includes("italic") ? "italic" : lowerFont.includes("oblique") ? "oblique" : "normal";
|
|
@@ -805,8 +867,8 @@ var SVGRenderer = (_class2 = class {
|
|
|
805
867
|
}
|
|
806
868
|
drawImage(source, dx, dy, dw, dh) {
|
|
807
869
|
this.flush();
|
|
808
|
-
const fromCanvas2 = typeof _optionalChain([source, 'optionalAccess',
|
|
809
|
-
const rawHref = fromCanvas2 ? source.toDataURL() : _optionalChain([source, 'optionalAccess',
|
|
870
|
+
const fromCanvas2 = typeof _optionalChain([source, 'optionalAccess', _11 => _11.toDataURL]) === "function";
|
|
871
|
+
const rawHref = fromCanvas2 ? source.toDataURL() : _optionalChain([source, 'optionalAccess', _12 => _12.src]) || "";
|
|
810
872
|
const href = fromCanvas2 && this.isSafeRasterDataUrl(rawHref) ? rawHref : sanitizeUrl(String(rawHref));
|
|
811
873
|
const transformStr = `matrix(${this.ma},${this.mb},${this.mc},${this.md},${this.me},${this.mf})`;
|
|
812
874
|
if (href) {
|
|
@@ -957,11 +1019,11 @@ var SVGRenderer = (_class2 = class {
|
|
|
957
1019
|
}
|
|
958
1020
|
/**
|
|
959
1021
|
* SVGRenderer accumulates strings in memory; nothing external is allocated.
|
|
960
|
-
* Drop the buffers for GC and become idempotent.
|
|
1022
|
+
* Drop the buffers for GC and become idempotent. `clear()` already empties
|
|
1023
|
+
* the gradient cache, so no second clear is needed here.
|
|
961
1024
|
*/
|
|
962
1025
|
dispose() {
|
|
963
1026
|
this.clear();
|
|
964
|
-
this.gradientCache.clear();
|
|
965
1027
|
}
|
|
966
1028
|
}, _class2);
|
|
967
1029
|
|
|
@@ -1333,13 +1395,22 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1333
1395
|
premultipliedAlpha: false
|
|
1334
1396
|
});
|
|
1335
1397
|
if (!gl) return null;
|
|
1336
|
-
const
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1398
|
+
const programs = [];
|
|
1399
|
+
const linkTracked = (vsSrc, fsSrc) => {
|
|
1400
|
+
const program = link(gl, vsSrc, fsSrc);
|
|
1401
|
+
if (program) programs.push(program);
|
|
1402
|
+
return program;
|
|
1403
|
+
};
|
|
1404
|
+
const pointProgram = linkTracked(POINT_VERT, POINT_FRAG);
|
|
1405
|
+
const rectProgram = linkTracked(RECT_VERT, RECT_FRAG);
|
|
1406
|
+
const spriteProgram = linkTracked(SPRITE_VERT, SPRITE_FRAG);
|
|
1407
|
+
const msdfProgram = linkTracked(SPRITE_VERT, MSDF_FRAG);
|
|
1408
|
+
const circleQuadProgram = linkTracked(SPRITE_VERT, CIRCLE_QUAD_FRAG);
|
|
1409
|
+
if (!pointProgram || !rectProgram || !spriteProgram || !msdfProgram || !circleQuadProgram) {
|
|
1410
|
+
for (const program of programs) gl.deleteProgram(program);
|
|
1411
|
+
_optionalChain([gl, 'access', _13 => _13.getExtension, 'call', _14 => _14("WEBGL_lose_context"), 'optionalAccess', _15 => _15.loseContext, 'call', _16 => _16()]);
|
|
1342
1412
|
return null;
|
|
1413
|
+
}
|
|
1343
1414
|
gl.enable(gl.BLEND);
|
|
1344
1415
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
1345
1416
|
const pAPos = gl.getAttribLocation(pointProgram, "a_pos");
|
|
@@ -1519,6 +1590,7 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1519
1590
|
ensureQuadIndices(spriteCount);
|
|
1520
1591
|
gl.drawElements(gl.TRIANGLES, spriteCount * INDICES_PER_QUAD, gl.UNSIGNED_INT, 0);
|
|
1521
1592
|
frameDrawCalls++;
|
|
1593
|
+
gl.bindVertexArray(null);
|
|
1522
1594
|
spriteCount = 0;
|
|
1523
1595
|
};
|
|
1524
1596
|
const drawGlyphs = () => {
|
|
@@ -1797,6 +1869,7 @@ function createWebGLPointRenderer(canvas) {
|
|
|
1797
1869
|
}
|
|
1798
1870
|
|
|
1799
1871
|
// src/renderer/WebGPUParticleSystemManager.ts
|
|
1872
|
+
var recordComputePassScratch = new Float32Array(20);
|
|
1800
1873
|
var COMPUTE_SHADER = `
|
|
1801
1874
|
struct Particle {
|
|
1802
1875
|
position: vec2<f32>,
|
|
@@ -1971,16 +2044,22 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
|
|
1971
2044
|
`;
|
|
1972
2045
|
var WebGPUParticleSystemManager = (_class3 = class {
|
|
1973
2046
|
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2047
|
+
__init40() {this.computePipeline = null}
|
|
2048
|
+
__init41() {this.renderPipeline = null}
|
|
2049
|
+
// Held so destroy() can release them — modules were previously unreachable
|
|
2050
|
+
// after initPipelines and lived until context loss (#684).
|
|
2051
|
+
__init42() {this.computeModule = null}
|
|
2052
|
+
__init43() {this.renderModule = null}
|
|
2053
|
+
__init44() {this.computeBindGroupLayout = null}
|
|
2054
|
+
__init45() {this.renderBindGroupLayout = null}
|
|
2055
|
+
constructor(device) {;_class3.prototype.__init40.call(this);_class3.prototype.__init41.call(this);_class3.prototype.__init42.call(this);_class3.prototype.__init43.call(this);_class3.prototype.__init44.call(this);_class3.prototype.__init45.call(this);
|
|
1979
2056
|
this.device = device;
|
|
1980
2057
|
}
|
|
1981
2058
|
initPipelines(format) {
|
|
1982
|
-
|
|
1983
|
-
|
|
2059
|
+
this.computeModule = this.device.createShaderModule({ code: COMPUTE_SHADER });
|
|
2060
|
+
this.renderModule = this.device.createShaderModule({ code: RENDER_SHADER });
|
|
2061
|
+
const computeModule = this.computeModule;
|
|
2062
|
+
const renderModule = this.renderModule;
|
|
1984
2063
|
this.computeBindGroupLayout = this.device.createBindGroupLayout({
|
|
1985
2064
|
entries: [
|
|
1986
2065
|
{
|
|
@@ -2039,6 +2118,8 @@ var WebGPUParticleSystemManager = (_class3 = class {
|
|
|
2039
2118
|
});
|
|
2040
2119
|
}
|
|
2041
2120
|
setupEntityResources(entity) {
|
|
2121
|
+
releaseGpuObject(entity.gpuStorageBuffer);
|
|
2122
|
+
releaseGpuObject(entity.gpuUniformBuffer);
|
|
2042
2123
|
const storageSize = entity.maxParticles * 32;
|
|
2043
2124
|
entity.gpuStorageBuffer = this.device.createBuffer({
|
|
2044
2125
|
size: storageSize,
|
|
@@ -2065,7 +2146,7 @@ var WebGPUParticleSystemManager = (_class3 = class {
|
|
|
2065
2146
|
}
|
|
2066
2147
|
recordComputePass(pass, entity, dt, mouseX, mouseY, width, height) {
|
|
2067
2148
|
if (!this.computePipeline || !entity.computeBindGroup) return;
|
|
2068
|
-
const uniformArray =
|
|
2149
|
+
const uniformArray = recordComputePassScratch;
|
|
2069
2150
|
const color = parseColorToRGBA(entity.baseColor);
|
|
2070
2151
|
let opacity = 1;
|
|
2071
2152
|
for (let current = entity; current; current = current.parent) {
|
|
@@ -2109,34 +2190,45 @@ var WebGPUParticleSystemManager = (_class3 = class {
|
|
|
2109
2190
|
pass.draw(6, entity.maxParticles);
|
|
2110
2191
|
}
|
|
2111
2192
|
destroy() {
|
|
2193
|
+
releaseGpuObject(this.computePipeline);
|
|
2194
|
+
releaseGpuObject(this.renderPipeline);
|
|
2195
|
+
releaseGpuObject(this.computeModule);
|
|
2196
|
+
releaseGpuObject(this.renderModule);
|
|
2112
2197
|
this.computePipeline = null;
|
|
2113
2198
|
this.renderPipeline = null;
|
|
2199
|
+
this.computeModule = null;
|
|
2200
|
+
this.renderModule = null;
|
|
2114
2201
|
this.computeBindGroupLayout = null;
|
|
2115
2202
|
this.renderBindGroupLayout = null;
|
|
2116
2203
|
}
|
|
2117
2204
|
}, _class3);
|
|
2205
|
+
function releaseGpuObject(obj) {
|
|
2206
|
+
if (obj && typeof obj.destroy === "function") {
|
|
2207
|
+
obj.destroy();
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2118
2210
|
|
|
2119
2211
|
// src/renderer/GlyphRasterAtlas.ts
|
|
2120
2212
|
var HARD_MAX_SIZE = 8192;
|
|
2121
2213
|
var PAD = 2;
|
|
2122
2214
|
var GlyphRasterAtlas = (_class4 = class {
|
|
2123
|
-
|
|
2215
|
+
__init46() {this.slots = /* @__PURE__ */ new Map()}
|
|
2124
2216
|
|
|
2125
2217
|
|
|
2126
|
-
|
|
2127
|
-
|
|
2218
|
+
__init47() {this.canvas = null}
|
|
2219
|
+
__init48() {this.ctx = null}
|
|
2128
2220
|
/**
|
|
2129
2221
|
* Shelf packing: glyphs land left-to-right on a row, then a new row starts.
|
|
2130
2222
|
* A monospace grid produces near-uniform widths, so shelves waste very little
|
|
2131
2223
|
* and cost one comparison per insert — a real 2D packer would buy nothing here.
|
|
2132
2224
|
*/
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
constructor(options = {}) {;_class4.prototype.
|
|
2225
|
+
__init49() {this.penX = PAD}
|
|
2226
|
+
__init50() {this.penY = PAD}
|
|
2227
|
+
__init51() {this.rowHeight = 0}
|
|
2228
|
+
__init52() {this._hits = 0}
|
|
2229
|
+
__init53() {this._misses = 0}
|
|
2230
|
+
__init54() {this._resets = 0}
|
|
2231
|
+
constructor(options = {}) {;_class4.prototype.__init46.call(this);_class4.prototype.__init47.call(this);_class4.prototype.__init48.call(this);_class4.prototype.__init49.call(this);_class4.prototype.__init50.call(this);_class4.prototype.__init51.call(this);_class4.prototype.__init52.call(this);_class4.prototype.__init53.call(this);_class4.prototype.__init54.call(this);
|
|
2140
2232
|
this.dpr = Math.max(1, _nullishCoalesce(options.dpr, () => ( 1)));
|
|
2141
2233
|
this.maxSize = Math.min(HARD_MAX_SIZE, Math.max(256, _nullishCoalesce(options.maxSize, () => ( 2048))));
|
|
2142
2234
|
}
|
|
@@ -2195,7 +2287,7 @@ var GlyphRasterAtlas = (_class4 = class {
|
|
|
2195
2287
|
* (headless, unrasterizable, or too large to pack).
|
|
2196
2288
|
*/
|
|
2197
2289
|
get(font, color, glyph) {
|
|
2198
|
-
const key = font
|
|
2290
|
+
const key = `${font.length}\0${font}${color.length}\0${color}${glyph.length}\0${glyph}`;
|
|
2199
2291
|
const existing = this.slots.get(key);
|
|
2200
2292
|
if (existing !== void 0) {
|
|
2201
2293
|
if (existing) this._hits++;
|
|
@@ -2318,13 +2410,13 @@ var GlyphRasterAtlas = (_class4 = class {
|
|
|
2318
2410
|
|
|
2319
2411
|
// src/renderer/TextRasterCache.ts
|
|
2320
2412
|
var TextRasterCache = (_class5 = class {
|
|
2321
|
-
|
|
2413
|
+
__init55() {this.cache = /* @__PURE__ */ new Map()}
|
|
2322
2414
|
|
|
2323
2415
|
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
constructor(options = {}) {;_class5.prototype.
|
|
2416
|
+
__init56() {this.scratchCtx = null}
|
|
2417
|
+
__init57() {this._hits = 0}
|
|
2418
|
+
__init58() {this._misses = 0}
|
|
2419
|
+
constructor(options = {}) {;_class5.prototype.__init55.call(this);_class5.prototype.__init56.call(this);_class5.prototype.__init57.call(this);_class5.prototype.__init58.call(this);
|
|
2328
2420
|
this.maxEntries = Math.max(1, _nullishCoalesce(options.maxEntries, () => ( 4096)));
|
|
2329
2421
|
this.dpr = Math.max(1, _nullishCoalesce(options.dpr, () => ( 1)));
|
|
2330
2422
|
}
|
|
@@ -2349,7 +2441,7 @@ var TextRasterCache = (_class5 = class {
|
|
|
2349
2441
|
* fall back to {@link IRenderer.fillText}).
|
|
2350
2442
|
*/
|
|
2351
2443
|
get(font, color, text) {
|
|
2352
|
-
const key = font
|
|
2444
|
+
const key = `${font.length}\0${font}${color.length}\0${color}${text.length}\0${text}`;
|
|
2353
2445
|
const hit = this.cache.get(key);
|
|
2354
2446
|
if (hit) {
|
|
2355
2447
|
this._hits++;
|