@vectojs/core 1.5.0 → 1.6.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-N7DNUDVY.mjs → chunk-3CODWSF3.mjs} +27 -0
- package/dist/{chunk-NHNOKBD4.js → chunk-DFNK6OV6.js} +28 -1
- package/dist/{chunk-FNXOS7IA.mjs → chunk-V7GUWG5C.mjs} +5 -2
- package/dist/{chunk-XLZDOFSB.js → chunk-ZBKKRYDH.js} +5 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +87 -29
- package/dist/index.mjs +63 -5
- package/dist/layout.js +2 -2
- package/dist/layout.mjs +1 -1
- package/dist/text/Typography.d.ts +11 -0
- package/dist/text/index.d.ts +1 -0
- package/dist/text.js +6 -2
- package/dist/text.mjs +7 -3
- package/dist/tree/Entity.d.ts +44 -0
- package/package.json +2 -2
|
@@ -939,6 +939,31 @@ var Entity = class {
|
|
|
939
939
|
}
|
|
940
940
|
};
|
|
941
941
|
|
|
942
|
+
// src/text/Typography.ts
|
|
943
|
+
var typographyContext;
|
|
944
|
+
var baselineCache = /* @__PURE__ */ new Map();
|
|
945
|
+
function cssLineBoxBaseline(font, lineHeight) {
|
|
946
|
+
if (typeof document === "undefined") return lineHeight * 0.8;
|
|
947
|
+
const key = `${font}\0${lineHeight}`;
|
|
948
|
+
const cached = baselineCache.get(key);
|
|
949
|
+
if (cached !== void 0) return cached;
|
|
950
|
+
if (typographyContext === void 0) {
|
|
951
|
+
typographyContext = document.createElement("canvas").getContext("2d");
|
|
952
|
+
}
|
|
953
|
+
if (!typographyContext) return lineHeight * 0.8;
|
|
954
|
+
typographyContext.font = font;
|
|
955
|
+
const metrics = typographyContext.measureText("Mg");
|
|
956
|
+
const ascent = metrics.fontBoundingBoxAscent || metrics.actualBoundingBoxAscent;
|
|
957
|
+
const descent = metrics.fontBoundingBoxDescent || metrics.actualBoundingBoxDescent;
|
|
958
|
+
if (!(ascent > 0) || !(descent >= 0)) return lineHeight * 0.8;
|
|
959
|
+
const baseline = (lineHeight - ascent - descent) / 2 + ascent;
|
|
960
|
+
baselineCache.set(key, baseline);
|
|
961
|
+
return baseline;
|
|
962
|
+
}
|
|
963
|
+
function clearCssLineBoxMetrics() {
|
|
964
|
+
baselineCache.clear();
|
|
965
|
+
}
|
|
966
|
+
|
|
942
967
|
// src/text/MSDFFont.ts
|
|
943
968
|
function kernKey(a, b) {
|
|
944
969
|
return a * 1114112 + b;
|
|
@@ -1442,6 +1467,8 @@ export {
|
|
|
1442
1467
|
SpringDriver,
|
|
1443
1468
|
VectoJSEvent,
|
|
1444
1469
|
Entity,
|
|
1470
|
+
cssLineBoxBaseline,
|
|
1471
|
+
clearCssLineBoxMetrics,
|
|
1445
1472
|
MSDFFont,
|
|
1446
1473
|
MSDFTextEntity,
|
|
1447
1474
|
SVGEntity
|
|
@@ -939,6 +939,31 @@ var Entity = (_class4 = class {
|
|
|
939
939
|
}
|
|
940
940
|
}, _class4);
|
|
941
941
|
|
|
942
|
+
// src/text/Typography.ts
|
|
943
|
+
var typographyContext;
|
|
944
|
+
var baselineCache = /* @__PURE__ */ new Map();
|
|
945
|
+
function cssLineBoxBaseline(font, lineHeight) {
|
|
946
|
+
if (typeof document === "undefined") return lineHeight * 0.8;
|
|
947
|
+
const key = `${font}\0${lineHeight}`;
|
|
948
|
+
const cached = baselineCache.get(key);
|
|
949
|
+
if (cached !== void 0) return cached;
|
|
950
|
+
if (typographyContext === void 0) {
|
|
951
|
+
typographyContext = document.createElement("canvas").getContext("2d");
|
|
952
|
+
}
|
|
953
|
+
if (!typographyContext) return lineHeight * 0.8;
|
|
954
|
+
typographyContext.font = font;
|
|
955
|
+
const metrics = typographyContext.measureText("Mg");
|
|
956
|
+
const ascent = metrics.fontBoundingBoxAscent || metrics.actualBoundingBoxAscent;
|
|
957
|
+
const descent = metrics.fontBoundingBoxDescent || metrics.actualBoundingBoxDescent;
|
|
958
|
+
if (!(ascent > 0) || !(descent >= 0)) return lineHeight * 0.8;
|
|
959
|
+
const baseline = (lineHeight - ascent - descent) / 2 + ascent;
|
|
960
|
+
baselineCache.set(key, baseline);
|
|
961
|
+
return baseline;
|
|
962
|
+
}
|
|
963
|
+
function clearCssLineBoxMetrics() {
|
|
964
|
+
baselineCache.clear();
|
|
965
|
+
}
|
|
966
|
+
|
|
942
967
|
// src/text/MSDFFont.ts
|
|
943
968
|
function kernKey(a, b) {
|
|
944
969
|
return a * 1114112 + b;
|
|
@@ -1445,4 +1470,6 @@ var SVGEntity = (_class7 = class extends Entity {
|
|
|
1445
1470
|
|
|
1446
1471
|
|
|
1447
1472
|
|
|
1448
|
-
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
exports.SpringPhysics = SpringPhysics; exports.Easing = Easing; exports.isTweenConfig = isTweenConfig; exports.TweenDriver = TweenDriver; exports.SpringDriver = SpringDriver; exports.VectoJSEvent = VectoJSEvent; exports.Entity = Entity; exports.cssLineBoxBaseline = cssLineBoxBaseline; exports.clearCssLineBoxMetrics = clearCssLineBoxMetrics; exports.MSDFFont = MSDFFont; exports.MSDFTextEntity = MSDFTextEntity; exports.SVGEntity = SVGEntity;
|
|
@@ -598,8 +598,11 @@ var LayoutEngine = class {
|
|
|
598
598
|
currentLineNodes.push({
|
|
599
599
|
char: glyph.char,
|
|
600
600
|
x: currentX,
|
|
601
|
-
//
|
|
602
|
-
|
|
601
|
+
// Canvas text is positioned by baseline, while `y` is the local
|
|
602
|
+
// top used by the renderer. Offset smaller runs by their baseline
|
|
603
|
+
// delta, not by their full em-box delta, so mixed-size glyphs share
|
|
604
|
+
// one real baseline in every Canvas 2D implementation.
|
|
605
|
+
y: currentY + (pMax - gfs) * 0.8,
|
|
603
606
|
width: charWidth,
|
|
604
607
|
height: gfs,
|
|
605
608
|
style: glyph.style,
|
|
@@ -598,8 +598,11 @@ var LayoutEngine = (_class = class {
|
|
|
598
598
|
currentLineNodes.push({
|
|
599
599
|
char: glyph.char,
|
|
600
600
|
x: currentX,
|
|
601
|
-
//
|
|
602
|
-
|
|
601
|
+
// Canvas text is positioned by baseline, while `y` is the local
|
|
602
|
+
// top used by the renderer. Offset smaller runs by their baseline
|
|
603
|
+
// delta, not by their full em-box delta, so mixed-size glyphs share
|
|
604
|
+
// one real baseline in every Canvas 2D implementation.
|
|
605
|
+
y: currentY + (pMax - gfs) * 0.8,
|
|
603
606
|
width: charWidth,
|
|
604
607
|
height: gfs,
|
|
605
608
|
style: glyph.style,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkZBKKRYDHjs = require('./chunk-ZBKKRYDH.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -24,7 +24,9 @@ var _chunkBPMNCGU7js = require('./chunk-BPMNCGU7.js');
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
var _chunkDFNK6OV6js = require('./chunk-DFNK6OV6.js');
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
|
|
@@ -41,7 +43,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
|
|
|
41
43
|
var PARTICLE_OFFSET_ORIGIN_Y = 5;
|
|
42
44
|
var PARTICLE_OFFSET_SIZE = 6;
|
|
43
45
|
var PARTICLE_OFFSET_LIFE = 7;
|
|
44
|
-
var ComputeParticleEntity = (_class = class extends
|
|
46
|
+
var ComputeParticleEntity = (_class = class extends _chunkDFNK6OV6js.Entity {
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
|
|
@@ -429,7 +431,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
429
431
|
this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
|
|
430
432
|
this.contentProjectionEnabled = _nullishCoalesce(options.contentProjection, () => ( true));
|
|
431
433
|
this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
432
|
-
this.root = new class RootEntity extends
|
|
434
|
+
this.root = new class RootEntity extends _chunkDFNK6OV6js.Entity {
|
|
433
435
|
isPointInside() {
|
|
434
436
|
return false;
|
|
435
437
|
}
|
|
@@ -438,7 +440,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
438
440
|
}
|
|
439
441
|
}("root");
|
|
440
442
|
this.root._scene = this;
|
|
441
|
-
this.overlayRoot = new class OverlayRoot extends
|
|
443
|
+
this.overlayRoot = new class OverlayRoot extends _chunkDFNK6OV6js.Entity {
|
|
442
444
|
isPointInside() {
|
|
443
445
|
return false;
|
|
444
446
|
}
|
|
@@ -505,6 +507,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
505
507
|
};
|
|
506
508
|
if (typeof document !== "undefined" && document.fonts) {
|
|
507
509
|
this.fontLoadHandler = () => {
|
|
510
|
+
_chunkDFNK6OV6js.clearCssLineBoxMetrics.call(void 0, );
|
|
508
511
|
this.markDirty();
|
|
509
512
|
};
|
|
510
513
|
document.fonts.ready.then(this.fontLoadHandler);
|
|
@@ -802,42 +805,42 @@ var Scene = (_class2 = class _Scene {
|
|
|
802
805
|
el.style.background = "transparent";
|
|
803
806
|
}
|
|
804
807
|
el.addEventListener("click", (e) => {
|
|
805
|
-
node.dispatchEvent(new (0,
|
|
808
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("click", node, e));
|
|
806
809
|
});
|
|
807
810
|
el.addEventListener("mouseenter", (e) => {
|
|
808
811
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
|
|
809
|
-
node.dispatchEvent(new (0,
|
|
812
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("hover", node, e, false));
|
|
810
813
|
});
|
|
811
814
|
el.addEventListener("mouseleave", (e) => {
|
|
812
815
|
if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
|
|
813
|
-
node.dispatchEvent(new (0,
|
|
816
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerleave", node, e, false));
|
|
814
817
|
});
|
|
815
818
|
const capEl = el;
|
|
816
819
|
el.addEventListener("pointerdown", (e) => {
|
|
817
820
|
if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
|
|
818
|
-
node.dispatchEvent(new (0,
|
|
821
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerdown", node, e));
|
|
819
822
|
});
|
|
820
823
|
el.addEventListener("pointerup", (e) => {
|
|
821
824
|
if (typeof capEl.releasePointerCapture === "function")
|
|
822
825
|
capEl.releasePointerCapture(e.pointerId);
|
|
823
|
-
node.dispatchEvent(new (0,
|
|
826
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerup", node, e));
|
|
824
827
|
});
|
|
825
828
|
el.addEventListener(
|
|
826
829
|
"pointermove",
|
|
827
|
-
(e) => node.dispatchEvent(new (0,
|
|
830
|
+
(e) => node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointermove", node, e))
|
|
828
831
|
);
|
|
829
832
|
el.addEventListener(
|
|
830
833
|
"wheel",
|
|
831
834
|
(e) => {
|
|
832
|
-
node.dispatchEvent(new (0,
|
|
835
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("wheel", node, e));
|
|
833
836
|
},
|
|
834
837
|
{ passive: false }
|
|
835
838
|
);
|
|
836
839
|
el.addEventListener("keydown", (e) => {
|
|
837
|
-
node.dispatchEvent(new (0,
|
|
840
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("keydown", node, e));
|
|
838
841
|
});
|
|
839
842
|
el.addEventListener("keyup", (e) => {
|
|
840
|
-
node.dispatchEvent(new (0,
|
|
843
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("keyup", node, e));
|
|
841
844
|
});
|
|
842
845
|
if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
|
|
843
846
|
const input = el;
|
|
@@ -910,7 +913,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
910
913
|
el.addEventListener("keydown", (e) => {
|
|
911
914
|
if (e.key === "Enter" || e.key === " ") {
|
|
912
915
|
e.preventDefault();
|
|
913
|
-
node.dispatchEvent(new (0,
|
|
916
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("click", node, e));
|
|
914
917
|
}
|
|
915
918
|
});
|
|
916
919
|
}
|
|
@@ -993,6 +996,16 @@ var Scene = (_class2 = class _Scene {
|
|
|
993
996
|
el.setAttribute("aria-valuenow", attrs.value);
|
|
994
997
|
}
|
|
995
998
|
}
|
|
999
|
+
if (attrs.textInputStyle !== void 0 && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
|
|
1000
|
+
const textStyle = attrs.textInputStyle;
|
|
1001
|
+
if (el.style.font !== textStyle.font) el.style.font = textStyle.font;
|
|
1002
|
+
const lineHeight = `${textStyle.lineHeight}px`;
|
|
1003
|
+
if (el.style.lineHeight !== lineHeight) el.style.lineHeight = lineHeight;
|
|
1004
|
+
const padding = `${textStyle.padding}px`;
|
|
1005
|
+
if (el.style.padding !== padding) el.style.padding = padding;
|
|
1006
|
+
if (el.style.boxSizing !== "border-box") el.style.boxSizing = "border-box";
|
|
1007
|
+
if (el instanceof HTMLTextAreaElement) el.style.resize = "none";
|
|
1008
|
+
}
|
|
996
1009
|
if (node.a11yFullViewport) {
|
|
997
1010
|
el.style.left = "0px";
|
|
998
1011
|
el.style.top = "0px";
|
|
@@ -1048,7 +1061,7 @@ var Scene = (_class2 = class _Scene {
|
|
|
1048
1061
|
el.addEventListener(
|
|
1049
1062
|
"wheel",
|
|
1050
1063
|
(e2) => {
|
|
1051
|
-
node.dispatchEvent(new (0,
|
|
1064
|
+
node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("wheel", node, e2));
|
|
1052
1065
|
},
|
|
1053
1066
|
{ passive: false }
|
|
1054
1067
|
);
|
|
@@ -1056,7 +1069,46 @@ var Scene = (_class2 = class _Scene {
|
|
|
1056
1069
|
this.contentElements.set(node.id, el);
|
|
1057
1070
|
this.a11yNeedsReorder = true;
|
|
1058
1071
|
}
|
|
1059
|
-
|
|
1072
|
+
const lines = projection.lines;
|
|
1073
|
+
if (lines && lines.length > 0) {
|
|
1074
|
+
const signature = JSON.stringify({
|
|
1075
|
+
lines,
|
|
1076
|
+
fallbackFont: _nullishCoalesce(projection.font, () => ( "")),
|
|
1077
|
+
fallbackLineHeight: _nullishCoalesce(projection.lineHeight, () => ( 16))
|
|
1078
|
+
});
|
|
1079
|
+
if (el.dataset.vectoProjectionLines !== signature) {
|
|
1080
|
+
el.replaceChildren();
|
|
1081
|
+
for (let index = 0; index < lines.length; index++) {
|
|
1082
|
+
const line = lines[index];
|
|
1083
|
+
const lineElement = document.createElement("span");
|
|
1084
|
+
const lineFont = _nullishCoalesce(_nullishCoalesce(line.font, () => ( projection.font)), () => ( ""));
|
|
1085
|
+
const lineHeight2 = _nullishCoalesce(_nullishCoalesce(line.lineHeight, () => ( projection.lineHeight)), () => ( 16));
|
|
1086
|
+
lineElement.style.position = "absolute";
|
|
1087
|
+
lineElement.style.left = `${line.x}px`;
|
|
1088
|
+
lineElement.style.top = `${line.y + line.baseline - _chunkDFNK6OV6js.cssLineBoxBaseline.call(void 0, lineFont, lineHeight2)}px`;
|
|
1089
|
+
lineElement.style.whiteSpace = "pre";
|
|
1090
|
+
if (lineFont) lineElement.style.font = lineFont;
|
|
1091
|
+
lineElement.style.lineHeight = `${lineHeight2}px`;
|
|
1092
|
+
if (line.runs && line.runs.length > 0) {
|
|
1093
|
+
for (const run of line.runs) {
|
|
1094
|
+
const runElement = document.createElement("span");
|
|
1095
|
+
runElement.textContent = run.text;
|
|
1096
|
+
if (run.font) runElement.style.font = run.font;
|
|
1097
|
+
runElement.style.lineHeight = `${lineHeight2}px`;
|
|
1098
|
+
lineElement.appendChild(runElement);
|
|
1099
|
+
}
|
|
1100
|
+
} else {
|
|
1101
|
+
lineElement.textContent = line.text;
|
|
1102
|
+
}
|
|
1103
|
+
el.appendChild(lineElement);
|
|
1104
|
+
if (index < lines.length - 1) el.appendChild(document.createTextNode("\n"));
|
|
1105
|
+
}
|
|
1106
|
+
el.dataset.vectoProjectionLines = signature;
|
|
1107
|
+
}
|
|
1108
|
+
} else {
|
|
1109
|
+
if (el.textContent !== projection.text) el.textContent = projection.text;
|
|
1110
|
+
delete el.dataset.vectoProjectionLines;
|
|
1111
|
+
}
|
|
1060
1112
|
const font = _nullishCoalesce(projection.font, () => ( ""));
|
|
1061
1113
|
if (el.style.font !== font) el.style.font = font;
|
|
1062
1114
|
const lineHeight = projection.lineHeight !== void 0 ? `${projection.lineHeight}px` : "";
|
|
@@ -1074,8 +1126,12 @@ var Scene = (_class2 = class _Scene {
|
|
|
1074
1126
|
el.style.cursor = selectable ? "text" : "";
|
|
1075
1127
|
}
|
|
1076
1128
|
const { a, b, c, d, e, f } = node.getWorldTransform();
|
|
1077
|
-
|
|
1078
|
-
|
|
1129
|
+
const contentX = _nullishCoalesce(projection.contentX, () => ( 0));
|
|
1130
|
+
const contentY = _nullishCoalesce(projection.contentY, () => ( 0));
|
|
1131
|
+
const baselineOffset = lines && lines.length > 0 ? 0 : projection.baseline === void 0 ? 0 : projection.baseline - _chunkDFNK6OV6js.cssLineBoxBaseline.call(void 0, font, _nullishCoalesce(projection.lineHeight, () => ( 16)));
|
|
1132
|
+
const localY = contentY + baselineOffset;
|
|
1133
|
+
el.style.left = `${e + a * contentX + c * localY}px`;
|
|
1134
|
+
el.style.top = `${f + b * contentX + d * localY}px`;
|
|
1079
1135
|
if (node.width > 0) el.style.width = `${node.width}px`;
|
|
1080
1136
|
if (node.height > 0) el.style.height = `${node.height}px`;
|
|
1081
1137
|
el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
|
|
@@ -1833,10 +1889,10 @@ var Scene = (_class2 = class _Scene {
|
|
|
1833
1889
|
// src/components/TextEntity.ts
|
|
1834
1890
|
var sharedMeasurer;
|
|
1835
1891
|
function defaultMeasurer() {
|
|
1836
|
-
if (sharedMeasurer === void 0) sharedMeasurer =
|
|
1892
|
+
if (sharedMeasurer === void 0) sharedMeasurer = _chunkZBKKRYDHjs.createCanvasMeasurer.call(void 0, "sans-serif");
|
|
1837
1893
|
return sharedMeasurer;
|
|
1838
1894
|
}
|
|
1839
|
-
var TextEntity = (_class3 = class extends
|
|
1895
|
+
var TextEntity = (_class3 = class extends _chunkDFNK6OV6js.Entity {
|
|
1840
1896
|
|
|
1841
1897
|
|
|
1842
1898
|
|
|
@@ -1853,7 +1909,7 @@ var TextEntity = (_class3 = class extends _chunkNHNOKBD4js.Entity {
|
|
|
1853
1909
|
this.text = text;
|
|
1854
1910
|
this.atlas = atlas;
|
|
1855
1911
|
this.fontSize = fontSize;
|
|
1856
|
-
this.layout = new (0,
|
|
1912
|
+
this.layout = new (0, _chunkZBKKRYDHjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
|
|
1857
1913
|
this.prepared = this.layout.prepare(this.text, this.atlas, this.fontSize);
|
|
1858
1914
|
this.applyLayout();
|
|
1859
1915
|
this.interactive = true;
|
|
@@ -1962,7 +2018,7 @@ var TextEntity = (_class3 = class extends _chunkNHNOKBD4js.Entity {
|
|
|
1962
2018
|
}, _class3);
|
|
1963
2019
|
|
|
1964
2020
|
// src/components/GridTextEntity.ts
|
|
1965
|
-
var GridTextEntity = (_class4 = class extends
|
|
2021
|
+
var GridTextEntity = (_class4 = class extends _chunkDFNK6OV6js.Entity {
|
|
1966
2022
|
|
|
1967
2023
|
__init60() {this.fillStyle = "#ffffff"}
|
|
1968
2024
|
__init61() {this.grid = []}
|
|
@@ -2056,7 +2112,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
|
|
|
2056
2112
|
const ey = py - cy;
|
|
2057
2113
|
return ex * ex + ey * ey;
|
|
2058
2114
|
}
|
|
2059
|
-
var SplineEntity = (_class5 = class extends
|
|
2115
|
+
var SplineEntity = (_class5 = class extends _chunkDFNK6OV6js.Entity {
|
|
2060
2116
|
|
|
2061
2117
|
|
|
2062
2118
|
|
|
@@ -2425,7 +2481,7 @@ var SpatialHashGrid = (_class6 = class {
|
|
|
2425
2481
|
}, _class6);
|
|
2426
2482
|
|
|
2427
2483
|
// src/tree/DOMPortalEntity.ts
|
|
2428
|
-
var DOMPortalEntity = (_class7 = class extends
|
|
2484
|
+
var DOMPortalEntity = (_class7 = class extends _chunkDFNK6OV6js.Entity {
|
|
2429
2485
|
|
|
2430
2486
|
__init72() {this.isDOMPortal = true}
|
|
2431
2487
|
__init73() {this.domListeners = []}
|
|
@@ -2460,7 +2516,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkNHNOKBD4js.Entity {
|
|
|
2460
2516
|
const events = ["click", "pointerdown", "pointerup", "pointermove", "wheel"];
|
|
2461
2517
|
for (const type of events) {
|
|
2462
2518
|
const handler = (e) => {
|
|
2463
|
-
this.dispatchEvent(new (0,
|
|
2519
|
+
this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(type, this, e));
|
|
2464
2520
|
};
|
|
2465
2521
|
this.domElement.addEventListener(type, handler);
|
|
2466
2522
|
this.domListeners.push({ type, handler, capture: false });
|
|
@@ -2471,7 +2527,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkNHNOKBD4js.Entity {
|
|
|
2471
2527
|
];
|
|
2472
2528
|
for (const { native, vecto } of hoverEvents) {
|
|
2473
2529
|
const handler = (e) => {
|
|
2474
|
-
this.dispatchEvent(new (0,
|
|
2530
|
+
this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(vecto, this, e, false));
|
|
2475
2531
|
};
|
|
2476
2532
|
this.domElement.addEventListener(native, handler);
|
|
2477
2533
|
this.domListeners.push({ type: native, handler, capture: false });
|
|
@@ -2479,7 +2535,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkNHNOKBD4js.Entity {
|
|
|
2479
2535
|
const focusEvents = ["focus", "blur"];
|
|
2480
2536
|
for (const type of focusEvents) {
|
|
2481
2537
|
const handler = (e) => {
|
|
2482
|
-
this.dispatchEvent(new (0,
|
|
2538
|
+
this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(type, this, e, true));
|
|
2483
2539
|
};
|
|
2484
2540
|
this.domElement.addEventListener(type, handler, true);
|
|
2485
2541
|
this.domListeners.push({ type, handler, capture: true });
|
|
@@ -2564,4 +2620,6 @@ Scene.registerWebGPUParticleSystemManager(_chunkBPMNCGU7js.WebGPUParticleSystemM
|
|
|
2564
2620
|
|
|
2565
2621
|
|
|
2566
2622
|
|
|
2567
|
-
|
|
2623
|
+
|
|
2624
|
+
|
|
2625
|
+
exports.ArabicShaper = _chunkCTZQOM5Zjs.ArabicShaper; exports.BidiResolver = _chunkCTZQOM5Zjs.BidiResolver; exports.CanvasRenderer = _chunkBPMNCGU7js.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkDFNK6OV6js.Easing; exports.Entity = _chunkDFNK6OV6js.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunkZBKKRYDHjs.LayoutEngine; exports.LayoutResultBuffer = _chunkZBKKRYDHjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunkCTZQOM5Zjs.LayoutWorkerManager; exports.MSDFFont = _chunkDFNK6OV6js.MSDFFont; exports.MSDFTextEntity = _chunkDFNK6OV6js.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.SVGEntity = _chunkDFNK6OV6js.SVGEntity; exports.SVGRenderer = _chunkBPMNCGU7js.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkDFNK6OV6js.SpringDriver; exports.SpringPhysics = _chunkDFNK6OV6js.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkDFNK6OV6js.TweenDriver; exports.VectoJSEvent = _chunkDFNK6OV6js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkBPMNCGU7js.WebGPUParticleSystemManager; exports.clearCssLineBoxMetrics = _chunkDFNK6OV6js.clearCssLineBoxMetrics; exports.computeLineSegments = _chunkZBKKRYDHjs.computeLineSegments; exports.createCanvasMeasurer = _chunkZBKKRYDHjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkBPMNCGU7js.createWebGLPointRenderer; exports.cssLineBoxBaseline = _chunkDFNK6OV6js.cssLineBoxBaseline; exports.isSafeUrl = _chunkBPMNCGU7js.isSafeUrl; exports.isTweenConfig = _chunkDFNK6OV6js.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkBPMNCGU7js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkBPMNCGU7js.sanitizeUrl;
|
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-V7GUWG5C.mjs";
|
|
7
7
|
import {
|
|
8
8
|
CanvasRenderer,
|
|
9
9
|
SVGRenderer,
|
|
@@ -23,8 +23,10 @@ import {
|
|
|
23
23
|
SpringPhysics,
|
|
24
24
|
TweenDriver,
|
|
25
25
|
VectoJSEvent,
|
|
26
|
+
clearCssLineBoxMetrics,
|
|
27
|
+
cssLineBoxBaseline,
|
|
26
28
|
isTweenConfig
|
|
27
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-3CODWSF3.mjs";
|
|
28
30
|
import {
|
|
29
31
|
ArabicShaper,
|
|
30
32
|
BidiResolver,
|
|
@@ -505,6 +507,7 @@ var Scene = class _Scene {
|
|
|
505
507
|
};
|
|
506
508
|
if (typeof document !== "undefined" && document.fonts) {
|
|
507
509
|
this.fontLoadHandler = () => {
|
|
510
|
+
clearCssLineBoxMetrics();
|
|
508
511
|
this.markDirty();
|
|
509
512
|
};
|
|
510
513
|
document.fonts.ready.then(this.fontLoadHandler);
|
|
@@ -993,6 +996,16 @@ var Scene = class _Scene {
|
|
|
993
996
|
el.setAttribute("aria-valuenow", attrs.value);
|
|
994
997
|
}
|
|
995
998
|
}
|
|
999
|
+
if (attrs.textInputStyle !== void 0 && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
|
|
1000
|
+
const textStyle = attrs.textInputStyle;
|
|
1001
|
+
if (el.style.font !== textStyle.font) el.style.font = textStyle.font;
|
|
1002
|
+
const lineHeight = `${textStyle.lineHeight}px`;
|
|
1003
|
+
if (el.style.lineHeight !== lineHeight) el.style.lineHeight = lineHeight;
|
|
1004
|
+
const padding = `${textStyle.padding}px`;
|
|
1005
|
+
if (el.style.padding !== padding) el.style.padding = padding;
|
|
1006
|
+
if (el.style.boxSizing !== "border-box") el.style.boxSizing = "border-box";
|
|
1007
|
+
if (el instanceof HTMLTextAreaElement) el.style.resize = "none";
|
|
1008
|
+
}
|
|
996
1009
|
if (node.a11yFullViewport) {
|
|
997
1010
|
el.style.left = "0px";
|
|
998
1011
|
el.style.top = "0px";
|
|
@@ -1056,7 +1069,46 @@ var Scene = class _Scene {
|
|
|
1056
1069
|
this.contentElements.set(node.id, el);
|
|
1057
1070
|
this.a11yNeedsReorder = true;
|
|
1058
1071
|
}
|
|
1059
|
-
|
|
1072
|
+
const lines = projection.lines;
|
|
1073
|
+
if (lines && lines.length > 0) {
|
|
1074
|
+
const signature = JSON.stringify({
|
|
1075
|
+
lines,
|
|
1076
|
+
fallbackFont: projection.font ?? "",
|
|
1077
|
+
fallbackLineHeight: projection.lineHeight ?? 16
|
|
1078
|
+
});
|
|
1079
|
+
if (el.dataset.vectoProjectionLines !== signature) {
|
|
1080
|
+
el.replaceChildren();
|
|
1081
|
+
for (let index = 0; index < lines.length; index++) {
|
|
1082
|
+
const line = lines[index];
|
|
1083
|
+
const lineElement = document.createElement("span");
|
|
1084
|
+
const lineFont = line.font ?? projection.font ?? "";
|
|
1085
|
+
const lineHeight2 = line.lineHeight ?? projection.lineHeight ?? 16;
|
|
1086
|
+
lineElement.style.position = "absolute";
|
|
1087
|
+
lineElement.style.left = `${line.x}px`;
|
|
1088
|
+
lineElement.style.top = `${line.y + line.baseline - cssLineBoxBaseline(lineFont, lineHeight2)}px`;
|
|
1089
|
+
lineElement.style.whiteSpace = "pre";
|
|
1090
|
+
if (lineFont) lineElement.style.font = lineFont;
|
|
1091
|
+
lineElement.style.lineHeight = `${lineHeight2}px`;
|
|
1092
|
+
if (line.runs && line.runs.length > 0) {
|
|
1093
|
+
for (const run of line.runs) {
|
|
1094
|
+
const runElement = document.createElement("span");
|
|
1095
|
+
runElement.textContent = run.text;
|
|
1096
|
+
if (run.font) runElement.style.font = run.font;
|
|
1097
|
+
runElement.style.lineHeight = `${lineHeight2}px`;
|
|
1098
|
+
lineElement.appendChild(runElement);
|
|
1099
|
+
}
|
|
1100
|
+
} else {
|
|
1101
|
+
lineElement.textContent = line.text;
|
|
1102
|
+
}
|
|
1103
|
+
el.appendChild(lineElement);
|
|
1104
|
+
if (index < lines.length - 1) el.appendChild(document.createTextNode("\n"));
|
|
1105
|
+
}
|
|
1106
|
+
el.dataset.vectoProjectionLines = signature;
|
|
1107
|
+
}
|
|
1108
|
+
} else {
|
|
1109
|
+
if (el.textContent !== projection.text) el.textContent = projection.text;
|
|
1110
|
+
delete el.dataset.vectoProjectionLines;
|
|
1111
|
+
}
|
|
1060
1112
|
const font = projection.font ?? "";
|
|
1061
1113
|
if (el.style.font !== font) el.style.font = font;
|
|
1062
1114
|
const lineHeight = projection.lineHeight !== void 0 ? `${projection.lineHeight}px` : "";
|
|
@@ -1074,8 +1126,12 @@ var Scene = class _Scene {
|
|
|
1074
1126
|
el.style.cursor = selectable ? "text" : "";
|
|
1075
1127
|
}
|
|
1076
1128
|
const { a, b, c, d, e, f } = node.getWorldTransform();
|
|
1077
|
-
|
|
1078
|
-
|
|
1129
|
+
const contentX = projection.contentX ?? 0;
|
|
1130
|
+
const contentY = projection.contentY ?? 0;
|
|
1131
|
+
const baselineOffset = lines && lines.length > 0 ? 0 : projection.baseline === void 0 ? 0 : projection.baseline - cssLineBoxBaseline(font, projection.lineHeight ?? 16);
|
|
1132
|
+
const localY = contentY + baselineOffset;
|
|
1133
|
+
el.style.left = `${e + a * contentX + c * localY}px`;
|
|
1134
|
+
el.style.top = `${f + b * contentX + d * localY}px`;
|
|
1079
1135
|
if (node.width > 0) el.style.width = `${node.width}px`;
|
|
1080
1136
|
if (node.height > 0) el.style.height = `${node.height}px`;
|
|
1081
1137
|
el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
|
|
@@ -2555,9 +2611,11 @@ export {
|
|
|
2555
2611
|
TweenDriver,
|
|
2556
2612
|
VectoJSEvent,
|
|
2557
2613
|
WebGPUParticleSystemManager,
|
|
2614
|
+
clearCssLineBoxMetrics,
|
|
2558
2615
|
computeLineSegments,
|
|
2559
2616
|
createCanvasMeasurer,
|
|
2560
2617
|
createWebGLPointRenderer,
|
|
2618
|
+
cssLineBoxBaseline,
|
|
2561
2619
|
isSafeUrl,
|
|
2562
2620
|
isTweenConfig,
|
|
2563
2621
|
loadSpline,
|
package/dist/layout.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkZBKKRYDHjs = require('./chunk-ZBKKRYDH.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 = _chunkZBKKRYDHjs.LayoutEngine; exports.LayoutResultBuffer = _chunkZBKKRYDHjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunkCTZQOM5Zjs.LayoutWorkerManager; exports.computeLineSegments = _chunkZBKKRYDHjs.computeLineSegments; exports.createCanvasMeasurer = _chunkZBKKRYDHjs.createCanvasMeasurer;
|
package/dist/layout.mjs
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return the baseline offset inside a CSS line box for a canvas-compatible
|
|
3
|
+
* font. Canvas text and a native editor must use this identical value whenever
|
|
4
|
+
* one mirrors the other; CSS otherwise centers font metrics in the line box.
|
|
5
|
+
*
|
|
6
|
+
* The 0.8 fallback preserves the framework's deterministic, DOM-free text
|
|
7
|
+
* contract in SSR and test environments where Canvas 2D is unavailable.
|
|
8
|
+
*/
|
|
9
|
+
export declare function cssLineBoxBaseline(font: string, lineHeight: number): number;
|
|
10
|
+
/** Clear cached browser font metrics after a webfont finishes loading. */
|
|
11
|
+
export declare function clearCssLineBoxMetrics(): void;
|
package/dist/text/index.d.ts
CHANGED
package/dist/text.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkDFNK6OV6js = require('./chunk-DFNK6OV6.js');
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
|
|
@@ -13,4 +15,6 @@ var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
|
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
exports.ArabicShaper = _chunkCTZQOM5Zjs.ArabicShaper; exports.BidiResolver = _chunkCTZQOM5Zjs.BidiResolver; exports.MSDFFont = _chunkDFNK6OV6js.MSDFFont; exports.MSDFTextEntity = _chunkDFNK6OV6js.MSDFTextEntity; exports.SVGEntity = _chunkDFNK6OV6js.SVGEntity; exports.clearCssLineBoxMetrics = _chunkDFNK6OV6js.clearCssLineBoxMetrics; exports.cssLineBoxBaseline = _chunkDFNK6OV6js.cssLineBoxBaseline;
|
package/dist/text.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MSDFFont,
|
|
3
3
|
MSDFTextEntity,
|
|
4
|
-
SVGEntity
|
|
5
|
-
|
|
4
|
+
SVGEntity,
|
|
5
|
+
clearCssLineBoxMetrics,
|
|
6
|
+
cssLineBoxBaseline
|
|
7
|
+
} from "./chunk-3CODWSF3.mjs";
|
|
6
8
|
import {
|
|
7
9
|
ArabicShaper,
|
|
8
10
|
BidiResolver
|
|
@@ -12,5 +14,7 @@ export {
|
|
|
12
14
|
BidiResolver,
|
|
13
15
|
MSDFFont,
|
|
14
16
|
MSDFTextEntity,
|
|
15
|
-
SVGEntity
|
|
17
|
+
SVGEntity,
|
|
18
|
+
clearCssLineBoxMetrics,
|
|
19
|
+
cssLineBoxBaseline
|
|
16
20
|
};
|
package/dist/tree/Entity.d.ts
CHANGED
|
@@ -59,6 +59,27 @@ export interface BatchRect {
|
|
|
59
59
|
* find-in-page, screen readers, SEO crawlers, translation, `#:~:text=`
|
|
60
60
|
* fragments — operates on canvas-rendered text.
|
|
61
61
|
*/
|
|
62
|
+
export interface ContentProjectionRun {
|
|
63
|
+
/** Text written with one CSS font inside a projected visual line. */
|
|
64
|
+
text: string;
|
|
65
|
+
/** CSS font shorthand matching the canvas run. */
|
|
66
|
+
font?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface ContentProjectionLine {
|
|
69
|
+
/** Text for browser find-in-page and native selection. */
|
|
70
|
+
text: string;
|
|
71
|
+
/** Local origin of the visual line inside the entity. */
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
/** Canvas baseline relative to `y`. */
|
|
75
|
+
baseline: number;
|
|
76
|
+
/** CSS font used for the line when it has no styled runs. */
|
|
77
|
+
font?: string;
|
|
78
|
+
/** Explicit line height for this line. */
|
|
79
|
+
lineHeight?: number;
|
|
80
|
+
/** Styled text runs in visual order. */
|
|
81
|
+
runs?: ContentProjectionRun[];
|
|
82
|
+
}
|
|
62
83
|
export interface ContentProjection {
|
|
63
84
|
/** The plain text content as rendered (line breaks as `\n`). */
|
|
64
85
|
text: string;
|
|
@@ -71,6 +92,27 @@ export interface ContentProjection {
|
|
|
71
92
|
* projection never intercepts pointer input meant for the canvas.
|
|
72
93
|
*/
|
|
73
94
|
selectable?: boolean;
|
|
95
|
+
/** Local x-origin of the rendered text inside the owning entity. */
|
|
96
|
+
contentX?: number;
|
|
97
|
+
/** Local y-origin of the rendered text inside the owning entity. */
|
|
98
|
+
contentY?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Canvas baseline relative to `contentY` for the first line. When supplied,
|
|
101
|
+
* Scene aligns the DOM line box baseline instead of assuming both engines
|
|
102
|
+
* interpret the entity top as a text baseline.
|
|
103
|
+
*/
|
|
104
|
+
baseline?: number;
|
|
105
|
+
/** Explicit visual lines for mixed-style or internally inset text. */
|
|
106
|
+
lines?: ContentProjectionLine[];
|
|
107
|
+
}
|
|
108
|
+
/** Typography for a native input projected by the accessibility layer. */
|
|
109
|
+
export interface TextInputStyle {
|
|
110
|
+
/** CSS font shorthand shared with the canvas mirror. */
|
|
111
|
+
font: string;
|
|
112
|
+
/** Explicit line advance in CSS pixels. */
|
|
113
|
+
lineHeight: number;
|
|
114
|
+
/** Inner text inset in CSS pixels. */
|
|
115
|
+
padding: number;
|
|
74
116
|
}
|
|
75
117
|
/**
|
|
76
118
|
* Semantic attributes an {@link Entity} can project into the accessibility /
|
|
@@ -114,6 +156,8 @@ export interface A11yAttributes {
|
|
|
114
156
|
activedescendant?: string;
|
|
115
157
|
valuemin?: string;
|
|
116
158
|
valuemax?: string;
|
|
159
|
+
/** Explicit native editor typography; ignored for non-input elements. */
|
|
160
|
+
textInputStyle?: TextInputStyle;
|
|
117
161
|
}
|
|
118
162
|
/**
|
|
119
163
|
* Union of all pointer/interaction events that can be emitted by an {@link Entity}.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vectojs/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "node scripts/build-worker.js && tsup && tsc -p tsconfig.build.json",
|
|
56
56
|
"test": "vitest run",
|
|
57
|
-
"test:e2e": "bun e2e/hidpi.e2e.ts"
|
|
57
|
+
"test:e2e": "bun e2e/hidpi.e2e.ts && bun e2e/text-projection.e2e.ts"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {},
|
|
60
60
|
"devDependencies": {
|