@broberg/bodymap 0.7.0 → 0.8.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/README.md +53 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +15 -1
- package/dist/react.d.ts +15 -1
- package/dist/react.js.map +1 -1
- package/dist/three.cjs +52 -9
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +50 -2
- package/dist/three.d.ts +50 -2
- package/dist/three.js +51 -10
- package/dist/three.js.map +1 -1
- package/package.json +1 -1
package/dist/three.cjs
CHANGED
|
@@ -103,10 +103,12 @@ function emitFeedback(outcome, region, opts = {}) {
|
|
|
103
103
|
if (opts.haptics === false) return "skipped";
|
|
104
104
|
return requestVibration(VIBRATION_PATTERNS[outcome], opts.nav);
|
|
105
105
|
}
|
|
106
|
+
var STAGE_BG = "#0e1424";
|
|
106
107
|
var defaultUi = {
|
|
107
108
|
text: "#1e293b",
|
|
108
109
|
mutedText: "#475569",
|
|
109
110
|
panelBg: "#fff",
|
|
111
|
+
stageBg: STAGE_BG,
|
|
110
112
|
border: "#e2e8f0",
|
|
111
113
|
badgeBg: "#f1f5f9",
|
|
112
114
|
danger: "#dc2626"
|
|
@@ -268,6 +270,14 @@ function seamBlend(nearestSq, secondSq) {
|
|
|
268
270
|
if (t >= 1) return 0.5;
|
|
269
271
|
return t * t * (3 - 2 * t) * 0.5;
|
|
270
272
|
}
|
|
273
|
+
function seamWeight(seamEnabled, blend) {
|
|
274
|
+
return seamEnabled ? blend : 0;
|
|
275
|
+
}
|
|
276
|
+
function ensureNormals(geo) {
|
|
277
|
+
if (geo.getAttribute("normal")) return false;
|
|
278
|
+
geo.computeVertexNormals();
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
271
281
|
var ANCHOR_KEYS = Object.keys(ANCHORS);
|
|
272
282
|
for (const k of ANCHOR_KEYS) ANCHORS[k][0] = -ANCHORS[k][0];
|
|
273
283
|
function mergeLabels(locale, overrides) {
|
|
@@ -353,6 +363,8 @@ function BodyMap3D(props) {
|
|
|
353
363
|
setReadyRef.current = setReady;
|
|
354
364
|
const seamRef = react.useRef(seam);
|
|
355
365
|
seamRef.current = seam;
|
|
366
|
+
const stageRef = react.useRef(chrome.stageBg);
|
|
367
|
+
stageRef.current = chrome.stageBg;
|
|
356
368
|
const [internalFs, setInternalFs] = react.useState(false);
|
|
357
369
|
const isFullscreen = fullscreenProp ?? internalFs;
|
|
358
370
|
const setFullscreen = (v) => {
|
|
@@ -369,7 +381,7 @@ function BodyMap3D(props) {
|
|
|
369
381
|
if (!el) return;
|
|
370
382
|
let W = el.clientWidth || 520, H = el.clientHeight || 600;
|
|
371
383
|
const scene = new THREE__namespace.Scene();
|
|
372
|
-
scene.background = new THREE__namespace.Color(
|
|
384
|
+
scene.background = new THREE__namespace.Color(stageRef.current);
|
|
373
385
|
const camera = new THREE__namespace.PerspectiveCamera(32, W / H, 0.1, 100);
|
|
374
386
|
camera.position.set(0, 1.05, 4.4);
|
|
375
387
|
let renderer;
|
|
@@ -452,7 +464,7 @@ function BodyMap3D(props) {
|
|
|
452
464
|
};
|
|
453
465
|
for (let i = 0; i < vertexRegion.length; i++) {
|
|
454
466
|
tmp.copy(col(vertexRegion[i]));
|
|
455
|
-
const w = seamRef.current
|
|
467
|
+
const w = seamWeight(seamRef.current, vertexBlend[i]);
|
|
456
468
|
if (w > 0) {
|
|
457
469
|
tmp2.copy(col(vertexNeighbour[i]));
|
|
458
470
|
tmp.lerp(tmp2, w);
|
|
@@ -462,6 +474,7 @@ function BodyMap3D(props) {
|
|
|
462
474
|
colorAttr.needsUpdate = true;
|
|
463
475
|
};
|
|
464
476
|
const refresh = () => {
|
|
477
|
+
scene.background = new THREE__namespace.Color(stageRef.current);
|
|
465
478
|
paint();
|
|
466
479
|
renderFrame();
|
|
467
480
|
};
|
|
@@ -486,7 +499,7 @@ function BodyMap3D(props) {
|
|
|
486
499
|
});
|
|
487
500
|
if (bodyMesh) {
|
|
488
501
|
const geo = bodyMesh.geometry;
|
|
489
|
-
|
|
502
|
+
ensureNormals(geo);
|
|
490
503
|
const pos = geo.getAttribute("position");
|
|
491
504
|
const n = pos.count;
|
|
492
505
|
const cols = new Float32Array(n * 3);
|
|
@@ -684,8 +697,23 @@ function BodyMap3D(props) {
|
|
|
684
697
|
position: "fixed",
|
|
685
698
|
inset: 0,
|
|
686
699
|
zIndex: 2147483e3,
|
|
687
|
-
|
|
688
|
-
|
|
700
|
+
// THE STAGE, not the panel. This used to be `chrome.panelBg`,
|
|
701
|
+
// the same field that paints the picker card — so a consumer with
|
|
702
|
+
// a dark canvas got a white void around a dark body in fullscreen,
|
|
703
|
+
// and could not fix it: darkening panelBg hid the 0-10 buttons.
|
|
704
|
+
// One field, two surfaces, opposite needs. (F052.29)
|
|
705
|
+
background: chrome.stageBg,
|
|
706
|
+
// F052.27 — a fixed inset:0 surface in a standalone/Capacitor
|
|
707
|
+
// webview covers the STATUS BAR too, so a control laid out at the
|
|
708
|
+
// top lands on the clock and the battery. Measured by fd-sundhed
|
|
709
|
+
// on a real iPhone: the owner could not read the button or get
|
|
710
|
+
// out, and Escape does not exist on a phone. Every side gets its
|
|
711
|
+
// safe-area inset, bottom included — the home indicator covers
|
|
712
|
+
// content just as effectively.
|
|
713
|
+
paddingTop: "calc(12px + env(safe-area-inset-top))",
|
|
714
|
+
paddingBottom: "calc(12px + env(safe-area-inset-bottom))",
|
|
715
|
+
paddingLeft: "calc(12px + env(safe-area-inset-left))",
|
|
716
|
+
paddingRight: "calc(12px + env(safe-area-inset-right))",
|
|
689
717
|
display: "flex",
|
|
690
718
|
flexDirection: "column",
|
|
691
719
|
overflow: "auto"
|
|
@@ -706,12 +734,25 @@ function BodyMap3D(props) {
|
|
|
706
734
|
"aria-pressed": isFullscreen,
|
|
707
735
|
"aria-label": isFullscreen ? UI.collapse ?? "Close" : UI.expand ?? "Expand",
|
|
708
736
|
onClick: () => setFullscreen(!isFullscreen),
|
|
709
|
-
style: {
|
|
710
|
-
|
|
737
|
+
style: {
|
|
738
|
+
...btn,
|
|
739
|
+
color: chrome.text,
|
|
740
|
+
borderColor: chrome.border,
|
|
741
|
+
background: chrome.panelBg,
|
|
742
|
+
...isFullscreen ? { width: 40, height: 40, padding: 0, fontSize: 22, lineHeight: 1 } : null
|
|
743
|
+
},
|
|
744
|
+
children: isFullscreen ? "\xD7" : UI.expand ?? "Expand"
|
|
711
745
|
}
|
|
712
746
|
) }),
|
|
713
747
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 18, alignItems: "flex-start", flexWrap: "wrap", ...isFullscreen ? { flex: "1 1 auto", minHeight: 0 } : null }, children: [
|
|
714
|
-
unsupported ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
748
|
+
unsupported ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
749
|
+
"div",
|
|
750
|
+
{
|
|
751
|
+
"data-testid": "bodymap3d-unsupported",
|
|
752
|
+
style: { flex: "1 1 520px", minWidth: 320, height: canvasH, borderRadius: 16, background: chrome.panelBg, color: chrome.mutedText, border: `1px solid ${chrome.border}`, display: "flex", alignItems: "center", justifyContent: "center", padding: 24, textAlign: "center", fontSize: 14 },
|
|
753
|
+
children: "3D kr\xE6ver WebGL, som ikke er tilg\xE6ngeligt her."
|
|
754
|
+
}
|
|
755
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
715
756
|
"div",
|
|
716
757
|
{
|
|
717
758
|
ref: mountRef,
|
|
@@ -726,7 +767,7 @@ function BodyMap3D(props) {
|
|
|
726
767
|
minHeight: isFullscreen ? 0 : void 0,
|
|
727
768
|
borderRadius: 16,
|
|
728
769
|
overflow: "hidden",
|
|
729
|
-
background:
|
|
770
|
+
background: chrome.stageBg,
|
|
730
771
|
touchAction: "none"
|
|
731
772
|
}
|
|
732
773
|
}
|
|
@@ -763,7 +804,9 @@ function BodyMap3D(props) {
|
|
|
763
804
|
}
|
|
764
805
|
|
|
765
806
|
exports.BodyMap3D = BodyMap3D;
|
|
807
|
+
exports.ensureNormals = ensureNormals;
|
|
766
808
|
exports.seamBlend = seamBlend;
|
|
809
|
+
exports.seamWeight = seamWeight;
|
|
767
810
|
exports.serializeReport = serializeReport;
|
|
768
811
|
//# sourceMappingURL=three.cjs.map
|
|
769
812
|
//# sourceMappingURL=three.cjs.map
|