@liquidcars/atlas 0.1.10 → 0.1.12
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 +6 -3
- package/demo/index.html +2 -2
- package/dist/liquidcars-atlas.js +65 -15
- package/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,7 @@ atlas.setTheme({
|
|
|
56
56
|
lighting: { ambient: 1.8, directional: 3.0 },
|
|
57
57
|
ui: { breadcrumbs: true, panel: true, toolbar: true, hint: false }
|
|
58
58
|
});
|
|
59
|
+
atlas.setPalette({ channels: '#58b6ec', offers: '#48c8b0', connection: '#f4edba' });
|
|
59
60
|
```
|
|
60
61
|
|
|
61
62
|
El mismo bloque `theme` puede formar parte del JSON del modelo. Los estilos
|
|
@@ -75,11 +76,13 @@ Eventos disponibles: `lc-ready`, `lc-error`, `lc-select`, `lc-relation-mode` y `
|
|
|
75
76
|
- `s` son dimensiones absolutas locales `[x, y, z]`.
|
|
76
77
|
- `relations` acepta objetos `{from, to, label}` o la forma corta `[from, to, label]`.
|
|
77
78
|
|
|
78
|
-
Geometrías incluidas en esta primera versión: `box`, `cylinder`, `sphere`, `cone`, `frustum-cone`, `frustum-pyramid`, `frustum-triangle`, `prism`, `pyramid-square`, `pyramid-triangle`, `octahedron`, `dodecahedron` e `icosahedron`.
|
|
79
|
+
Geometrías incluidas en esta primera versión: `box`, `cylinder`, `sphere`, `cone`, `frustum-cone`, `frustum-pyramid`, `frustum-triangle`, `prism`, `pyramid-square`, `pyramid-triangle`, `octahedron`, `dodecahedron` e `icosahedron`. Las variantes `frustum-*` son sólidos truncados con dos caras finitas paralelas; las dimensiones `s` se aplican sobre su caja final normalizada.
|
|
80
|
+
|
|
81
|
+
La paleta puede cambiarse después de cargar el modelo mediante `atlas.setPalette({ nombre: color })` o asignando `atlas.palette = { ... }`. El cambio actualiza las piezas, aristas y relaciones sin reconstruir el modelo.
|
|
79
82
|
|
|
80
83
|
## Distribución
|
|
81
84
|
|
|
82
|
-
El archivo `dist/liquidcars-atlas.js` es un módulo ESM autocontenido: Three.js se incluye dentro del bundle, por lo que el consumidor no necesita instalar otra dependencia para probarlo. Para una distribución privada se puede servir ese archivo desde un CDN propio o desde el mismo sitio. Para publicar en npm, después de revisar el API estable:
|
|
85
|
+
El archivo `dist/liquidcars-atlas.js` es un módulo ESM autocontenido: Three.js se incluye dentro del bundle, por lo que el consumidor no necesita instalar otra dependencia para probarlo. El bundle no contiene ningún modelo de negocio ni datos de LiquidCars Atlas; los modelos se suministran aparte mediante `model`, `src` o un `<script type="application/json">`. Para una distribución privada se puede servir ese archivo desde un CDN propio o desde el mismo sitio. Para publicar en npm, después de revisar el API estable:
|
|
83
86
|
|
|
84
87
|
```bash
|
|
85
88
|
npm publish --access public
|
|
@@ -95,4 +98,4 @@ npm install ./liquidcars-atlas-0.1.10.tgz
|
|
|
95
98
|
|
|
96
99
|
## Estado
|
|
97
100
|
|
|
98
|
-
`0.1.
|
|
101
|
+
`0.1.12` mantiene la corrección del desplazamiento interno del texto y ancla las etiquetas a las dimensiones reales de las geometrías redondeadas. Además fija un margen superior absoluto para las etiquetas secundarias de contenedores abiertos, situado dentro del frontal del contenedor y sin depender de sus dimensiones. También corrige los sólidos truncados, normaliza sus dimensiones finales, refuerza la visibilidad de la toolbar, desacopla la paleta por defecto de nombres de dominio y añade actualización programática de la paleta con `setPalette`.
|
package/demo/index.html
CHANGED
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
liquidcars-atlas { display: block; width: 100%; max-width: 1480px; margin: 0 auto; }
|
|
15
15
|
code { color: #85e5d3; }
|
|
16
16
|
</style>
|
|
17
|
-
<script type="module" src="../dist/liquidcars-atlas.js?v=0.1.
|
|
17
|
+
<script type="module" src="../dist/liquidcars-atlas.js?v=0.1.12"></script>
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
|
20
20
|
<header>
|
|
21
21
|
<h1>LiquidCars Atlas</h1>
|
|
22
|
-
<p>Prueba de distribución del componente <code><liquidcars-atlas></code> · v0.1.
|
|
22
|
+
<p>Prueba de distribución del componente <code><liquidcars-atlas></code> · v0.1.12</p>
|
|
23
23
|
</header>
|
|
24
24
|
<main>
|
|
25
25
|
<liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
|
package/dist/liquidcars-atlas.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! LiquidCars Atlas 0.1.
|
|
1
|
+
/*! LiquidCars Atlas 0.1.12 | MIT */
|
|
2
2
|
|
|
3
3
|
// src/three.core.js
|
|
4
4
|
var REVISION = "180";
|
|
@@ -28993,15 +28993,7 @@ var WebGLRenderer = class {
|
|
|
28993
28993
|
|
|
28994
28994
|
// src/liquidcars-atlas.js
|
|
28995
28995
|
var DEFAULT_PALETTE = {
|
|
28996
|
-
offers: "#48c8b0",
|
|
28997
|
-
ole: "#a995f1",
|
|
28998
|
-
agreements: "#edb36f",
|
|
28999
|
-
channels: "#60b5e6",
|
|
29000
|
-
buyer: "#9cc95e",
|
|
29001
|
-
dealer: "#48c8b0",
|
|
29002
|
-
serviceProvider: "#ed8f98",
|
|
29003
28996
|
component: "#8ae4d0",
|
|
29004
|
-
channelOffer: "#d2c4ff",
|
|
29005
28997
|
connection: "#f4edba"
|
|
29006
28998
|
};
|
|
29007
28999
|
var DEFAULT_THEME = {
|
|
@@ -29029,7 +29021,7 @@ function normalizeTheme(value) {
|
|
|
29029
29021
|
}
|
|
29030
29022
|
var CSS = [
|
|
29031
29023
|
":host{display:block;position:relative;height:var(--lc-height,680px);min-height:420px;color:var(--lc-panel-title,#e9f0f5);font:14px Inter,system-ui,-apple-system,sans-serif;background:var(--lc-bg,#0a111a);border:1px solid #294252;border-radius:12px;overflow:hidden;contain:content}",
|
|
29032
|
-
"*{box-sizing:border-box}.atlas{display:grid;grid-template-columns:minmax(0,1fr) 300px;height:100%}.atlas[data-panel=hidden]{grid-template-columns:1fr}.viewport{position:relative;min-width:0;background:radial-gradient(ellipse at 50% 45%,var(--lc-bg-glow,#1c2b39),var(--lc-bg-fade,#0a111a) 82%)}canvas{display:block;width:100%;height:100%;cursor:grab;touch-action:none}.toolbar{position:absolute;z-index:
|
|
29024
|
+
"*{box-sizing:border-box}.atlas{display:grid;grid-template-columns:minmax(0,1fr) 300px;height:100%}.atlas[data-panel=hidden]{grid-template-columns:1fr}.viewport{position:relative;min-width:0;background:radial-gradient(ellipse at 50% 45%,var(--lc-bg-glow,#1c2b39),var(--lc-bg-fade,#0a111a) 82%)}canvas{display:block;width:100%;height:100%;cursor:grab;touch-action:none}.toolbar{position:absolute;z-index:10;bottom:16px;left:50%;transform:translateX(-50%);display:flex;gap:3px;padding:6px;background:var(--lc-toolbar-bg,#15232fe8);border:1px solid var(--lc-toolbar-border,#3a5062);border-radius:8px;white-space:nowrap}.toolbar[data-hidden=true],.toolbar[hidden],.panel[data-hidden=true],.panel[hidden],.crumbs[data-hidden=true],.crumbs[hidden],.hint[data-hidden=true],.hint[hidden]{display:none!important}.toolbar button{height:30px;padding:0 9px;border:0;border-radius:5px;background:none;color:var(--lc-toolbar-text,#dbe7ec);cursor:pointer}.toolbar button:hover,.toolbar button.active{background:var(--lc-toolbar-active,#1f3d4b);color:var(--lc-toolbar-active-text,#c5f2e9)}.toolbar i{display:block;width:1px;margin:2px 3px;background:#38515f}.hint{position:absolute;bottom:5px;left:0;right:0;text-align:center;font-size:11px;color:var(--lc-hint,#8da6b8);pointer-events:none}.panel{overflow:auto;padding:24px 20px;background:var(--lc-panel-bg,linear-gradient(140deg,#182633,#0e1925 65%));border-left:1px solid var(--lc-panel-border,#2a3a48)}.panel h2{font-size:26px;line-height:1.12;font-weight:470;margin:12px 0;color:var(--lc-panel-title,#e9f0f5)}.panel h3{font-size:11px;letter-spacing:1.4px;color:#91aabd;margin:24px 0 10px}.panel p{font-size:14px;line-height:1.55;color:var(--lc-panel-text,#b5c6d2)}.panel .eyebrow{font-size:11px;letter-spacing:1.7px;color:#6ad7c0}.panel .sub{font-size:13px;color:#8fa8bd;margin-bottom:16px}.panel button{display:block;width:100%;padding:10px 0;text-align:left;background:none;border:0;border-bottom:1px solid var(--lc-panel-border,#2a3a48);color:#d9e7eb;cursor:pointer}.panel button:hover{color:#6ad7c0}.panel .relation{padding:10px 0;border-bottom:1px solid var(--lc-panel-border,#2a3a48)}.panel .relation strong{display:block;font-weight:550}.panel .relation small{display:block;color:#86a6b9;font-size:12px;margin-top:4px}.panel .back{color:#9db7c8;font-size:13px}.panel .crumbs{display:flex;flex-wrap:wrap;gap:5px;align-items:center;margin:0 0 12px}.panel .crumbs button{display:inline;width:auto;padding:3px 7px;border:0;border-radius:4px;background:var(--lc-crumb-bg,#142733);color:var(--lc-crumb-text,#91b6c7);font-size:12px}.panel .crumbs button.current{background:var(--lc-crumb-active,#1c4a4d);color:var(--lc-crumb-active-text,#c5f2e9)}.panel .note{border-top:1px solid var(--lc-panel-border,#2a3a48);padding-top:16px;margin-top:22px;font-size:12px;color:#7692a6}.error{position:absolute;inset:20%;padding:18px;background:#172b3b;border:1px solid #7896a9;line-height:1.5;z-index:4}@media(max-width:900px){.toolbar{gap:0}.toolbar button{padding:0 6px;font-size:12px}}@media(max-width:760px){:host{height:680px}.atlas{grid-template-columns:1fr;grid-template-rows:minmax(420px,1fr) auto}.panel{max-height:250px;border-left:0;border-top:1px solid var(--lc-panel-border,#2a3a48);padding:18px}.toolbar{bottom:10px}.hint{display:none}}"
|
|
29033
29025
|
].join("");
|
|
29034
29026
|
var TEMPLATE = '<div class="atlas"><section class="viewport"><canvas tabindex="0" aria-label="Modelo 3D interactivo"></canvas><div class="toolbar"><button data-action="minus" aria-label="Alejar">\u2212</button><button data-action="plus" aria-label="Acercar">+</button><i></i><button data-action="fit">\u2316 Encuadrar</button><button data-action="front">\u25B1 Frontal</button><button data-action="labels" class="active" aria-pressed="true">\u25A7 Etiquetas</button><i></i><button data-action="relations-all" aria-pressed="false">Todas</button><button data-action="relations-selected" class="active" aria-pressed="true">Selecci\xF3n</button><button data-action="relations-none" aria-pressed="false">Ocultar</button></div><div class="hint">Arrastra para girar \xB7 rueda para zoom \xB7 clic para seleccionar</div></section><aside class="panel" aria-live="polite"></aside></div>';
|
|
29035
29027
|
function escapeHtml(value) {
|
|
@@ -29117,11 +29109,15 @@ function makeGeometry(kind, radius = 0, segments = 4, size = [1, 1, 1]) {
|
|
|
29117
29109
|
case "frustum-cone":
|
|
29118
29110
|
case "truncated-cone":
|
|
29119
29111
|
return r ? roundedFrustum(0.28, 0.5, r, s) : new CylinderGeometry(0.28, 0.5, 1, 32);
|
|
29112
|
+
// A frustum is a solid with two finite parallel faces. ConeGeometry
|
|
29113
|
+
// leaves the narrow face collapsed to an apex, which made both truncated
|
|
29114
|
+
// pyramid variants look like ordinary pyramids. CylinderGeometry with
|
|
29115
|
+
// three/four radial segments gives us a real triangular/square frustum.
|
|
29120
29116
|
case "frustum-pyramid":
|
|
29121
29117
|
case "truncated-pyramid":
|
|
29122
|
-
return
|
|
29118
|
+
return new CylinderGeometry(0.28, 0.5, 1, 4);
|
|
29123
29119
|
case "frustum-triangle":
|
|
29124
|
-
return
|
|
29120
|
+
return new CylinderGeometry(0.28, 0.5, 1, 3);
|
|
29125
29121
|
case "prism":
|
|
29126
29122
|
return r ? roundedPrism(6, r, s) : new CylinderGeometry(0.5, 0.5, 1, 6);
|
|
29127
29123
|
case "pyramid-square":
|
|
@@ -29140,6 +29136,15 @@ function makeGeometry(kind, radius = 0, segments = 4, size = [1, 1, 1]) {
|
|
|
29140
29136
|
return r ? roundedBox(r, s, size) : new BoxGeometry(1, 1, 1);
|
|
29141
29137
|
}
|
|
29142
29138
|
}
|
|
29139
|
+
function normalizeGeometry(geometry) {
|
|
29140
|
+
geometry.computeBoundingBox();
|
|
29141
|
+
const bounds = geometry.boundingBox;
|
|
29142
|
+
const size = bounds?.getSize(new Vector3());
|
|
29143
|
+
if (!size || !size.x || !size.y || !size.z) return geometry;
|
|
29144
|
+
geometry.scale(1 / size.x, 1 / size.y, 1 / size.z);
|
|
29145
|
+
geometry.computeBoundingBox();
|
|
29146
|
+
return geometry;
|
|
29147
|
+
}
|
|
29143
29148
|
function makeLabel(text, color, dimensions, type = "") {
|
|
29144
29149
|
const bitmap = document.createElement("canvas");
|
|
29145
29150
|
const context = bitmap.getContext("2d");
|
|
@@ -29280,6 +29285,24 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29280
29285
|
set model(value) {
|
|
29281
29286
|
this.load(value);
|
|
29282
29287
|
}
|
|
29288
|
+
get palette() {
|
|
29289
|
+
return this.modelData?.palette || { ...DEFAULT_PALETTE };
|
|
29290
|
+
}
|
|
29291
|
+
set palette(value) {
|
|
29292
|
+
this.setPalette(value);
|
|
29293
|
+
}
|
|
29294
|
+
setPalette(value = {}) {
|
|
29295
|
+
if (!value || typeof value !== "object") return this;
|
|
29296
|
+
if (!this.modelData) {
|
|
29297
|
+
this._pendingPalette = { ...this._pendingPalette || {}, ...value };
|
|
29298
|
+
return this;
|
|
29299
|
+
}
|
|
29300
|
+
this.modelData.palette = { ...this.modelData.palette, ...value };
|
|
29301
|
+
this._recolorNodes();
|
|
29302
|
+
this._rebuildRelations();
|
|
29303
|
+
this.invalidate();
|
|
29304
|
+
return this;
|
|
29305
|
+
}
|
|
29283
29306
|
get styles() {
|
|
29284
29307
|
return this.theme;
|
|
29285
29308
|
}
|
|
@@ -29325,11 +29348,25 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29325
29348
|
const panel = this.shadowRoot.querySelector(".panel");
|
|
29326
29349
|
const hint = this.shadowRoot.querySelector(".hint");
|
|
29327
29350
|
if (atlas) atlas.dataset.panel = theme.ui.panel === false ? "hidden" : "visible";
|
|
29328
|
-
|
|
29329
|
-
|
|
29330
|
-
|
|
29351
|
+
const toolbarVisible = theme.ui.toolbar !== false;
|
|
29352
|
+
const panelVisible = theme.ui.panel !== false;
|
|
29353
|
+
const hintVisible = theme.ui.hint !== false;
|
|
29354
|
+
if (toolbar) {
|
|
29355
|
+
toolbar.dataset.hidden = String(!toolbarVisible);
|
|
29356
|
+
toolbar.hidden = !toolbarVisible;
|
|
29357
|
+
toolbar.style.display = toolbarVisible ? "flex" : "none";
|
|
29358
|
+
}
|
|
29359
|
+
if (panel) {
|
|
29360
|
+
panel.dataset.hidden = String(!panelVisible);
|
|
29361
|
+
panel.hidden = !panelVisible;
|
|
29362
|
+
}
|
|
29363
|
+
if (hint) {
|
|
29364
|
+
hint.dataset.hidden = String(!hintVisible);
|
|
29365
|
+
hint.hidden = !hintVisible;
|
|
29366
|
+
}
|
|
29331
29367
|
this.shadowRoot.querySelectorAll(".crumbs").forEach((crumbs) => {
|
|
29332
29368
|
crumbs.dataset.hidden = String(theme.ui.breadcrumbs === false);
|
|
29369
|
+
crumbs.hidden = theme.ui.breadcrumbs === false;
|
|
29333
29370
|
});
|
|
29334
29371
|
}
|
|
29335
29372
|
async _loadInitial() {
|
|
@@ -29348,6 +29385,10 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29348
29385
|
try {
|
|
29349
29386
|
const data = typeof source === "string" ? await fetch(source).then((response) => response.json()) : source;
|
|
29350
29387
|
this.modelData = normalizeModel(data);
|
|
29388
|
+
if (this._pendingPalette) {
|
|
29389
|
+
this.modelData.palette = { ...this.modelData.palette, ...this._pendingPalette };
|
|
29390
|
+
this._pendingPalette = null;
|
|
29391
|
+
}
|
|
29351
29392
|
this.theme = this.modelData.theme;
|
|
29352
29393
|
this._applyTheme();
|
|
29353
29394
|
this._build();
|
|
@@ -29405,6 +29446,14 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29405
29446
|
this.nodes.clear();
|
|
29406
29447
|
this.relationGroup.clear();
|
|
29407
29448
|
}
|
|
29449
|
+
_recolorNodes() {
|
|
29450
|
+
if (!this.modelData) return;
|
|
29451
|
+
for (const node of this.nodes.values()) {
|
|
29452
|
+
const color = this.modelData.palette[node.c] || node.c || this.modelData.palette.component;
|
|
29453
|
+
if (node.material) node.material.color.set(color);
|
|
29454
|
+
if (node.edge?.material) node.edge.material.color.set(color);
|
|
29455
|
+
}
|
|
29456
|
+
}
|
|
29408
29457
|
_build() {
|
|
29409
29458
|
if (!this._ensureRenderer()) return;
|
|
29410
29459
|
this._clearObjects();
|
|
@@ -29416,6 +29465,7 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29416
29465
|
const geometryKind = entity.geometry || "box";
|
|
29417
29466
|
const baked = geometryKind === "box" && Number(entity.radius) > 0;
|
|
29418
29467
|
const geometry = makeGeometry(geometryKind, entity.radius, entity.segments, entity.s);
|
|
29468
|
+
if (!baked) normalizeGeometry(geometry);
|
|
29419
29469
|
const color = this.modelData.palette[entity.c] || entity.c || this.modelData.palette.component;
|
|
29420
29470
|
node.material = new MeshStandardMaterial({ color, roughness: 0.72, metalness: 0.06, transparent: true, opacity: entity.type === "shell" ? 0.96 : 1 });
|
|
29421
29471
|
node.mesh = new Mesh(geometry, node.material);
|
package/index.html
CHANGED
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
liquidcars-atlas { display: block; width: 100%; max-width: 1480px; margin: 0 auto; }
|
|
15
15
|
code { color: #85e5d3; }
|
|
16
16
|
</style>
|
|
17
|
-
<script type="module" src="./dist/liquidcars-atlas.js?v=0.1.
|
|
17
|
+
<script type="module" src="./dist/liquidcars-atlas.js?v=0.1.12"></script>
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
|
20
20
|
<header>
|
|
21
21
|
<h1>LiquidCars Atlas</h1>
|
|
22
|
-
<p>Prueba de distribución del componente <code><liquidcars-atlas></code> · v0.1.
|
|
22
|
+
<p>Prueba de distribución del componente <code><liquidcars-atlas></code> · v0.1.12</p>
|
|
23
23
|
</header>
|
|
24
24
|
<main>
|
|
25
25
|
<liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
|