@vectojs/core 0.2.7 → 0.2.9
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-GTQRCY6W.js → chunk-BPMNCGU7.js} +87 -2
- package/dist/{chunk-SSOP3F5F.mjs → chunk-FNXOS7IA.mjs} +161 -15
- package/dist/{chunk-YVN3PJRC.mjs → chunk-PY4KGL5Y.mjs} +19 -7
- package/dist/{chunk-DWMQYHNC.js → chunk-U4UYRERW.js} +27 -15
- package/dist/{chunk-HVJHXIKW.mjs → chunk-WT2XZHJQ.mjs} +87 -2
- package/dist/{chunk-BWLNEJJW.js → chunk-XLZDOFSB.js} +175 -29
- package/dist/components/TextEntity.d.ts +11 -0
- package/dist/index.js +148 -115
- package/dist/index.mjs +55 -22
- package/dist/layout/LayoutEngine.d.ts +24 -0
- package/dist/layout.js +2 -2
- package/dist/layout.mjs +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 +13 -3
- package/dist/tree/Scene.d.ts +10 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
LayoutResultBuffer,
|
|
4
4
|
computeLineSegments,
|
|
5
5
|
createCanvasMeasurer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FNXOS7IA.mjs";
|
|
7
7
|
import {
|
|
8
8
|
CanvasRenderer,
|
|
9
9
|
SVGRenderer,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isSafeUrl,
|
|
13
13
|
parseColorToRGBA,
|
|
14
14
|
sanitizeUrl
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-WT2XZHJQ.mjs";
|
|
16
16
|
import {
|
|
17
17
|
Easing,
|
|
18
18
|
Entity,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
TweenDriver,
|
|
25
25
|
VectoJSEvent,
|
|
26
26
|
isTweenConfig
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-PY4KGL5Y.mjs";
|
|
28
28
|
import {
|
|
29
29
|
ArabicShaper,
|
|
30
30
|
BidiResolver,
|
|
@@ -358,6 +358,11 @@ var Scene = class _Scene {
|
|
|
358
358
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
359
359
|
contentElements = /* @__PURE__ */ new Map();
|
|
360
360
|
contentProjectionEnabled = true;
|
|
361
|
+
// Animation/interactive flags collected during the render walk (tree-walk
|
|
362
|
+
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
363
|
+
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
364
|
+
frameHadAnimation = true;
|
|
365
|
+
frameHadInteractive = true;
|
|
361
366
|
resizeHandler;
|
|
362
367
|
focusedA11yElement = null;
|
|
363
368
|
caretBlinkTimer = null;
|
|
@@ -711,6 +716,18 @@ var Scene = class _Scene {
|
|
|
711
716
|
* Essential for deterministic rendering (e.g. video export).
|
|
712
717
|
* Note: You should call `scene.stop()` before using this to avoid conflict with the rAF loop.
|
|
713
718
|
*/
|
|
719
|
+
/**
|
|
720
|
+
* The scene-graph root entity. Exposed read-only for tooling — the devtools
|
|
721
|
+
* inspector walks it to build the Virtual Math Tree view. Mutate the graph
|
|
722
|
+
* through {@link add}/{@link remove}, not by editing this node directly.
|
|
723
|
+
*/
|
|
724
|
+
get rootEntity() {
|
|
725
|
+
return this.root;
|
|
726
|
+
}
|
|
727
|
+
/** The overlay layer root (see {@link showOverlay}), read-only for tooling. */
|
|
728
|
+
get overlayRootEntity() {
|
|
729
|
+
return this.overlayRoot;
|
|
730
|
+
}
|
|
714
731
|
step(dt) {
|
|
715
732
|
const time = this.lastTime + dt;
|
|
716
733
|
this.lastTime = time;
|
|
@@ -727,21 +744,7 @@ var Scene = class _Scene {
|
|
|
727
744
|
this.dirty = true;
|
|
728
745
|
}
|
|
729
746
|
/** True when any node in the subtree has a pending animation. */
|
|
730
|
-
hasAnyPendingAnimation(node) {
|
|
731
|
-
if (node.hasPendingAnimations()) return true;
|
|
732
|
-
for (const child of node.children) {
|
|
733
|
-
if (this.hasAnyPendingAnimation(child)) return true;
|
|
734
|
-
}
|
|
735
|
-
return false;
|
|
736
|
-
}
|
|
737
747
|
/** True when any node in the subtree is interactive (drives a11y sync). */
|
|
738
|
-
hasAnyInteractive(node) {
|
|
739
|
-
if (node.interactive) return true;
|
|
740
|
-
for (const child of node.children) {
|
|
741
|
-
if (this.hasAnyInteractive(child)) return true;
|
|
742
|
-
}
|
|
743
|
-
return false;
|
|
744
|
-
}
|
|
745
748
|
syncA11y(node) {
|
|
746
749
|
if (!this.a11yRoot) return;
|
|
747
750
|
if (node.isDOMPortal) {
|
|
@@ -1276,7 +1279,7 @@ var Scene = class _Scene {
|
|
|
1276
1279
|
loop(time) {
|
|
1277
1280
|
if (!this.isRunning) return;
|
|
1278
1281
|
let cap = this.effectiveMaxFPS();
|
|
1279
|
-
const isIdle = !this.dirty && !this.
|
|
1282
|
+
const isIdle = !this.dirty && !this.frameHadAnimation;
|
|
1280
1283
|
if (isIdle && this.autoThrottle && this.renderMode === "always" && this.maxFPS > 0) {
|
|
1281
1284
|
cap = Math.min(cap, 2);
|
|
1282
1285
|
}
|
|
@@ -1292,8 +1295,8 @@ var Scene = class _Scene {
|
|
|
1292
1295
|
}
|
|
1293
1296
|
this.dirty = false;
|
|
1294
1297
|
this.render(this.renderer, dt, time);
|
|
1295
|
-
const hasActiveAnimation = this.
|
|
1296
|
-
const hasInteractive = this.
|
|
1298
|
+
const hasActiveAnimation = this.frameHadAnimation;
|
|
1299
|
+
const hasInteractive = this.frameHadInteractive;
|
|
1297
1300
|
const wantsContentSync = this.contentProjectionEnabled;
|
|
1298
1301
|
const shouldSyncInterval = this.a11ySyncInterval <= 0 || time - this.lastA11ySync >= this.a11ySyncInterval;
|
|
1299
1302
|
if ((hasInteractive || this.a11yElements.size > 0 || wantsContentSync) && (shouldSyncInterval || this.a11yPendingSyncAfterAnimation)) {
|
|
@@ -1450,8 +1453,14 @@ var Scene = class _Scene {
|
|
|
1450
1453
|
}
|
|
1451
1454
|
const vw = this.width;
|
|
1452
1455
|
const vh = this.height;
|
|
1456
|
+
let walkHadAnimation = false;
|
|
1457
|
+
let walkHadInteractive = false;
|
|
1453
1458
|
const renderNode = (node, pa, pb, pc, pd, pe, pf, parentOpacity) => {
|
|
1454
|
-
if (isMainRenderer)
|
|
1459
|
+
if (isMainRenderer) {
|
|
1460
|
+
node.update(dt, time);
|
|
1461
|
+
if (!walkHadAnimation && node.hasPendingAnimations()) walkHadAnimation = true;
|
|
1462
|
+
if (!walkHadInteractive && node.interactive) walkHadInteractive = true;
|
|
1463
|
+
}
|
|
1455
1464
|
const cos = Math.cos(node.rotation);
|
|
1456
1465
|
const sin = Math.sin(node.rotation);
|
|
1457
1466
|
const te = pa * node.x + pc * node.y + pe;
|
|
@@ -1571,7 +1580,11 @@ var Scene = class _Scene {
|
|
|
1571
1580
|
for (const overlay of this.overlayRoot.children) {
|
|
1572
1581
|
renderNode(overlay, 1, 0, 0, 1, 0, 0, 1);
|
|
1573
1582
|
}
|
|
1574
|
-
if (isMainRenderer)
|
|
1583
|
+
if (isMainRenderer) {
|
|
1584
|
+
this.frameHadAnimation = walkHadAnimation;
|
|
1585
|
+
this.frameHadInteractive = walkHadInteractive;
|
|
1586
|
+
this.reconcilePortals();
|
|
1587
|
+
}
|
|
1575
1588
|
renderer.flush();
|
|
1576
1589
|
if (isMainRenderer) {
|
|
1577
1590
|
this.pointRenderer?.flush();
|
|
@@ -1835,6 +1848,26 @@ var TextEntity = class extends Entity {
|
|
|
1835
1848
|
this.applyLayout();
|
|
1836
1849
|
return this;
|
|
1837
1850
|
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Set horizontal alignment (`'justify'` stretches wrapped lines flush to
|
|
1853
|
+
* the wrap width; the last line stays ragged) and reflow.
|
|
1854
|
+
*/
|
|
1855
|
+
setTextAlign(align) {
|
|
1856
|
+
this.layout.textAlign = align;
|
|
1857
|
+
this.applyLayout();
|
|
1858
|
+
return this;
|
|
1859
|
+
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Plug a hyphenator (word → parts). Break opportunities are baked in during
|
|
1862
|
+
* the cold pass, so this re-prepares the current text. Soft hyphens
|
|
1863
|
+
* (U+00AD) in the text work without one.
|
|
1864
|
+
*/
|
|
1865
|
+
setHyphenator(fn) {
|
|
1866
|
+
this.layout.hyphenate = fn;
|
|
1867
|
+
this.prepared = this.layout.prepare(this.text, this.atlas, this.fontSize);
|
|
1868
|
+
this.applyLayout();
|
|
1869
|
+
return this;
|
|
1870
|
+
}
|
|
1838
1871
|
/** Hot pass: place the cached {@link PreparedText} and refresh the a11y box. */
|
|
1839
1872
|
applyLayout() {
|
|
1840
1873
|
const result = this.layout.layoutPrepared(this.prepared);
|
|
@@ -88,6 +88,11 @@ export interface PreparedWord {
|
|
|
88
88
|
isWordLike: boolean | undefined;
|
|
89
89
|
/** Pre-computed `word.trim().length === 0`. */
|
|
90
90
|
isWhitespace: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Glyph indices where the word may break with a visible hyphen — from
|
|
93
|
+
* soft hyphens (U+00AD) in the source or the engine's `hyphenate` hook.
|
|
94
|
+
*/
|
|
95
|
+
breakPoints?: number[];
|
|
91
96
|
}
|
|
92
97
|
/** A measured paragraph; `isEmpty` marks a blank line (forced newline). */
|
|
93
98
|
export interface PreparedParagraph {
|
|
@@ -107,6 +112,8 @@ export interface PreparedText {
|
|
|
107
112
|
paragraphs: PreparedParagraph[];
|
|
108
113
|
fontSize: number;
|
|
109
114
|
fallbackToCanvas?: boolean;
|
|
115
|
+
/** Advance width of '-' at `fontSize`, for wrap-time hyphen insertion. */
|
|
116
|
+
hyphenWidth?: number;
|
|
110
117
|
}
|
|
111
118
|
/**
|
|
112
119
|
* A rectangular region (in the text's local coordinate space) that text must
|
|
@@ -140,6 +147,13 @@ export declare function computeLineSegments(top: number, bottom: number, maxWidt
|
|
|
140
147
|
*/
|
|
141
148
|
export declare class LayoutEngine {
|
|
142
149
|
maxWidth: number;
|
|
150
|
+
/**
|
|
151
|
+
* Horizontal alignment. `'justify'` stretches inter-word spaces (or, for
|
|
152
|
+
* space-less CJK lines, inter-character gaps) so wrapped lines end flush at
|
|
153
|
+
* `maxWidth`; the last line of each paragraph stays ragged. Only applies to
|
|
154
|
+
* the object layout path without exclusion shapes.
|
|
155
|
+
*/
|
|
156
|
+
textAlign: 'left' | 'justify';
|
|
143
157
|
maxHeight: number;
|
|
144
158
|
preserveLeadingSpaces: boolean;
|
|
145
159
|
private wordSegmenter;
|
|
@@ -150,6 +164,16 @@ export declare class LayoutEngine {
|
|
|
150
164
|
private richParagraphCache;
|
|
151
165
|
private lastAtlas;
|
|
152
166
|
private measurer;
|
|
167
|
+
private _hyphenate;
|
|
168
|
+
/**
|
|
169
|
+
* Optional hyphenator: given a word, return its break parts (e.g.
|
|
170
|
+
* `['hyphen', 'ation']`). Used at wrap time when a word doesn't fit; a
|
|
171
|
+
* visible '-' is drawn at the chosen break. Soft hyphens (U+00AD) in the
|
|
172
|
+
* source work without any hyphenator. Setting this clears the prepared
|
|
173
|
+
* caches (break opportunities are baked in during prepare()).
|
|
174
|
+
*/
|
|
175
|
+
get hyphenate(): ((word: string) => string[]) | null;
|
|
176
|
+
set hyphenate(fn: ((word: string) => string[]) | null);
|
|
153
177
|
constructor(maxWidth: number, maxHeight: number, measurer?: GlyphMeasurer | null);
|
|
154
178
|
private getWordSegments;
|
|
155
179
|
/**
|
package/dist/layout.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkXLZDOFSBjs = require('./chunk-XLZDOFSB.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
|
|
@@ -13,4 +13,4 @@ var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
exports.LayoutEngine =
|
|
16
|
+
exports.LayoutEngine = _chunkXLZDOFSBjs.LayoutEngine; exports.LayoutResultBuffer = _chunkXLZDOFSBjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunkCTZQOM5Zjs.LayoutWorkerManager; exports.computeLineSegments = _chunkXLZDOFSBjs.computeLineSegments; exports.createCanvasMeasurer = _chunkXLZDOFSBjs.createCanvasMeasurer;
|
package/dist/layout.mjs
CHANGED
package/dist/renderer.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkBPMNCGU7js = require('./chunk-BPMNCGU7.js');
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
exports.CanvasRenderer =
|
|
14
|
+
exports.CanvasRenderer = _chunkBPMNCGU7js.CanvasRenderer; exports.SVGRenderer = _chunkBPMNCGU7js.SVGRenderer; exports.WebGPUParticleSystemManager = _chunkBPMNCGU7js.WebGPUParticleSystemManager; exports.createWebGLPointRenderer = _chunkBPMNCGU7js.createWebGLPointRenderer; exports.parseColorToRGBA = _chunkBPMNCGU7js.parseColorToRGBA;
|
package/dist/renderer.mjs
CHANGED
package/dist/text.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkU4UYRERWjs = require('./chunk-U4UYRERW.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -13,4 +13,4 @@ var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
exports.ArabicShaper = _chunkCTZQOM5Zjs.ArabicShaper; exports.BidiResolver = _chunkCTZQOM5Zjs.BidiResolver; exports.MSDFFont =
|
|
16
|
+
exports.ArabicShaper = _chunkCTZQOM5Zjs.ArabicShaper; exports.BidiResolver = _chunkCTZQOM5Zjs.BidiResolver; exports.MSDFFont = _chunkU4UYRERWjs.MSDFFont; exports.MSDFTextEntity = _chunkU4UYRERWjs.MSDFTextEntity; exports.SVGEntity = _chunkU4UYRERWjs.SVGEntity;
|
package/dist/text.mjs
CHANGED
package/dist/tree/Entity.d.ts
CHANGED
|
@@ -262,6 +262,16 @@ export declare abstract class Entity {
|
|
|
262
262
|
/**
|
|
263
263
|
* Append a child entity to this node's children array.
|
|
264
264
|
*
|
|
265
|
+
* If `child` already has a parent (including `this`), it's detached from it
|
|
266
|
+
* first — otherwise re-adding an already-added child duplicates it in
|
|
267
|
+
* `children[]` (one `remove()` call only strips the first occurrence,
|
|
268
|
+
* leaving a stale entry that keeps rendering/updating despite
|
|
269
|
+
* `child.parent` reporting `null`), and re-parenting to a different entity
|
|
270
|
+
* without an explicit `remove()` first leaves the old parent holding a
|
|
271
|
+
* stale reference whose own `.parent` disagrees with where it now lives.
|
|
272
|
+
* `child.parent` is only ever `null` or `this`'s ultimate owner, so this
|
|
273
|
+
* check is O(1) for the overwhelming common case (a brand-new entity).
|
|
274
|
+
*
|
|
265
275
|
* @param child - The entity to add as a child.
|
|
266
276
|
* @returns `this` for method chaining.
|
|
267
277
|
*/
|
|
@@ -405,8 +415,8 @@ export declare abstract class Entity {
|
|
|
405
415
|
getWorldBounds(): Bounds;
|
|
406
416
|
/**
|
|
407
417
|
* Accumulated world scale factors: this entity's own `scaleX`/`scaleY` times
|
|
408
|
-
* those of every ancestor
|
|
409
|
-
*
|
|
418
|
+
* those of every ancestor. Useful for mapping a world-space point back into
|
|
419
|
+
* local space for hit-testing.
|
|
410
420
|
*
|
|
411
421
|
* @returns The world scale `{ x, y }`.
|
|
412
422
|
*/
|
|
@@ -416,7 +426,7 @@ export declare abstract class Entity {
|
|
|
416
426
|
};
|
|
417
427
|
/**
|
|
418
428
|
* Accumulated world rotation: this entity's own `rotation` plus
|
|
419
|
-
* that of every ancestor
|
|
429
|
+
* that of every ancestor.
|
|
420
430
|
*
|
|
421
431
|
* @returns The accumulated world rotation in radians.
|
|
422
432
|
*/
|
package/dist/tree/Scene.d.ts
CHANGED
|
@@ -158,6 +158,8 @@ export declare class Scene {
|
|
|
158
158
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
159
159
|
private contentElements;
|
|
160
160
|
private contentProjectionEnabled;
|
|
161
|
+
private frameHadAnimation;
|
|
162
|
+
private frameHadInteractive;
|
|
161
163
|
private resizeHandler;
|
|
162
164
|
private focusedA11yElement;
|
|
163
165
|
private caretBlinkTimer;
|
|
@@ -267,6 +269,14 @@ export declare class Scene {
|
|
|
267
269
|
* Essential for deterministic rendering (e.g. video export).
|
|
268
270
|
* Note: You should call `scene.stop()` before using this to avoid conflict with the rAF loop.
|
|
269
271
|
*/
|
|
272
|
+
/**
|
|
273
|
+
* The scene-graph root entity. Exposed read-only for tooling — the devtools
|
|
274
|
+
* inspector walks it to build the Virtual Math Tree view. Mutate the graph
|
|
275
|
+
* through {@link add}/{@link remove}, not by editing this node directly.
|
|
276
|
+
*/
|
|
277
|
+
get rootEntity(): Entity;
|
|
278
|
+
/** The overlay layer root (see {@link showOverlay}), read-only for tooling. */
|
|
279
|
+
get overlayRootEntity(): Entity;
|
|
270
280
|
step(dt: number): void;
|
|
271
281
|
/**
|
|
272
282
|
* Mark the scene as needing a redraw on the next frame.
|
|
@@ -276,9 +286,7 @@ export declare class Scene {
|
|
|
276
286
|
*/
|
|
277
287
|
markDirty(): void;
|
|
278
288
|
/** True when any node in the subtree has a pending animation. */
|
|
279
|
-
private hasAnyPendingAnimation;
|
|
280
289
|
/** True when any node in the subtree is interactive (drives a11y sync). */
|
|
281
|
-
private hasAnyInteractive;
|
|
282
290
|
private syncA11y;
|
|
283
291
|
/**
|
|
284
292
|
* Mirror one entity's static text ({@link Entity.getContentProjection}) as a
|