@vectojs/core 1.36.0 → 1.38.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-25PS5K7R.mjs → chunk-LWEMD34D.mjs} +18 -4
- package/dist/{chunk-QJC4VZ2E.mjs → chunk-QVTCKWDO.mjs} +39 -3
- package/dist/{chunk-XE6K7T5S.js → chunk-SRXU3ZXK.js} +105 -69
- package/dist/{chunk-MO24PVGT.js → chunk-ZYYP2M5D.js} +18 -4
- package/dist/index.js +76 -41
- package/dist/index.mjs +39 -4
- package/dist/renderer/CanvasRenderer.d.ts +1 -1
- package/dist/renderer/IRenderer.d.ts +8 -1
- package/dist/renderer/SVGRenderer.d.ts +1 -1
- package/dist/renderer.js +2 -2
- package/dist/renderer.mjs +1 -1
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +43 -3
- package/package.json +1 -1
|
@@ -304,11 +304,15 @@ var CanvasRenderer = class _CanvasRenderer {
|
|
|
304
304
|
this.ctx.globalAlpha = alpha;
|
|
305
305
|
}
|
|
306
306
|
/** @inheritdoc */
|
|
307
|
-
clip(x, y, width, height) {
|
|
307
|
+
clip(x, y, width, height, radii) {
|
|
308
308
|
this.flush();
|
|
309
309
|
if (this.counters) this.counters.clips++;
|
|
310
310
|
this.ctx.beginPath();
|
|
311
|
-
|
|
311
|
+
if (radii !== void 0) {
|
|
312
|
+
this.ctx.roundRect(x, y, width, height, radii);
|
|
313
|
+
} else {
|
|
314
|
+
this.ctx.rect(x, y, width, height);
|
|
315
|
+
}
|
|
312
316
|
this.ctx.clip();
|
|
313
317
|
}
|
|
314
318
|
/** @inheritdoc */
|
|
@@ -854,11 +858,21 @@ var SVGRenderer = class {
|
|
|
854
858
|
createMatrix: [this.ma, this.mb, this.mc, this.md, this.me, this.mf]
|
|
855
859
|
};
|
|
856
860
|
}
|
|
857
|
-
clip(x, y, width, height) {
|
|
861
|
+
clip(x, y, width, height, radii) {
|
|
858
862
|
this.flush();
|
|
859
863
|
const id = `clip-${this.clipCounter++}`;
|
|
860
864
|
const transformStr = `matrix(${this.ma},${this.mb},${this.mc},${this.md},${this.me},${this.mf})`;
|
|
861
|
-
|
|
865
|
+
let clipShape;
|
|
866
|
+
if (radii !== void 0) {
|
|
867
|
+
const savedPath = this.currentPath;
|
|
868
|
+
this.currentPath = [];
|
|
869
|
+
this.roundRect(x, y, width, height, radii);
|
|
870
|
+
clipShape = `<path d="${this.currentPath.join(" ")}" transform="${transformStr}" />`;
|
|
871
|
+
this.currentPath = savedPath;
|
|
872
|
+
} else {
|
|
873
|
+
clipShape = `<rect x="${x}" y="${y}" width="${width}" height="${height}" transform="${transformStr}" />`;
|
|
874
|
+
}
|
|
875
|
+
const clipXML = `<clipPath id="${id}">${clipShape}</clipPath>`;
|
|
862
876
|
this.defsBuffer.push(clipXML);
|
|
863
877
|
this.buffer.push(`<g clip-path="url(#${id})">`);
|
|
864
878
|
this.clipDepth++;
|
|
@@ -134,6 +134,12 @@ var VectoJSEvent = class {
|
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
136
|
var Entity = class {
|
|
137
|
+
/**
|
|
138
|
+
* Whether Scene may ask {@link getRenderChildRange} to prune this entity's
|
|
139
|
+
* visual child traversal. Off by default so ordinary containers pay no
|
|
140
|
+
* viewport-inversion cost.
|
|
141
|
+
*/
|
|
142
|
+
viewportCullChildren = false;
|
|
137
143
|
id;
|
|
138
144
|
children = [];
|
|
139
145
|
parent = null;
|
|
@@ -283,9 +289,20 @@ var Entity = class {
|
|
|
283
289
|
* and promotes it.
|
|
284
290
|
*
|
|
285
291
|
* `'never'` suppresses the node entirely. Prefer `interactive = false` unless
|
|
286
|
-
* the entity genuinely needs
|
|
287
|
-
* this exists so a purely decorative interactive surface can opt
|
|
288
|
-
*
|
|
292
|
+
* the entity genuinely needs to stay hit-testable without any semantic
|
|
293
|
+
* presence — this exists so a purely decorative interactive surface can opt
|
|
294
|
+
* out of the a11y tree.
|
|
295
|
+
*
|
|
296
|
+
* **Pointer input is routed through the projected mirror.** The engine binds
|
|
297
|
+
* `pointerdown`/`pointermove`/`pointerup`/`click`/`dblclick` to each shadow
|
|
298
|
+
* element (the canvas itself only tracks `mouseX`/`mouseY`), so an entity
|
|
299
|
+
* with no materialized node receives **no pointer events at all** — neither
|
|
300
|
+
* in `'never'` mode nor in `'onDemand'` before it is engaged (focused,
|
|
301
|
+
* pointer target, or `requestA11yProjection`). Canvas hit-testing exists
|
|
302
|
+
* (`Scene.findEntityAt`) but is a query API, not a dispatch path. For a
|
|
303
|
+
* pointer-reactive region with no role (e.g. a desktop click-catcher), use
|
|
304
|
+
* `'eager'` + `a11yFullViewport` + `tabIndex: -1` with a role-less
|
|
305
|
+
* `getA11yAttributes()`: the mirror is AT-invisible but pointer-visible.
|
|
289
306
|
*
|
|
290
307
|
* **This does not replace an aggregate description.** A thousand `'onDemand'`
|
|
291
308
|
* danmaku are individually reachable but say nothing collectively. The proven
|
|
@@ -1083,6 +1100,25 @@ var Entity = class {
|
|
|
1083
1100
|
getBounds() {
|
|
1084
1101
|
return null;
|
|
1085
1102
|
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Select a contiguous subset of direct children for visual rendering.
|
|
1105
|
+
*
|
|
1106
|
+
* Return `null` (the default) to visit every child. Containers may override
|
|
1107
|
+
* this only when child order and geometry prove that every skipped child's
|
|
1108
|
+
* entire painted subtree lies outside `localViewport`. The Scene still keeps
|
|
1109
|
+
* all children resident, and hit testing, accessibility, and content
|
|
1110
|
+
* projection continue to see the complete tree. Skipped subtrees do not run
|
|
1111
|
+
* `update()` or `render()` in the visual pass, so opt in only for children that
|
|
1112
|
+
* are static while offscreen or whose state advances outside those methods.
|
|
1113
|
+
*
|
|
1114
|
+
* The returned range is half-open and is clamped to `children.length`.
|
|
1115
|
+
* `localViewport` is a conservative axis-aligned box obtained by mapping the
|
|
1116
|
+
* Scene viewport into this entity's local coordinate space.
|
|
1117
|
+
*/
|
|
1118
|
+
getRenderChildRange(localViewport) {
|
|
1119
|
+
void localViewport;
|
|
1120
|
+
return null;
|
|
1121
|
+
}
|
|
1086
1122
|
/**
|
|
1087
1123
|
* Opt into the renderer's draw-call batching fast-path for point-cloud /
|
|
1088
1124
|
* particle entities that draw as a single filled circle at their local origin.
|
|
@@ -136,9 +136,15 @@ var VectoJSEvent = (_class = class {
|
|
|
136
136
|
}
|
|
137
137
|
}, _class);
|
|
138
138
|
var Entity = (_class2 = class {
|
|
139
|
+
/**
|
|
140
|
+
* Whether Scene may ask {@link getRenderChildRange} to prune this entity's
|
|
141
|
+
* visual child traversal. Off by default so ordinary containers pay no
|
|
142
|
+
* viewport-inversion cost.
|
|
143
|
+
*/
|
|
144
|
+
__init3() {this.viewportCullChildren = false}
|
|
139
145
|
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
__init4() {this.children = []}
|
|
147
|
+
__init5() {this.parent = null}
|
|
142
148
|
/**
|
|
143
149
|
* Walk up the parent chain to find the scene this entity is currently attached to.
|
|
144
150
|
*/
|
|
@@ -146,52 +152,52 @@ var Entity = (_class2 = class {
|
|
|
146
152
|
if (this._scene) return this._scene;
|
|
147
153
|
return this.parent ? this.parent.scene : null;
|
|
148
154
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
__init6() {this._x = 0}
|
|
156
|
+
__init7() {this._y = 0}
|
|
157
|
+
__init8() {this._scaleX = 1}
|
|
158
|
+
__init9() {this._scaleY = 1}
|
|
159
|
+
__init10() {this._rotation = 0}
|
|
160
|
+
__init11() {this._opacity = 1}
|
|
155
161
|
// Fast-path flag: false for the overwhelming majority of entities (incl. the
|
|
156
162
|
// Danmaku hot loop), so a bare `entity.x = v` is one boolean check + field write.
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
__init12() {this._hasTransitions = false}
|
|
164
|
+
__init13() {this._transitions = null}
|
|
159
165
|
// Lazily allocated: null until first use. A scene of many passive entities
|
|
160
166
|
// (particles, data points) never touches these, so paying an empty-Map/array
|
|
161
167
|
// allocation per entity in the constructor is pure waste at scale.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
168
|
+
__init14() {this._drivers = null}
|
|
169
|
+
__init15() {this._mounted = false}
|
|
170
|
+
__init16() {this._destroyed = false}
|
|
165
171
|
// Frame this entity's active drivers were last advanced by Scene's batched
|
|
166
172
|
// WASM animation pass (see Scene._tickBatchedDrivers), or -1 if never. When
|
|
167
173
|
// it equals the current frame, tickDrivers() must skip its own tick loop —
|
|
168
174
|
// otherwise a driver already advanced by the batch pass would be ticked a
|
|
169
175
|
// second time by the normal per-entity update() walk in the same frame.
|
|
170
176
|
// Irrelevant (and harmless) for entities never touched by WASM batching.
|
|
171
|
-
|
|
177
|
+
__init17() {this._driversTickedFrame = -1}
|
|
172
178
|
// Cached cos/sin, recomputed only when rotation actually changes. renderNode
|
|
173
179
|
// and getWorldTransform() both read this instead of calling Math.cos/sin per
|
|
174
180
|
// entity per frame (V8's are ~2.5x slower than other engines).
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
__init18() {this._trig = { cos: 1, sin: 0 }}
|
|
182
|
+
__init19() {this._trigRotation = Number.NaN}
|
|
177
183
|
// NaN !== any rotation -> first read computes
|
|
178
184
|
// Per-frame world-matrix cache. Written by Scene during the render walk;
|
|
179
185
|
// getWorldTransform() returns it only while `_worldFrame === scene.currentFrame`
|
|
180
186
|
// and otherwise falls back to the full ancestor walk, so it can never return a
|
|
181
187
|
// stale/wrong transform — only sometimes miss the fast path.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
__init20() {this._wa = 1}
|
|
189
|
+
__init21() {this._wb = 0}
|
|
190
|
+
__init22() {this._wc = 0}
|
|
191
|
+
__init23() {this._wd = 1}
|
|
192
|
+
__init24() {this._we = 0}
|
|
193
|
+
__init25() {this._wf = 0}
|
|
194
|
+
__init26() {this._worldFrame = -1}
|
|
189
195
|
// Slot in the Scene's resident WASM transform store, or -1 when this entity is
|
|
190
196
|
// not in that store (JS transform path, overlay/detached, or before the first
|
|
191
197
|
// structural rebuild). Assigned by Scene on a structural rebuild; the Scene
|
|
192
198
|
// validates it against its slot table before trusting it, so a stale value can
|
|
193
199
|
// only cost a JS-path fallback, never a wrong read.
|
|
194
|
-
|
|
200
|
+
__init27() {this._storeSlot = -1}
|
|
195
201
|
get x() {
|
|
196
202
|
return this._x;
|
|
197
203
|
}
|
|
@@ -234,8 +240,8 @@ var Entity = (_class2 = class {
|
|
|
234
240
|
if (this._hasTransitions) this._animateProp("opacity", v);
|
|
235
241
|
else this._opacity = v;
|
|
236
242
|
}
|
|
237
|
-
|
|
238
|
-
|
|
243
|
+
__init28() {this.isDOMPortal = false}
|
|
244
|
+
__init29() {this._interactive = false}
|
|
239
245
|
get interactive() {
|
|
240
246
|
return this._interactive;
|
|
241
247
|
}
|
|
@@ -249,10 +255,10 @@ var Entity = (_class2 = class {
|
|
|
249
255
|
}
|
|
250
256
|
}
|
|
251
257
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
258
|
+
__init30() {this.width = 0}
|
|
259
|
+
__init31() {this.height = 0}
|
|
260
|
+
__init32() {this.a11yOffsetX = 0}
|
|
261
|
+
__init33() {this.a11yOffsetY = 0}
|
|
256
262
|
/**
|
|
257
263
|
* Opt in to a viewport-filling accessibility/automation shadow node even when
|
|
258
264
|
* this entity has no intrinsic box (`width`/`height` of `0`). Use for
|
|
@@ -260,7 +266,7 @@ var Entity = (_class2 = class {
|
|
|
260
266
|
* that need global pointer events. The node is mounted behind all other shadow
|
|
261
267
|
* nodes, so on-top components stay clickable.
|
|
262
268
|
*/
|
|
263
|
-
|
|
269
|
+
__init34() {this.a11yFullViewport = false}
|
|
264
270
|
/**
|
|
265
271
|
* When this entity's a11y shadow node is materialized.
|
|
266
272
|
*
|
|
@@ -285,9 +291,20 @@ var Entity = (_class2 = class {
|
|
|
285
291
|
* and promotes it.
|
|
286
292
|
*
|
|
287
293
|
* `'never'` suppresses the node entirely. Prefer `interactive = false` unless
|
|
288
|
-
* the entity genuinely needs
|
|
289
|
-
* this exists so a purely decorative interactive surface can opt
|
|
290
|
-
*
|
|
294
|
+
* the entity genuinely needs to stay hit-testable without any semantic
|
|
295
|
+
* presence — this exists so a purely decorative interactive surface can opt
|
|
296
|
+
* out of the a11y tree.
|
|
297
|
+
*
|
|
298
|
+
* **Pointer input is routed through the projected mirror.** The engine binds
|
|
299
|
+
* `pointerdown`/`pointermove`/`pointerup`/`click`/`dblclick` to each shadow
|
|
300
|
+
* element (the canvas itself only tracks `mouseX`/`mouseY`), so an entity
|
|
301
|
+
* with no materialized node receives **no pointer events at all** — neither
|
|
302
|
+
* in `'never'` mode nor in `'onDemand'` before it is engaged (focused,
|
|
303
|
+
* pointer target, or `requestA11yProjection`). Canvas hit-testing exists
|
|
304
|
+
* (`Scene.findEntityAt`) but is a query API, not a dispatch path. For a
|
|
305
|
+
* pointer-reactive region with no role (e.g. a desktop click-catcher), use
|
|
306
|
+
* `'eager'` + `a11yFullViewport` + `tabIndex: -1` with a role-less
|
|
307
|
+
* `getA11yAttributes()`: the mirror is AT-invisible but pointer-visible.
|
|
291
308
|
*
|
|
292
309
|
* **This does not replace an aggregate description.** A thousand `'onDemand'`
|
|
293
310
|
* danmaku are individually reachable but say nothing collectively. The proven
|
|
@@ -296,7 +313,7 @@ var Entity = (_class2 = class {
|
|
|
296
313
|
* `vectojs-native/danmaku`. Use `'onDemand'` to stop paying per entity, not as
|
|
297
314
|
* the whole accessibility story.
|
|
298
315
|
*/
|
|
299
|
-
|
|
316
|
+
__init35() {this.a11yProjection = "eager"}
|
|
300
317
|
/**
|
|
301
318
|
* Hide this entity AND its whole subtree from the accessibility/automation
|
|
302
319
|
* projection, regardless of each node's own `interactive` flag.
|
|
@@ -314,14 +331,14 @@ var Entity = (_class2 = class {
|
|
|
314
331
|
* `=== 0` test never fires; a threshold would instead silently un-project a
|
|
315
332
|
* faint-but-live control.
|
|
316
333
|
*/
|
|
317
|
-
|
|
334
|
+
__init36() {this.a11yHidden = false}
|
|
318
335
|
/**
|
|
319
336
|
* Clip this node's children to its local box (`[0,0]–[width,height]`) while
|
|
320
337
|
* rendering. Combined with translating a content child, this is how
|
|
321
338
|
* scroll/overflow containers (e.g. `ScrollView`) keep their content inside a
|
|
322
339
|
* fixed viewport. Off by default (children render unclipped). Canvas2D only.
|
|
323
340
|
*/
|
|
324
|
-
|
|
341
|
+
__init37() {this.clipChildren = false}
|
|
325
342
|
/**
|
|
326
343
|
* Group this subtree's projected text into its own accessibility **region**,
|
|
327
344
|
* without clipping anything.
|
|
@@ -348,14 +365,14 @@ var Entity = (_class2 = class {
|
|
|
348
365
|
*
|
|
349
366
|
* Off by default. Regions nest: the nearest enclosing region wins.
|
|
350
367
|
*/
|
|
351
|
-
|
|
368
|
+
__init38() {this.a11yRegion = false}
|
|
352
369
|
// Lazily allocated (see _drivers above). Most entities never register a
|
|
353
370
|
// listener or an imperative animate() tween.
|
|
354
|
-
|
|
371
|
+
__init39() {this.listeners = null}
|
|
355
372
|
/** Capture-phase listeners (fired root→target before bubble). */
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
constructor(id) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);_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);_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);_class2.prototype.__init40.call(this);
|
|
373
|
+
__init40() {this.captureListeners = null}
|
|
374
|
+
__init41() {this.animations = null}
|
|
375
|
+
constructor(id) {;_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);_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);_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);_class2.prototype.__init40.call(this);_class2.prototype.__init41.call(this);
|
|
359
376
|
this.id = id || `entity_${Math.random().toString(36).substring(2, 9)}`;
|
|
360
377
|
}
|
|
361
378
|
/**
|
|
@@ -1085,6 +1102,25 @@ var Entity = (_class2 = class {
|
|
|
1085
1102
|
getBounds() {
|
|
1086
1103
|
return null;
|
|
1087
1104
|
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Select a contiguous subset of direct children for visual rendering.
|
|
1107
|
+
*
|
|
1108
|
+
* Return `null` (the default) to visit every child. Containers may override
|
|
1109
|
+
* this only when child order and geometry prove that every skipped child's
|
|
1110
|
+
* entire painted subtree lies outside `localViewport`. The Scene still keeps
|
|
1111
|
+
* all children resident, and hit testing, accessibility, and content
|
|
1112
|
+
* projection continue to see the complete tree. Skipped subtrees do not run
|
|
1113
|
+
* `update()` or `render()` in the visual pass, so opt in only for children that
|
|
1114
|
+
* are static while offscreen or whose state advances outside those methods.
|
|
1115
|
+
*
|
|
1116
|
+
* The returned range is half-open and is clamped to `children.length`.
|
|
1117
|
+
* `localViewport` is a conservative axis-aligned box obtained by mapping the
|
|
1118
|
+
* Scene viewport into this entity's local coordinate space.
|
|
1119
|
+
*/
|
|
1120
|
+
getRenderChildRange(localViewport) {
|
|
1121
|
+
void localViewport;
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1088
1124
|
/**
|
|
1089
1125
|
* Opt into the renderer's draw-call batching fast-path for point-cloud /
|
|
1090
1126
|
* particle entities that draw as a single filled circle at their local origin.
|
|
@@ -1197,28 +1233,28 @@ var MSDFTextEntity = (_class3 = class extends Entity {
|
|
|
1197
1233
|
// joined by soft hyphens (U+00AD); the worker then treats those as break
|
|
1198
1234
|
// opportunities. `text` keeps the original string for a11y/content
|
|
1199
1235
|
// projection; `layoutText` is the soft-hyphen-annotated string sent to layout.
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1236
|
+
__init42() {this.hyphenator = null}
|
|
1237
|
+
__init43() {this.layoutText = ""}
|
|
1238
|
+
__init44() {this.text = ""}
|
|
1239
|
+
__init45() {this.lastRenderedSeqId = 0}
|
|
1204
1240
|
/** Bumped by {@link queueLayout}; read by `Scene` to skip an unchanged sync. */
|
|
1205
|
-
|
|
1241
|
+
__init46() {this.contentEpoch = 0}
|
|
1206
1242
|
// Atlas-decode subscription (see watchAtlasDecode). Held so `destroy()` can
|
|
1207
1243
|
// release it: the handler closes over `this`, so leaving it attached to a
|
|
1208
1244
|
// long-lived shared atlas image would retain the whole entity.
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1245
|
+
__init47() {this.atlasDecodeTarget = null}
|
|
1246
|
+
__init48() {this.atlasDecodeHandler = null}
|
|
1247
|
+
__init49() {this.rgbColorCache = /* @__PURE__ */ new Map()}
|
|
1248
|
+
__init50() {this.fontStringCache = []}
|
|
1249
|
+
__init51() {this.layoutResult = null}
|
|
1214
1250
|
/**
|
|
1215
1251
|
* Visual rows rebuilt from {@link layoutResult} (see
|
|
1216
1252
|
* {@link rebuildProjectionLines}). Empty until a layout reply lands and the
|
|
1217
1253
|
* reply's shaped glyphs can be mapped back to the source text 1:1.
|
|
1218
1254
|
*/
|
|
1219
|
-
|
|
1255
|
+
__init52() {this.projectionLines = []}
|
|
1220
1256
|
constructor(text, options) {
|
|
1221
|
-
super();_class3.prototype.
|
|
1257
|
+
super();_class3.prototype.__init42.call(this);_class3.prototype.__init43.call(this);_class3.prototype.__init44.call(this);_class3.prototype.__init45.call(this);_class3.prototype.__init46.call(this);_class3.prototype.__init47.call(this);_class3.prototype.__init48.call(this);_class3.prototype.__init49.call(this);_class3.prototype.__init50.call(this);_class3.prototype.__init51.call(this);_class3.prototype.__init52.call(this);;
|
|
1222
1258
|
this.font = options.font;
|
|
1223
1259
|
this.texture = options.texture;
|
|
1224
1260
|
this.fallbackFont = _nullishCoalesce(options.fallbackFont, () => ( "sans-serif"));
|
|
@@ -1585,23 +1621,23 @@ var SVGEntity = (_class4 = class extends Entity {
|
|
|
1585
1621
|
* rasterized. Set to `'transparent'` to opt out and keep the box empty.
|
|
1586
1622
|
* Default `'rgba(248,113,113,0.9)'`.
|
|
1587
1623
|
*/
|
|
1588
|
-
|
|
1624
|
+
__init53() {this.fallbackStroke = "rgba(248,113,113,0.9)"}
|
|
1589
1625
|
/** Fill behind the fallback marker. Default `'rgba(248,113,113,0.12)'`. */
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1626
|
+
__init54() {this.fallbackFill = "rgba(248,113,113,0.12)"}
|
|
1627
|
+
__init55() {this.svgSource = ""}
|
|
1628
|
+
__init56() {this.imageBitmap = null}
|
|
1629
|
+
__init57() {this.imageElement = null}
|
|
1630
|
+
__init58() {this.blobURL = null}
|
|
1631
|
+
__init59() {this.currentImg = null}
|
|
1632
|
+
__init60() {this.lodTimeout = null}
|
|
1633
|
+
__init61() {this.rasterFailed = false}
|
|
1634
|
+
__init62() {this.cachedDoc = null}
|
|
1635
|
+
__init63() {this.baseWidth = 100}
|
|
1636
|
+
__init64() {this.baseHeight = 100}
|
|
1637
|
+
__init65() {this.lastRasterizedScale = 1}
|
|
1638
|
+
__init66() {this.targetScale = 1}
|
|
1603
1639
|
constructor(svgSource, id) {
|
|
1604
|
-
super(id);_class4.prototype.
|
|
1640
|
+
super(id);_class4.prototype.__init53.call(this);_class4.prototype.__init54.call(this);_class4.prototype.__init55.call(this);_class4.prototype.__init56.call(this);_class4.prototype.__init57.call(this);_class4.prototype.__init58.call(this);_class4.prototype.__init59.call(this);_class4.prototype.__init60.call(this);_class4.prototype.__init61.call(this);_class4.prototype.__init62.call(this);_class4.prototype.__init63.call(this);_class4.prototype.__init64.call(this);_class4.prototype.__init65.call(this);_class4.prototype.__init66.call(this);;
|
|
1605
1641
|
this.setSVGSource(svgSource);
|
|
1606
1642
|
}
|
|
1607
1643
|
setSVGSource(svgSource) {
|
|
@@ -306,11 +306,15 @@ var CanvasRenderer = (_class = class _CanvasRenderer {
|
|
|
306
306
|
this.ctx.globalAlpha = alpha;
|
|
307
307
|
}
|
|
308
308
|
/** @inheritdoc */
|
|
309
|
-
clip(x, y, width, height) {
|
|
309
|
+
clip(x, y, width, height, radii) {
|
|
310
310
|
this.flush();
|
|
311
311
|
if (this.counters) this.counters.clips++;
|
|
312
312
|
this.ctx.beginPath();
|
|
313
|
-
|
|
313
|
+
if (radii !== void 0) {
|
|
314
|
+
this.ctx.roundRect(x, y, width, height, radii);
|
|
315
|
+
} else {
|
|
316
|
+
this.ctx.rect(x, y, width, height);
|
|
317
|
+
}
|
|
314
318
|
this.ctx.clip();
|
|
315
319
|
}
|
|
316
320
|
/** @inheritdoc */
|
|
@@ -856,11 +860,21 @@ var SVGRenderer = (_class2 = class {
|
|
|
856
860
|
createMatrix: [this.ma, this.mb, this.mc, this.md, this.me, this.mf]
|
|
857
861
|
};
|
|
858
862
|
}
|
|
859
|
-
clip(x, y, width, height) {
|
|
863
|
+
clip(x, y, width, height, radii) {
|
|
860
864
|
this.flush();
|
|
861
865
|
const id = `clip-${this.clipCounter++}`;
|
|
862
866
|
const transformStr = `matrix(${this.ma},${this.mb},${this.mc},${this.md},${this.me},${this.mf})`;
|
|
863
|
-
|
|
867
|
+
let clipShape;
|
|
868
|
+
if (radii !== void 0) {
|
|
869
|
+
const savedPath = this.currentPath;
|
|
870
|
+
this.currentPath = [];
|
|
871
|
+
this.roundRect(x, y, width, height, radii);
|
|
872
|
+
clipShape = `<path d="${this.currentPath.join(" ")}" transform="${transformStr}" />`;
|
|
873
|
+
this.currentPath = savedPath;
|
|
874
|
+
} else {
|
|
875
|
+
clipShape = `<rect x="${x}" y="${y}" width="${width}" height="${height}" transform="${transformStr}" />`;
|
|
876
|
+
}
|
|
877
|
+
const clipXML = `<clipPath id="${id}">${clipShape}</clipPath>`;
|
|
864
878
|
this.defsBuffer.push(clipXML);
|
|
865
879
|
this.buffer.push(`<g clip-path="url(#${id})">`);
|
|
866
880
|
this.clipDepth++;
|
package/dist/index.js
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var _chunkZYYP2M5Djs = require('./chunk-ZYYP2M5D.js');
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
var
|
|
22
|
+
var _chunkSRXU3ZXKjs = require('./chunk-SRXU3ZXK.js');
|
|
23
23
|
|
|
24
24
|
// src/tree/ComputeParticleEntity.ts
|
|
25
25
|
var PARTICLE_STRIDE_FLOATS = 8;
|
|
@@ -31,7 +31,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
|
|
|
31
31
|
var PARTICLE_OFFSET_ORIGIN_Y = 5;
|
|
32
32
|
var PARTICLE_OFFSET_SIZE = 6;
|
|
33
33
|
var PARTICLE_OFFSET_LIFE = 7;
|
|
34
|
-
var ComputeParticleEntity = (_class = class extends
|
|
34
|
+
var ComputeParticleEntity = (_class = class extends _chunkSRXU3ZXKjs.Entity {
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
|
|
@@ -4698,7 +4698,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4698
4698
|
}
|
|
4699
4699
|
static set devMode(active) {
|
|
4700
4700
|
_Scene._devMode = active;
|
|
4701
|
-
|
|
4701
|
+
_chunkZYYP2M5Djs.setRendererDevMode.call(void 0, active);
|
|
4702
4702
|
}
|
|
4703
4703
|
static _devModeDetected() {
|
|
4704
4704
|
if (_Scene._devMode) return true;
|
|
@@ -4816,7 +4816,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4816
4816
|
this.readingDirection = _nullishCoalesce(options.readingDirection, () => ( "ltr"));
|
|
4817
4817
|
this.renderMode = _nullishCoalesce(options.renderMode, () => ( "always"));
|
|
4818
4818
|
this._devActive = _Scene._devModeDetected();
|
|
4819
|
-
|
|
4819
|
+
_chunkZYYP2M5Djs.setRendererDevMode.call(void 0, this._devActive);
|
|
4820
4820
|
this._warnUnknownOptions(options);
|
|
4821
4821
|
this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
4822
4822
|
if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
|
|
@@ -4824,7 +4824,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4824
4824
|
this.forcedColorsChangeHandler = () => this.markDirty();
|
|
4825
4825
|
_optionalChain([this, 'access', _118 => _118.forcedColorsQuery, 'access', _119 => _119.addEventListener, 'optionalCall', _120 => _120("change", this.forcedColorsChangeHandler)]);
|
|
4826
4826
|
}
|
|
4827
|
-
this.root = new class RootEntity extends
|
|
4827
|
+
this.root = new class RootEntity extends _chunkSRXU3ZXKjs.Entity {
|
|
4828
4828
|
isPointInside() {
|
|
4829
4829
|
return false;
|
|
4830
4830
|
}
|
|
@@ -4834,7 +4834,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4834
4834
|
}("root");
|
|
4835
4835
|
this.root._scene = this;
|
|
4836
4836
|
this._wasmBackend = new WasmBackendFacade(this.root);
|
|
4837
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
4837
|
+
this.overlayRoot = new class OverlayRoot extends _chunkSRXU3ZXKjs.Entity {
|
|
4838
4838
|
isPointInside() {
|
|
4839
4839
|
return false;
|
|
4840
4840
|
}
|
|
@@ -4847,7 +4847,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
4847
4847
|
if (options.renderer) {
|
|
4848
4848
|
this.renderer = options.renderer;
|
|
4849
4849
|
} else {
|
|
4850
|
-
this.renderer = new (0,
|
|
4850
|
+
this.renderer = new (0, _chunkZYYP2M5Djs.CanvasRenderer)(
|
|
4851
4851
|
canvas,
|
|
4852
4852
|
this.disableWindowResize ? { width: this.width, height: this.height } : void 0,
|
|
4853
4853
|
this.maxDPR
|
|
@@ -5154,7 +5154,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5154
5154
|
}
|
|
5155
5155
|
if (this.hoveredA11yElements.has(el)) {
|
|
5156
5156
|
this.hoveredA11yElements.delete(el);
|
|
5157
|
-
node.dispatchEvent(new (0,
|
|
5157
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("pointerleave", node, void 0, false));
|
|
5158
5158
|
}
|
|
5159
5159
|
this.preserveFocusOnRemoval(el);
|
|
5160
5160
|
el.remove();
|
|
@@ -5745,20 +5745,20 @@ var Scene = (_class15 = class _Scene {
|
|
|
5745
5745
|
el.style.background = "transparent";
|
|
5746
5746
|
}
|
|
5747
5747
|
el.addEventListener("click", (e) => {
|
|
5748
|
-
node.dispatchEvent(new (0,
|
|
5748
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("click", node, e));
|
|
5749
5749
|
});
|
|
5750
5750
|
el.addEventListener("dblclick", (e) => {
|
|
5751
|
-
node.dispatchEvent(new (0,
|
|
5751
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("dblclick", node, e));
|
|
5752
5752
|
});
|
|
5753
5753
|
el.addEventListener("mouseenter", (e) => {
|
|
5754
5754
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
5755
5755
|
this.hoveredA11yElements.add(el);
|
|
5756
|
-
node.dispatchEvent(new (0,
|
|
5756
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("hover", node, e, false));
|
|
5757
5757
|
});
|
|
5758
5758
|
el.addEventListener("mouseleave", (e) => {
|
|
5759
5759
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
5760
5760
|
this.hoveredA11yElements.delete(el);
|
|
5761
|
-
node.dispatchEvent(new (0,
|
|
5761
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("pointerleave", node, e, false));
|
|
5762
5762
|
});
|
|
5763
5763
|
const capEl = el;
|
|
5764
5764
|
const releasePointer = (event) => {
|
|
@@ -5774,24 +5774,24 @@ var Scene = (_class15 = class _Scene {
|
|
|
5774
5774
|
};
|
|
5775
5775
|
el.addEventListener("pointerdown", (e) => {
|
|
5776
5776
|
if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
|
|
5777
|
-
node.dispatchEvent(new (0,
|
|
5777
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("pointerdown", node, e));
|
|
5778
5778
|
});
|
|
5779
5779
|
el.addEventListener("pointerup", (e) => {
|
|
5780
5780
|
releasePointer(e);
|
|
5781
|
-
node.dispatchEvent(new (0,
|
|
5781
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("pointerup", node, e));
|
|
5782
5782
|
});
|
|
5783
5783
|
el.addEventListener("pointercancel", (e) => {
|
|
5784
5784
|
releasePointer(e);
|
|
5785
|
-
node.dispatchEvent(new (0,
|
|
5785
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("pointercancel", node, e));
|
|
5786
5786
|
});
|
|
5787
5787
|
el.addEventListener(
|
|
5788
5788
|
"pointermove",
|
|
5789
|
-
(e) => node.dispatchEvent(new (0,
|
|
5789
|
+
(e) => node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("pointermove", node, e))
|
|
5790
5790
|
);
|
|
5791
5791
|
el.addEventListener(
|
|
5792
5792
|
"wheel",
|
|
5793
5793
|
(e) => {
|
|
5794
|
-
node.dispatchEvent(new (0,
|
|
5794
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("wheel", node, e));
|
|
5795
5795
|
},
|
|
5796
5796
|
{ passive: false }
|
|
5797
5797
|
);
|
|
@@ -5816,10 +5816,10 @@ var Scene = (_class15 = class _Scene {
|
|
|
5816
5816
|
);
|
|
5817
5817
|
emitInitialScroll = emitScroll;
|
|
5818
5818
|
el.addEventListener("keydown", (e) => {
|
|
5819
|
-
node.dispatchEvent(new (0,
|
|
5819
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("keydown", node, e));
|
|
5820
5820
|
});
|
|
5821
5821
|
el.addEventListener("keyup", (e) => {
|
|
5822
|
-
node.dispatchEvent(new (0,
|
|
5822
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("keyup", node, e));
|
|
5823
5823
|
});
|
|
5824
5824
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
5825
5825
|
const input = el;
|
|
@@ -5885,7 +5885,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5885
5885
|
el.addEventListener("keydown", (e) => {
|
|
5886
5886
|
if (e.key === "Enter" || e.key === " ") {
|
|
5887
5887
|
e.preventDefault();
|
|
5888
|
-
node.dispatchEvent(new (0,
|
|
5888
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("click", node, e));
|
|
5889
5889
|
}
|
|
5890
5890
|
});
|
|
5891
5891
|
}
|
|
@@ -5923,7 +5923,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
5923
5923
|
this.syncOptionalAttribute(
|
|
5924
5924
|
el,
|
|
5925
5925
|
"href",
|
|
5926
|
-
attrs.href === void 0 ? void 0 :
|
|
5926
|
+
attrs.href === void 0 ? void 0 : _chunkZYYP2M5Djs.sanitizeUrl.call(void 0, attrs.href)
|
|
5927
5927
|
);
|
|
5928
5928
|
this.syncOptionalAttribute(el, "target", attrs.target);
|
|
5929
5929
|
}
|
|
@@ -6322,7 +6322,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6322
6322
|
el.addEventListener(
|
|
6323
6323
|
"wheel",
|
|
6324
6324
|
(e2) => {
|
|
6325
|
-
node.dispatchEvent(new (0,
|
|
6325
|
+
node.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)("wheel", node, e2));
|
|
6326
6326
|
},
|
|
6327
6327
|
{ passive: false }
|
|
6328
6328
|
);
|
|
@@ -6991,7 +6991,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
6991
6991
|
let walkHadAnimation = false;
|
|
6992
6992
|
let walkHadInteractive = false;
|
|
6993
6993
|
const runUpdate = (node) => {
|
|
6994
|
-
const overridesUpdate = node.update !==
|
|
6994
|
+
const overridesUpdate = node.update !== _chunkSRXU3ZXKjs.Entity.prototype.update;
|
|
6995
6995
|
let pending = node.hasPendingAnimations();
|
|
6996
6996
|
if (pending || overridesUpdate) {
|
|
6997
6997
|
node.update(dt, time);
|
|
@@ -7000,7 +7000,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7000
7000
|
if (pending) walkHadAnimation = true;
|
|
7001
7001
|
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
7002
7002
|
if (this._devActive && this._devFrameCount % 120 === 0) {
|
|
7003
|
-
if (overridesUpdate && node.hasPendingAnimations ===
|
|
7003
|
+
if (overridesUpdate && node.hasPendingAnimations === _chunkSRXU3ZXKjs.Entity.prototype.hasPendingAnimations) {
|
|
7004
7004
|
this._devWarn(
|
|
7005
7005
|
`Entity "${node.id}" overrides update() but not hasPendingAnimations(). Custom motion in update() without overriding hasPendingAnimations() causes the idle throttle to slow the animation. Override hasPendingAnimations() to return true while motion is in flight.`
|
|
7006
7006
|
);
|
|
@@ -7172,8 +7172,43 @@ var Scene = (_class15 = class _Scene {
|
|
|
7172
7172
|
if (node.clipChildren) {
|
|
7173
7173
|
renderer.clip(0, 0, node.width, node.height);
|
|
7174
7174
|
}
|
|
7175
|
-
|
|
7176
|
-
|
|
7175
|
+
const children = node.children;
|
|
7176
|
+
let childStart = 0;
|
|
7177
|
+
let childEnd = children.length;
|
|
7178
|
+
if (childEnd > 0 && node.viewportCullChildren) {
|
|
7179
|
+
const det = a * d - b * c;
|
|
7180
|
+
if (Number.isFinite(det) && Math.abs(det) > 1e-12) {
|
|
7181
|
+
const invDet = 1 / det;
|
|
7182
|
+
let minLocalX = Infinity;
|
|
7183
|
+
let minLocalY = Infinity;
|
|
7184
|
+
let maxLocalX = -Infinity;
|
|
7185
|
+
let maxLocalY = -Infinity;
|
|
7186
|
+
for (let i = 0; i < 4; i++) {
|
|
7187
|
+
const worldX = i & 1 ? vw : 0;
|
|
7188
|
+
const worldY = i & 2 ? vh : 0;
|
|
7189
|
+
const dx = worldX - te;
|
|
7190
|
+
const dy = worldY - tf;
|
|
7191
|
+
const localX = (d * dx - c * dy) * invDet;
|
|
7192
|
+
const localY = (-b * dx + a * dy) * invDet;
|
|
7193
|
+
if (localX < minLocalX) minLocalX = localX;
|
|
7194
|
+
if (localX > maxLocalX) maxLocalX = localX;
|
|
7195
|
+
if (localY < minLocalY) minLocalY = localY;
|
|
7196
|
+
if (localY > maxLocalY) maxLocalY = localY;
|
|
7197
|
+
}
|
|
7198
|
+
const range = node.getRenderChildRange({
|
|
7199
|
+
x: minLocalX,
|
|
7200
|
+
y: minLocalY,
|
|
7201
|
+
width: maxLocalX - minLocalX,
|
|
7202
|
+
height: maxLocalY - minLocalY
|
|
7203
|
+
});
|
|
7204
|
+
if (range) {
|
|
7205
|
+
childStart = Math.max(0, Math.min(childEnd, Math.floor(range.start)));
|
|
7206
|
+
childEnd = Math.max(childStart, Math.min(childEnd, Math.ceil(range.end)));
|
|
7207
|
+
}
|
|
7208
|
+
}
|
|
7209
|
+
}
|
|
7210
|
+
for (let i = childStart; i < childEnd; i++) {
|
|
7211
|
+
renderNode(children[i], a, b, c, d, te, tf, worldOpacity);
|
|
7177
7212
|
}
|
|
7178
7213
|
renderer.flush();
|
|
7179
7214
|
renderer.restore();
|
|
@@ -7213,7 +7248,7 @@ var Scene = (_class15 = class _Scene {
|
|
|
7213
7248
|
* Export the current scene state to a lightweight, flat SVG XML string.
|
|
7214
7249
|
*/
|
|
7215
7250
|
toSVG() {
|
|
7216
|
-
const renderer = new (0,
|
|
7251
|
+
const renderer = new (0, _chunkZYYP2M5Djs.SVGRenderer)(this.width, this.height);
|
|
7217
7252
|
this.render(renderer, 0, 0);
|
|
7218
7253
|
return renderer.toXMLString();
|
|
7219
7254
|
}
|
|
@@ -7426,7 +7461,7 @@ function defaultMeasurer() {
|
|
|
7426
7461
|
sharedMeasurer ??= _layout.resolveGlyphMeasurer.call(void 0, "sans-serif");
|
|
7427
7462
|
return sharedMeasurer;
|
|
7428
7463
|
}
|
|
7429
|
-
var TextEntity = (_class16 = class extends
|
|
7464
|
+
var TextEntity = (_class16 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
7430
7465
|
|
|
7431
7466
|
|
|
7432
7467
|
|
|
@@ -7630,7 +7665,7 @@ var TextEntity = (_class16 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
7630
7665
|
}, _class16);
|
|
7631
7666
|
|
|
7632
7667
|
// src/components/GridTextEntity.ts
|
|
7633
|
-
var GridTextEntity = (_class17 = class extends
|
|
7668
|
+
var GridTextEntity = (_class17 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
7634
7669
|
|
|
7635
7670
|
__init185() {this.fillStyle = "#ffffff"}
|
|
7636
7671
|
__init186() {this.grid = []}
|
|
@@ -7724,7 +7759,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
7724
7759
|
const ey = py - cy;
|
|
7725
7760
|
return ex * ex + ey * ey;
|
|
7726
7761
|
}
|
|
7727
|
-
var SplineEntity = (_class18 = class extends
|
|
7762
|
+
var SplineEntity = (_class18 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
7728
7763
|
|
|
7729
7764
|
|
|
7730
7765
|
|
|
@@ -8052,7 +8087,7 @@ async function loadSpline(url) {
|
|
|
8052
8087
|
}
|
|
8053
8088
|
|
|
8054
8089
|
// src/components/Rect.ts
|
|
8055
|
-
var Rect = class extends
|
|
8090
|
+
var Rect = class extends _chunkSRXU3ZXKjs.Entity {
|
|
8056
8091
|
|
|
8057
8092
|
|
|
8058
8093
|
|
|
@@ -8108,7 +8143,7 @@ var Rect = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
8108
8143
|
};
|
|
8109
8144
|
|
|
8110
8145
|
// src/components/Circle.ts
|
|
8111
|
-
var Circle = class extends
|
|
8146
|
+
var Circle = class extends _chunkSRXU3ZXKjs.Entity {
|
|
8112
8147
|
|
|
8113
8148
|
|
|
8114
8149
|
|
|
@@ -8172,7 +8207,7 @@ var Circle = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
8172
8207
|
};
|
|
8173
8208
|
|
|
8174
8209
|
// src/components/Group.ts
|
|
8175
|
-
var Group = class extends
|
|
8210
|
+
var Group = class extends _chunkSRXU3ZXKjs.Entity {
|
|
8176
8211
|
constructor(...children) {
|
|
8177
8212
|
super();
|
|
8178
8213
|
if (children.length > 0) this.add(...children);
|
|
@@ -8191,7 +8226,7 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
8191
8226
|
|
|
8192
8227
|
|
|
8193
8228
|
// src/tree/DOMPortalEntity.ts
|
|
8194
|
-
var DOMPortalEntity = (_class19 = class extends
|
|
8229
|
+
var DOMPortalEntity = (_class19 = class extends _chunkSRXU3ZXKjs.Entity {
|
|
8195
8230
|
|
|
8196
8231
|
__init196() {this.isDOMPortal = true}
|
|
8197
8232
|
__init197() {this.domListeners = []}
|
|
@@ -8247,7 +8282,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
8247
8282
|
];
|
|
8248
8283
|
for (const type of events) {
|
|
8249
8284
|
const handler = (e) => {
|
|
8250
|
-
this.dispatchEvent(new (0,
|
|
8285
|
+
this.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)(type, this, e));
|
|
8251
8286
|
};
|
|
8252
8287
|
this.domElement.addEventListener(type, handler);
|
|
8253
8288
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -8258,7 +8293,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
8258
8293
|
];
|
|
8259
8294
|
for (const { native, vecto } of hoverEvents) {
|
|
8260
8295
|
const handler = (e) => {
|
|
8261
|
-
this.dispatchEvent(new (0,
|
|
8296
|
+
this.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)(vecto, this, e, false));
|
|
8262
8297
|
};
|
|
8263
8298
|
this.domElement.addEventListener(native, handler);
|
|
8264
8299
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -8266,7 +8301,7 @@ var DOMPortalEntity = (_class19 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
8266
8301
|
const focusEvents = ["focus", "blur"];
|
|
8267
8302
|
for (const type of focusEvents) {
|
|
8268
8303
|
const handler = (e) => {
|
|
8269
|
-
this.dispatchEvent(new (0,
|
|
8304
|
+
this.dispatchEvent(new (0, _chunkSRXU3ZXKjs.VectoJSEvent)(type, this, e, true));
|
|
8270
8305
|
};
|
|
8271
8306
|
this.domElement.addEventListener(type, handler, true);
|
|
8272
8307
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -8317,8 +8352,8 @@ var DOMPortalEntity = (_class19 = class extends _chunkXE6K7T5Sjs.Entity {
|
|
|
8317
8352
|
}, _class19);
|
|
8318
8353
|
|
|
8319
8354
|
// src/index.ts
|
|
8320
|
-
Scene.registerWebGLPointRendererCreator(
|
|
8321
|
-
Scene.registerWebGPUParticleSystemManager(
|
|
8355
|
+
Scene.registerWebGLPointRendererCreator(_chunkZYYP2M5Djs.createWebGLPointRenderer);
|
|
8356
|
+
Scene.registerWebGPUParticleSystemManager(_chunkZYYP2M5Djs.WebGPUParticleSystemManager);
|
|
8322
8357
|
|
|
8323
8358
|
|
|
8324
8359
|
|
|
@@ -8364,4 +8399,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkMO24PVGTjs.WebGPUParticleSystemM
|
|
|
8364
8399
|
|
|
8365
8400
|
|
|
8366
8401
|
|
|
8367
|
-
exports.CanvasRenderer =
|
|
8402
|
+
exports.CanvasRenderer = _chunkZYYP2M5Djs.CanvasRenderer; exports.Circle = Circle; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DEFAULT_CONTENT_SEMANTIC_BUDGET = DEFAULT_CONTENT_SEMANTIC_BUDGET; exports.DOMPortalEntity = DOMPortalEntity; exports.Entity = _chunkSRXU3ZXKjs.Entity; exports.GlyphRasterAtlas = _chunkZYYP2M5Djs.GlyphRasterAtlas; exports.GridTextEntity = GridTextEntity; exports.Group = Group; exports.MSDFTextEntity = _chunkSRXU3ZXKjs.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 = _chunkSRXU3ZXKjs.SVGEntity; exports.SVGRenderer = _chunkZYYP2M5Djs.SVGRenderer; exports.Scene = Scene; exports.SplineEntity = SplineEntity; exports.TextEntity = TextEntity; exports.TextRasterCache = _chunkZYYP2M5Djs.TextRasterCache; exports.VECTO_USER_TIMING = VECTO_USER_TIMING; exports.VectoJSEvent = _chunkSRXU3ZXKjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkZYYP2M5Djs.WebGPUParticleSystemManager; exports.beginVectoUserTiming = beginVectoUserTiming; exports.contentLineInHint = _chunkSRXU3ZXKjs.contentLineInHint; exports.createWebGLPointRenderer = _chunkZYYP2M5Djs.createWebGLPointRenderer; exports.endVectoUserTiming = endVectoUserTiming; exports.installRendererDevTraps = _chunkZYYP2M5Djs.installRendererDevTraps; exports.isRendererDevMode = _chunkZYYP2M5Djs.isRendererDevMode; exports.isSafeUrl = _chunkZYYP2M5Djs.isSafeUrl; exports.loadSpline = loadSpline; exports.measureVectoUserTiming = measureVectoUserTiming; exports.parseColorToRGBA = _chunkZYYP2M5Djs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkZYYP2M5Djs.sanitizeUrl; exports.setRendererDevMode = _chunkZYYP2M5Djs.setRendererDevMode;
|
package/dist/index.mjs
CHANGED
|
@@ -11,14 +11,14 @@ import {
|
|
|
11
11
|
parseColorToRGBA,
|
|
12
12
|
sanitizeUrl,
|
|
13
13
|
setRendererDevMode
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-LWEMD34D.mjs";
|
|
15
15
|
import {
|
|
16
16
|
Entity,
|
|
17
17
|
MSDFTextEntity,
|
|
18
18
|
SVGEntity,
|
|
19
19
|
VectoJSEvent,
|
|
20
20
|
contentLineInHint
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-QVTCKWDO.mjs";
|
|
22
22
|
|
|
23
23
|
// src/tree/ComputeParticleEntity.ts
|
|
24
24
|
var PARTICLE_STRIDE_FLOATS = 8;
|
|
@@ -7171,8 +7171,43 @@ var Scene = class _Scene {
|
|
|
7171
7171
|
if (node.clipChildren) {
|
|
7172
7172
|
renderer.clip(0, 0, node.width, node.height);
|
|
7173
7173
|
}
|
|
7174
|
-
|
|
7175
|
-
|
|
7174
|
+
const children = node.children;
|
|
7175
|
+
let childStart = 0;
|
|
7176
|
+
let childEnd = children.length;
|
|
7177
|
+
if (childEnd > 0 && node.viewportCullChildren) {
|
|
7178
|
+
const det = a * d - b * c;
|
|
7179
|
+
if (Number.isFinite(det) && Math.abs(det) > 1e-12) {
|
|
7180
|
+
const invDet = 1 / det;
|
|
7181
|
+
let minLocalX = Infinity;
|
|
7182
|
+
let minLocalY = Infinity;
|
|
7183
|
+
let maxLocalX = -Infinity;
|
|
7184
|
+
let maxLocalY = -Infinity;
|
|
7185
|
+
for (let i = 0; i < 4; i++) {
|
|
7186
|
+
const worldX = i & 1 ? vw : 0;
|
|
7187
|
+
const worldY = i & 2 ? vh : 0;
|
|
7188
|
+
const dx = worldX - te;
|
|
7189
|
+
const dy = worldY - tf;
|
|
7190
|
+
const localX = (d * dx - c * dy) * invDet;
|
|
7191
|
+
const localY = (-b * dx + a * dy) * invDet;
|
|
7192
|
+
if (localX < minLocalX) minLocalX = localX;
|
|
7193
|
+
if (localX > maxLocalX) maxLocalX = localX;
|
|
7194
|
+
if (localY < minLocalY) minLocalY = localY;
|
|
7195
|
+
if (localY > maxLocalY) maxLocalY = localY;
|
|
7196
|
+
}
|
|
7197
|
+
const range = node.getRenderChildRange({
|
|
7198
|
+
x: minLocalX,
|
|
7199
|
+
y: minLocalY,
|
|
7200
|
+
width: maxLocalX - minLocalX,
|
|
7201
|
+
height: maxLocalY - minLocalY
|
|
7202
|
+
});
|
|
7203
|
+
if (range) {
|
|
7204
|
+
childStart = Math.max(0, Math.min(childEnd, Math.floor(range.start)));
|
|
7205
|
+
childEnd = Math.max(childStart, Math.min(childEnd, Math.ceil(range.end)));
|
|
7206
|
+
}
|
|
7207
|
+
}
|
|
7208
|
+
}
|
|
7209
|
+
for (let i = childStart; i < childEnd; i++) {
|
|
7210
|
+
renderNode(children[i], a, b, c, d, te, tf, worldOpacity);
|
|
7176
7211
|
}
|
|
7177
7212
|
renderer.flush();
|
|
7178
7213
|
renderer.restore();
|
|
@@ -133,7 +133,7 @@ export declare class CanvasRenderer implements IRenderer {
|
|
|
133
133
|
/** @inheritdoc */
|
|
134
134
|
setGlobalAlpha(alpha: number): void;
|
|
135
135
|
/** @inheritdoc */
|
|
136
|
-
clip(x: number, y: number, width: number, height: number): void;
|
|
136
|
+
clip(x: number, y: number, width: number, height: number, radii?: number | number[]): void;
|
|
137
137
|
/** @inheritdoc */
|
|
138
138
|
beginPath(): void;
|
|
139
139
|
/** @inheritdoc */
|
|
@@ -129,12 +129,19 @@ export interface IRenderer {
|
|
|
129
129
|
* Intersect the current clip region with a rectangle. Affects all subsequent
|
|
130
130
|
* draws until the next {@link restore}; wrap in {@link save}/{@link restore}.
|
|
131
131
|
*
|
|
132
|
+
* When `radii` is provided the clip is a rounded rectangle instead of a sharp
|
|
133
|
+
* one. Backends that can only express a rectangular clip (e.g. a scissor-test
|
|
134
|
+
* GPU path) may ignore `radii`, so it must be treated as a progressive
|
|
135
|
+
* enhancement rather than a guarantee.
|
|
136
|
+
*
|
|
132
137
|
* @param x - Left edge.
|
|
133
138
|
* @param y - Top edge.
|
|
134
139
|
* @param width - Rectangle width.
|
|
135
140
|
* @param height - Rectangle height.
|
|
141
|
+
* @param radii - Optional corner radius (uniform) or per-corner array, matching
|
|
142
|
+
* {@link roundRect}. Omit for a sharp rectangle.
|
|
136
143
|
*/
|
|
137
|
-
clip(x: number, y: number, width: number, height: number): void;
|
|
144
|
+
clip(x: number, y: number, width: number, height: number, radii?: number | number[]): void;
|
|
138
145
|
/** Begin a new sub-path, discarding the current path. */
|
|
139
146
|
beginPath(): void;
|
|
140
147
|
/**
|
|
@@ -72,7 +72,7 @@ export declare class SVGRenderer implements IRenderer {
|
|
|
72
72
|
stop: number;
|
|
73
73
|
color: string;
|
|
74
74
|
}[]): SVGLinearGradient;
|
|
75
|
-
clip(x: number, y: number, width: number, height: number): void;
|
|
75
|
+
clip(x: number, y: number, width: number, height: number, radii?: number | number[]): void;
|
|
76
76
|
toXMLString(): string;
|
|
77
77
|
private resolveGradient;
|
|
78
78
|
private escapeXML;
|
package/dist/renderer.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunkZYYP2M5Djs = require('./chunk-ZYYP2M5D.js');
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
@@ -22,4 +22,4 @@ var _chunkMO24PVGTjs = require('./chunk-MO24PVGT.js');
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
exports.CanvasRenderer =
|
|
25
|
+
exports.CanvasRenderer = _chunkZYYP2M5Djs.CanvasRenderer; exports.GlyphRasterAtlas = _chunkZYYP2M5Djs.GlyphRasterAtlas; exports.SVGRenderer = _chunkZYYP2M5Djs.SVGRenderer; exports.TextRasterCache = _chunkZYYP2M5Djs.TextRasterCache; exports.WebGPUParticleSystemManager = _chunkZYYP2M5Djs.WebGPUParticleSystemManager; exports.createWebGLPointRenderer = _chunkZYYP2M5Djs.createWebGLPointRenderer; exports.installRendererDevTraps = _chunkZYYP2M5Djs.installRendererDevTraps; exports.isRendererDevMode = _chunkZYYP2M5Djs.isRendererDevMode; exports.parseColorToRGBA = _chunkZYYP2M5Djs.parseColorToRGBA; exports.setRendererDevMode = _chunkZYYP2M5Djs.setRendererDevMode;
|
package/dist/renderer.mjs
CHANGED
package/dist/text.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkSRXU3ZXKjs = require('./chunk-SRXU3ZXK.js');
|
|
6
6
|
|
|
7
7
|
// src/text/index.ts
|
|
8
8
|
var _text = require('@vectojs/text'); _createStarExport(_text);
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
exports.MSDFTextEntity =
|
|
12
|
+
exports.MSDFTextEntity = _chunkSRXU3ZXKjs.MSDFTextEntity; exports.SVGEntity = _chunkSRXU3ZXKjs.SVGEntity;
|
package/dist/text.mjs
CHANGED
package/dist/tree/Entity.d.ts
CHANGED
|
@@ -29,6 +29,13 @@ export interface Bounds {
|
|
|
29
29
|
width: number;
|
|
30
30
|
height: number;
|
|
31
31
|
}
|
|
32
|
+
/** Half-open child index range selected for the current render traversal. */
|
|
33
|
+
export interface RenderChildRange {
|
|
34
|
+
/** Index of the first child to visit. */
|
|
35
|
+
start: number;
|
|
36
|
+
/** Index after the last child to visit. */
|
|
37
|
+
end: number;
|
|
38
|
+
}
|
|
32
39
|
/**
|
|
33
40
|
* Describes an entity that renders as a single filled circle at its local
|
|
34
41
|
* origin, returned from {@link Entity.getBatchCircle} to opt into the renderer's
|
|
@@ -577,6 +584,12 @@ export declare class VectoJSEvent<N = unknown> {
|
|
|
577
584
|
* }
|
|
578
585
|
*/
|
|
579
586
|
export declare abstract class Entity {
|
|
587
|
+
/**
|
|
588
|
+
* Whether Scene may ask {@link getRenderChildRange} to prune this entity's
|
|
589
|
+
* visual child traversal. Off by default so ordinary containers pay no
|
|
590
|
+
* viewport-inversion cost.
|
|
591
|
+
*/
|
|
592
|
+
viewportCullChildren: boolean;
|
|
580
593
|
id: string;
|
|
581
594
|
children: Entity[];
|
|
582
595
|
parent: Entity | null;
|
|
@@ -658,9 +671,20 @@ export declare abstract class Entity {
|
|
|
658
671
|
* and promotes it.
|
|
659
672
|
*
|
|
660
673
|
* `'never'` suppresses the node entirely. Prefer `interactive = false` unless
|
|
661
|
-
* the entity genuinely needs
|
|
662
|
-
* this exists so a purely decorative interactive surface can opt
|
|
663
|
-
*
|
|
674
|
+
* the entity genuinely needs to stay hit-testable without any semantic
|
|
675
|
+
* presence — this exists so a purely decorative interactive surface can opt
|
|
676
|
+
* out of the a11y tree.
|
|
677
|
+
*
|
|
678
|
+
* **Pointer input is routed through the projected mirror.** The engine binds
|
|
679
|
+
* `pointerdown`/`pointermove`/`pointerup`/`click`/`dblclick` to each shadow
|
|
680
|
+
* element (the canvas itself only tracks `mouseX`/`mouseY`), so an entity
|
|
681
|
+
* with no materialized node receives **no pointer events at all** — neither
|
|
682
|
+
* in `'never'` mode nor in `'onDemand'` before it is engaged (focused,
|
|
683
|
+
* pointer target, or `requestA11yProjection`). Canvas hit-testing exists
|
|
684
|
+
* (`Scene.findEntityAt`) but is a query API, not a dispatch path. For a
|
|
685
|
+
* pointer-reactive region with no role (e.g. a desktop click-catcher), use
|
|
686
|
+
* `'eager'` + `a11yFullViewport` + `tabIndex: -1` with a role-less
|
|
687
|
+
* `getA11yAttributes()`: the mirror is AT-invisible but pointer-visible.
|
|
664
688
|
*
|
|
665
689
|
* **This does not replace an aggregate description.** A thousand `'onDemand'`
|
|
666
690
|
* danmaku are individually reachable but say nothing collectively. The proven
|
|
@@ -1046,6 +1070,22 @@ export declare abstract class Entity {
|
|
|
1046
1070
|
* @returns The local bounds, or `null` to opt out of culling.
|
|
1047
1071
|
*/
|
|
1048
1072
|
getBounds(): Bounds | null;
|
|
1073
|
+
/**
|
|
1074
|
+
* Select a contiguous subset of direct children for visual rendering.
|
|
1075
|
+
*
|
|
1076
|
+
* Return `null` (the default) to visit every child. Containers may override
|
|
1077
|
+
* this only when child order and geometry prove that every skipped child's
|
|
1078
|
+
* entire painted subtree lies outside `localViewport`. The Scene still keeps
|
|
1079
|
+
* all children resident, and hit testing, accessibility, and content
|
|
1080
|
+
* projection continue to see the complete tree. Skipped subtrees do not run
|
|
1081
|
+
* `update()` or `render()` in the visual pass, so opt in only for children that
|
|
1082
|
+
* are static while offscreen or whose state advances outside those methods.
|
|
1083
|
+
*
|
|
1084
|
+
* The returned range is half-open and is clamped to `children.length`.
|
|
1085
|
+
* `localViewport` is a conservative axis-aligned box obtained by mapping the
|
|
1086
|
+
* Scene viewport into this entity's local coordinate space.
|
|
1087
|
+
*/
|
|
1088
|
+
getRenderChildRange(localViewport: Bounds): RenderChildRange | null;
|
|
1049
1089
|
/**
|
|
1050
1090
|
* Opt into the renderer's draw-call batching fast-path for point-cloud /
|
|
1051
1091
|
* particle entities that draw as a single filled circle at their local origin.
|