@vectojs/core 1.30.0 → 1.31.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-2WXZCPYQ.mjs → chunk-RWN3ITBD.mjs} +34 -0
- package/dist/{chunk-7PI7LVWW.js → chunk-TRT2TRCW.js} +55 -21
- package/dist/components/TextEntity.d.ts +3 -0
- package/dist/index.js +252 -192
- package/dist/index.mjs +71 -11
- package/dist/text/MSDFTextEntity.d.ts +3 -0
- package/dist/text.js +2 -2
- package/dist/text.mjs +1 -1
- package/dist/tree/Entity.d.ts +26 -0
- package/dist/tree/Scene.d.ts +39 -1
- package/package.json +1 -1
|
@@ -1095,6 +1095,34 @@ var Entity = class {
|
|
|
1095
1095
|
void hint;
|
|
1096
1096
|
return null;
|
|
1097
1097
|
}
|
|
1098
|
+
/**
|
|
1099
|
+
* A cheap, monotonically-increasing stamp of this entity's projected content.
|
|
1100
|
+
*
|
|
1101
|
+
* Purely an optimization, and opt-in: returning `null` (the default) means
|
|
1102
|
+
* "I cannot cheaply tell whether my content changed", and the {@link Scene}
|
|
1103
|
+
* then rebuilds the projection every synced frame exactly as before. An
|
|
1104
|
+
* implementation must bump the value whenever anything
|
|
1105
|
+
* {@link getContentProjection} would report changes — text, fonts, line
|
|
1106
|
+
* geometry, `selectable`, grid revision.
|
|
1107
|
+
*
|
|
1108
|
+
* When two consecutive syncs report the same epoch AND the entity's geometry
|
|
1109
|
+
* is unchanged, `Scene` skips the block *before* calling
|
|
1110
|
+
* {@link getContentProjection}. That matters because the projection call is
|
|
1111
|
+
* O(glyphs-in-block) and the DOM diff around it costs about the same again:
|
|
1112
|
+
* measured on a 1500-resident-block document, a sync in which the projected
|
|
1113
|
+
* text was byte-identical before and after still cost 17.875 ms, and skipping
|
|
1114
|
+
* unchanged blocks took that to 0.475 ms (carryctx CTX-0199, vectojs#343).
|
|
1115
|
+
*
|
|
1116
|
+
* Correctness is entirely on the implementer: a stale epoch means stale DOM,
|
|
1117
|
+
* so bump it in the same place the content is invalidated rather than trying
|
|
1118
|
+
* to enumerate mutation sites afterwards. Any monotonic counter works; the
|
|
1119
|
+
* value is only ever compared for equality with the previous sync's.
|
|
1120
|
+
*
|
|
1121
|
+
* @returns The current content epoch, or `null` to disable skipping.
|
|
1122
|
+
*/
|
|
1123
|
+
getContentEpoch() {
|
|
1124
|
+
return null;
|
|
1125
|
+
}
|
|
1098
1126
|
/**
|
|
1099
1127
|
* Whether this entity still has a queued/running tween animation, or an
|
|
1100
1128
|
* active {@link setTransition}/{@link animateTo}/{@link springTo} property
|
|
@@ -1138,6 +1166,8 @@ var MSDFTextEntity = class extends Entity {
|
|
|
1138
1166
|
layoutText = "";
|
|
1139
1167
|
text = "";
|
|
1140
1168
|
lastRenderedSeqId = 0;
|
|
1169
|
+
/** Bumped by {@link queueLayout}; read by `Scene` to skip an unchanged sync. */
|
|
1170
|
+
contentEpoch = 0;
|
|
1141
1171
|
// Atlas-decode subscription (see watchAtlasDecode). Held so `destroy()` can
|
|
1142
1172
|
// release it: the handler closes over `this`, so leaving it attached to a
|
|
1143
1173
|
// long-lived shared atlas image would retain the whole entity.
|
|
@@ -1257,6 +1287,7 @@ var MSDFTextEntity = class extends Entity {
|
|
|
1257
1287
|
});
|
|
1258
1288
|
}
|
|
1259
1289
|
queueLayout() {
|
|
1290
|
+
this.contentEpoch++;
|
|
1260
1291
|
LayoutWorkerManager.getInstance().queueLayout(this.id, this.layoutText, {
|
|
1261
1292
|
fontId: this.font.id,
|
|
1262
1293
|
fontSize: this.fontSize,
|
|
@@ -1286,6 +1317,9 @@ var MSDFTextEntity = class extends Entity {
|
|
|
1286
1317
|
lineHeight: this.lineHeight
|
|
1287
1318
|
};
|
|
1288
1319
|
}
|
|
1320
|
+
getContentEpoch() {
|
|
1321
|
+
return this.contentEpoch;
|
|
1322
|
+
}
|
|
1289
1323
|
isPointInside(globalX, globalY) {
|
|
1290
1324
|
if (!this.layoutResult) return false;
|
|
1291
1325
|
const local = this.worldToLocal(globalX, globalY);
|
|
@@ -1097,6 +1097,34 @@ var Entity = (_class2 = class {
|
|
|
1097
1097
|
void hint;
|
|
1098
1098
|
return null;
|
|
1099
1099
|
}
|
|
1100
|
+
/**
|
|
1101
|
+
* A cheap, monotonically-increasing stamp of this entity's projected content.
|
|
1102
|
+
*
|
|
1103
|
+
* Purely an optimization, and opt-in: returning `null` (the default) means
|
|
1104
|
+
* "I cannot cheaply tell whether my content changed", and the {@link Scene}
|
|
1105
|
+
* then rebuilds the projection every synced frame exactly as before. An
|
|
1106
|
+
* implementation must bump the value whenever anything
|
|
1107
|
+
* {@link getContentProjection} would report changes — text, fonts, line
|
|
1108
|
+
* geometry, `selectable`, grid revision.
|
|
1109
|
+
*
|
|
1110
|
+
* When two consecutive syncs report the same epoch AND the entity's geometry
|
|
1111
|
+
* is unchanged, `Scene` skips the block *before* calling
|
|
1112
|
+
* {@link getContentProjection}. That matters because the projection call is
|
|
1113
|
+
* O(glyphs-in-block) and the DOM diff around it costs about the same again:
|
|
1114
|
+
* measured on a 1500-resident-block document, a sync in which the projected
|
|
1115
|
+
* text was byte-identical before and after still cost 17.875 ms, and skipping
|
|
1116
|
+
* unchanged blocks took that to 0.475 ms (carryctx CTX-0199, vectojs#343).
|
|
1117
|
+
*
|
|
1118
|
+
* Correctness is entirely on the implementer: a stale epoch means stale DOM,
|
|
1119
|
+
* so bump it in the same place the content is invalidated rather than trying
|
|
1120
|
+
* to enumerate mutation sites afterwards. Any monotonic counter works; the
|
|
1121
|
+
* value is only ever compared for equality with the previous sync's.
|
|
1122
|
+
*
|
|
1123
|
+
* @returns The current content epoch, or `null` to disable skipping.
|
|
1124
|
+
*/
|
|
1125
|
+
getContentEpoch() {
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1100
1128
|
/**
|
|
1101
1129
|
* Whether this entity still has a queued/running tween animation, or an
|
|
1102
1130
|
* active {@link setTransition}/{@link animateTo}/{@link springTo} property
|
|
@@ -1140,16 +1168,18 @@ var MSDFTextEntity = (_class3 = class extends Entity {
|
|
|
1140
1168
|
__init41() {this.layoutText = ""}
|
|
1141
1169
|
__init42() {this.text = ""}
|
|
1142
1170
|
__init43() {this.lastRenderedSeqId = 0}
|
|
1171
|
+
/** Bumped by {@link queueLayout}; read by `Scene` to skip an unchanged sync. */
|
|
1172
|
+
__init44() {this.contentEpoch = 0}
|
|
1143
1173
|
// Atlas-decode subscription (see watchAtlasDecode). Held so `destroy()` can
|
|
1144
1174
|
// release it: the handler closes over `this`, so leaving it attached to a
|
|
1145
1175
|
// long-lived shared atlas image would retain the whole entity.
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1176
|
+
__init45() {this.atlasDecodeTarget = null}
|
|
1177
|
+
__init46() {this.atlasDecodeHandler = null}
|
|
1178
|
+
__init47() {this.rgbColorCache = /* @__PURE__ */ new Map()}
|
|
1179
|
+
__init48() {this.fontStringCache = []}
|
|
1180
|
+
__init49() {this.layoutResult = null}
|
|
1151
1181
|
constructor(text, options) {
|
|
1152
|
-
super();_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);_class3.prototype.__init46.call(this);_class3.prototype.__init47.call(this);_class3.prototype.__init48.call(this);;
|
|
1182
|
+
super();_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);_class3.prototype.__init46.call(this);_class3.prototype.__init47.call(this);_class3.prototype.__init48.call(this);_class3.prototype.__init49.call(this);;
|
|
1153
1183
|
this.font = options.font;
|
|
1154
1184
|
this.texture = options.texture;
|
|
1155
1185
|
this.fallbackFont = _nullishCoalesce(options.fallbackFont, () => ( "sans-serif"));
|
|
@@ -1259,6 +1289,7 @@ var MSDFTextEntity = (_class3 = class extends Entity {
|
|
|
1259
1289
|
});
|
|
1260
1290
|
}
|
|
1261
1291
|
queueLayout() {
|
|
1292
|
+
this.contentEpoch++;
|
|
1262
1293
|
_layout.LayoutWorkerManager.getInstance().queueLayout(this.id, this.layoutText, {
|
|
1263
1294
|
fontId: this.font.id,
|
|
1264
1295
|
fontSize: this.fontSize,
|
|
@@ -1288,6 +1319,9 @@ var MSDFTextEntity = (_class3 = class extends Entity {
|
|
|
1288
1319
|
lineHeight: this.lineHeight
|
|
1289
1320
|
};
|
|
1290
1321
|
}
|
|
1322
|
+
getContentEpoch() {
|
|
1323
|
+
return this.contentEpoch;
|
|
1324
|
+
}
|
|
1291
1325
|
isPointInside(globalX, globalY) {
|
|
1292
1326
|
if (!this.layoutResult) return false;
|
|
1293
1327
|
const local = this.worldToLocal(globalX, globalY);
|
|
@@ -1421,23 +1455,23 @@ var SVGEntity = (_class4 = class extends Entity {
|
|
|
1421
1455
|
* rasterized. Set to `'transparent'` to opt out and keep the box empty.
|
|
1422
1456
|
* Default `'rgba(248,113,113,0.9)'`.
|
|
1423
1457
|
*/
|
|
1424
|
-
|
|
1458
|
+
__init50() {this.fallbackStroke = "rgba(248,113,113,0.9)"}
|
|
1425
1459
|
/** Fill behind the fallback marker. Default `'rgba(248,113,113,0.12)'`. */
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1460
|
+
__init51() {this.fallbackFill = "rgba(248,113,113,0.12)"}
|
|
1461
|
+
__init52() {this.svgSource = ""}
|
|
1462
|
+
__init53() {this.imageBitmap = null}
|
|
1463
|
+
__init54() {this.imageElement = null}
|
|
1464
|
+
__init55() {this.blobURL = null}
|
|
1465
|
+
__init56() {this.currentImg = null}
|
|
1466
|
+
__init57() {this.lodTimeout = null}
|
|
1467
|
+
__init58() {this.rasterFailed = false}
|
|
1468
|
+
__init59() {this.cachedDoc = null}
|
|
1469
|
+
__init60() {this.baseWidth = 100}
|
|
1470
|
+
__init61() {this.baseHeight = 100}
|
|
1471
|
+
__init62() {this.lastRasterizedScale = 1}
|
|
1472
|
+
__init63() {this.targetScale = 1}
|
|
1439
1473
|
constructor(svgSource, id) {
|
|
1440
|
-
super(id);_class4.prototype.
|
|
1474
|
+
super(id);_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);_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);;
|
|
1441
1475
|
this.setSVGSource(svgSource);
|
|
1442
1476
|
}
|
|
1443
1477
|
setSVGSource(svgSource) {
|
|
@@ -12,12 +12,15 @@ export declare class TextEntity extends Entity {
|
|
|
12
12
|
hoveredFillStyle: string | any;
|
|
13
13
|
lineWidth: number;
|
|
14
14
|
private isHovered;
|
|
15
|
+
/** Bumped by {@link applyLayout}; read by `Scene` to skip an unchanged sync. */
|
|
16
|
+
private contentEpoch;
|
|
15
17
|
constructor(text: string, atlas: any, maxWidth: number, fontSize?: number);
|
|
16
18
|
/**
|
|
17
19
|
* Mirror the rendered text into the DOM content layer: find-in-page, screen
|
|
18
20
|
* readers, crawlers, and translation see the same string the canvas draws.
|
|
19
21
|
*/
|
|
20
22
|
getContentProjection(): ContentProjection | null;
|
|
23
|
+
getContentEpoch(): number;
|
|
21
24
|
/**
|
|
22
25
|
* Replace the text content. Runs the **cold** measurement pass (re-segment +
|
|
23
26
|
* re-measure) since the glyphs changed, then re-lays out.
|