@liquidcars/atlas 0.1.25 → 0.1.26
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 +16 -6
- package/demo/index.html +2 -2
- package/dist/liquidcars-atlas.js +86 -13
- package/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -180,9 +180,11 @@ El modelo configura cada instancia sin conocer la implementación del paquete:
|
|
|
180
180
|
Cada definición puede declarar parámetros tipados, una paleta local,
|
|
181
181
|
proporciones canónicas y anchors. Las piezas declarativas admiten primitivas,
|
|
182
182
|
posición, rotación, escala, materiales, iconos de texto o emoji e imágenes por
|
|
183
|
-
URL/data URI.
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
URL/data URI. Para planos con imagen, `imageFit` admite `cover`, `contain` y
|
|
184
|
+
`stretch`. El renderer mantiene Three.js encapsulado para evitar que los packs
|
|
185
|
+
dependan de su versión interna. Las relaciones parten del centro por defecto;
|
|
186
|
+
`fromAnchor` y `toAnchor` quedan como overrides explícitos para casos
|
|
187
|
+
excepcionales.
|
|
186
188
|
|
|
187
189
|
Si un namespace no está registrado, Atlas conserva el modelo renderizable con
|
|
188
190
|
una caja roja de fallback y emite `lc-warning` con el código
|
|
@@ -200,6 +202,13 @@ gestionan relaciones. Cada operación reconstruye la geometría necesaria,
|
|
|
200
202
|
conserva la cámara y la selección cuando sigue siendo válida, y emite
|
|
201
203
|
`lc-model-change` con el tipo de operación y el modelo resultante.
|
|
202
204
|
|
|
205
|
+
`getRenderStats()` devuelve una instantánea de entidades, relaciones, objetos
|
|
206
|
+
animados, draw calls y contadores de geometrías, texturas y programas del
|
|
207
|
+
renderer. Resulta útil para comprobar que una secuencia repetida de mutaciones
|
|
208
|
+
vuelve a una línea base estable. Al reconstruir o desconectar el componente se
|
|
209
|
+
liberan geometrías, materiales, texturas, cargas de imagen pendientes y el
|
|
210
|
+
contexto WebGL.
|
|
211
|
+
|
|
203
212
|
## Distribución
|
|
204
213
|
|
|
205
214
|
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:
|
|
@@ -213,14 +222,15 @@ Una vez publicado, los consumidores podrán instalarlo con `npm install @liquidc
|
|
|
213
222
|
Para probar el paquete sin publicarlo, basta con instalar el tarball generado:
|
|
214
223
|
|
|
215
224
|
```bash
|
|
216
|
-
npm install ./liquidcars-atlas-0.1.
|
|
225
|
+
npm install ./liquidcars-atlas-0.1.26.tgz
|
|
217
226
|
```
|
|
218
227
|
|
|
219
228
|
## Estado
|
|
220
229
|
|
|
221
|
-
`0.1.
|
|
230
|
+
`0.1.26` mantiene el centro como anclaje implícito de toda relación y utiliza
|
|
222
231
|
los puertos de geometrías externas únicamente cuando el modelo los solicita.
|
|
223
|
-
También evita recorrer los materiales de geometrías compuestas en cada frame
|
|
232
|
+
También evita recorrer los materiales de geometrías compuestas en cada frame,
|
|
233
|
+
refuerza la liberación de recursos y expone `getRenderStats()`.
|
|
224
234
|
`0.1.24` incorporó geometry packs independientes, namespaces, parámetros
|
|
225
235
|
personalizados, paletas locales, anchors e imágenes/iconos declarativos. La
|
|
226
236
|
versión `0.1.23` añadió desplazamiento lateral de cámara mediante ratón, teclado
|
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.26"></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.26</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.26 | MIT */
|
|
2
2
|
|
|
3
3
|
// src/three.core.js
|
|
4
4
|
/**
|
|
@@ -29642,17 +29642,52 @@ function createGeometryContent(definition, entity, modelPalette, invalidate) {
|
|
|
29642
29642
|
opacity: Number.isFinite(Number(part.opacity)) ? Number(part.opacity) : 1,
|
|
29643
29643
|
side: part.doubleSided ? DoubleSide : FrontSide
|
|
29644
29644
|
});
|
|
29645
|
+
let mesh;
|
|
29645
29646
|
const icon = part.icon;
|
|
29646
29647
|
const image = part.image;
|
|
29647
29648
|
if (typeof image === "string" && image) {
|
|
29648
29649
|
const bitmap = new Image();
|
|
29649
29650
|
bitmap.crossOrigin = "anonymous";
|
|
29650
29651
|
material.map = new Texture(bitmap);
|
|
29651
|
-
|
|
29652
|
+
let cancelled = false;
|
|
29653
|
+
const removeListeners = () => {
|
|
29654
|
+
bitmap.removeEventListener("load", onLoad);
|
|
29655
|
+
bitmap.removeEventListener("error", onError);
|
|
29656
|
+
};
|
|
29657
|
+
const onLoad = () => {
|
|
29658
|
+
removeListeners();
|
|
29659
|
+
if (cancelled || !material.map) return;
|
|
29660
|
+
const fit = part.imageFit || part.fit || "stretch";
|
|
29661
|
+
const imageAspect = bitmap.naturalWidth / Math.max(1, bitmap.naturalHeight);
|
|
29662
|
+
const baseWidth = Math.abs(Number(part.size?.[0])) || 1;
|
|
29663
|
+
const baseHeight = Math.abs(Number(part.size?.[1])) || 1;
|
|
29664
|
+
const faceAspect = baseWidth / baseHeight;
|
|
29665
|
+
if (fit === "cover") {
|
|
29666
|
+
if (imageAspect > faceAspect) {
|
|
29667
|
+
material.map.repeat.set(faceAspect / imageAspect, 1);
|
|
29668
|
+
material.map.offset.set((1 - material.map.repeat.x) / 2, 0);
|
|
29669
|
+
} else {
|
|
29670
|
+
material.map.repeat.set(1, imageAspect / faceAspect);
|
|
29671
|
+
material.map.offset.set(0, (1 - material.map.repeat.y) / 2);
|
|
29672
|
+
}
|
|
29673
|
+
} else if (fit === "contain" && mesh) {
|
|
29674
|
+
if (imageAspect > faceAspect) mesh.scale.y = baseWidth / imageAspect;
|
|
29675
|
+
else mesh.scale.x = baseHeight * imageAspect;
|
|
29676
|
+
}
|
|
29652
29677
|
material.map.needsUpdate = true;
|
|
29653
29678
|
invalidate?.();
|
|
29654
|
-
}
|
|
29655
|
-
|
|
29679
|
+
};
|
|
29680
|
+
const onError = () => {
|
|
29681
|
+
removeListeners();
|
|
29682
|
+
if (!cancelled) invalidate?.();
|
|
29683
|
+
};
|
|
29684
|
+
material.userData.atlasImageCleanup = () => {
|
|
29685
|
+
cancelled = true;
|
|
29686
|
+
removeListeners();
|
|
29687
|
+
bitmap.src = "";
|
|
29688
|
+
};
|
|
29689
|
+
bitmap.addEventListener("load", onLoad);
|
|
29690
|
+
bitmap.addEventListener("error", onError);
|
|
29656
29691
|
bitmap.src = image;
|
|
29657
29692
|
material.map.colorSpace = SRGBColorSpace;
|
|
29658
29693
|
material.needsUpdate = true;
|
|
@@ -29661,7 +29696,7 @@ function createGeometryContent(definition, entity, modelPalette, invalidate) {
|
|
|
29661
29696
|
material.transparent = true;
|
|
29662
29697
|
material.needsUpdate = true;
|
|
29663
29698
|
}
|
|
29664
|
-
|
|
29699
|
+
mesh = new Mesh(geometry, material);
|
|
29665
29700
|
mesh.position.fromArray(Array.isArray(part.position) ? part.position : [0, 0, 0]);
|
|
29666
29701
|
mesh.scale.fromArray(Array.isArray(part.size) ? part.size : [1, 1, 1]);
|
|
29667
29702
|
if (Array.isArray(part.rotation)) mesh.rotation.set(...part.rotation.map(Number));
|
|
@@ -29820,6 +29855,7 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29820
29855
|
}
|
|
29821
29856
|
connectedCallback() {
|
|
29822
29857
|
globalThis.addEventListener?.("lc-geometry-registry-change", this._geometryRegistryListener);
|
|
29858
|
+
this.resizeObserver.observe(this.canvas);
|
|
29823
29859
|
if (this.hasAttribute("height")) this.style.setProperty("--lc-height", this.getAttribute("height"));
|
|
29824
29860
|
this._loadInitial();
|
|
29825
29861
|
}
|
|
@@ -29827,7 +29863,13 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29827
29863
|
globalThis.removeEventListener?.("lc-geometry-registry-change", this._geometryRegistryListener);
|
|
29828
29864
|
this.resizeObserver.disconnect();
|
|
29829
29865
|
if (this.animationFrame) cancelAnimationFrame(this.animationFrame);
|
|
29830
|
-
|
|
29866
|
+
this._clearObjects();
|
|
29867
|
+
if (this.renderer) {
|
|
29868
|
+
this.renderer.dispose();
|
|
29869
|
+
this.renderer.forceContextLoss?.();
|
|
29870
|
+
this.renderer = null;
|
|
29871
|
+
}
|
|
29872
|
+
this.ready = false;
|
|
29831
29873
|
this.dispatchEvent(new CustomEvent("lc-disconnect"));
|
|
29832
29874
|
}
|
|
29833
29875
|
attributeChangedCallback(name, previous, value) {
|
|
@@ -29861,6 +29903,28 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29861
29903
|
const relation = this.selectedRelation;
|
|
29862
29904
|
return relation ? { kind: "relation", id: relation.id || null, index: relation.index, relation } : null;
|
|
29863
29905
|
}
|
|
29906
|
+
getRenderStats() {
|
|
29907
|
+
const info = this.renderer?.info;
|
|
29908
|
+
return {
|
|
29909
|
+
ready: this.ready,
|
|
29910
|
+
nodes: this.nodes.size,
|
|
29911
|
+
relations: this.relations.length,
|
|
29912
|
+
relationObjects: this.relationGroup.children.length,
|
|
29913
|
+
animatedRelationObjects: this.relationGroup.children.filter((object) => object.userData?.start).length,
|
|
29914
|
+
memory: {
|
|
29915
|
+
geometries: info?.memory?.geometries || 0,
|
|
29916
|
+
textures: info?.memory?.textures || 0,
|
|
29917
|
+
programs: info?.programs?.length || 0
|
|
29918
|
+
},
|
|
29919
|
+
render: {
|
|
29920
|
+
frame: info?.render?.frame || 0,
|
|
29921
|
+
calls: info?.render?.calls || 0,
|
|
29922
|
+
triangles: info?.render?.triangles || 0,
|
|
29923
|
+
lines: info?.render?.lines || 0,
|
|
29924
|
+
points: info?.render?.points || 0
|
|
29925
|
+
}
|
|
29926
|
+
};
|
|
29927
|
+
}
|
|
29864
29928
|
get clickBehavior() {
|
|
29865
29929
|
return this.selectionMode;
|
|
29866
29930
|
}
|
|
@@ -30240,17 +30304,26 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
30240
30304
|
return parent ? this._worldPosition(parent, trail).add(position) : position;
|
|
30241
30305
|
}
|
|
30242
30306
|
_clearObjects() {
|
|
30307
|
+
const geometries = /* @__PURE__ */ new Set();
|
|
30308
|
+
const materials = /* @__PURE__ */ new Set();
|
|
30309
|
+
const textures2 = /* @__PURE__ */ new Set();
|
|
30243
30310
|
for (const node of this.nodes.values()) {
|
|
30244
30311
|
node.group?.traverse((object) => {
|
|
30245
30312
|
if (!object.isMesh && !object.isSprite && !object.isLineSegments) return;
|
|
30246
|
-
object.geometry
|
|
30247
|
-
|
|
30248
|
-
|
|
30313
|
+
if (object.geometry && !geometries.has(object.geometry)) {
|
|
30314
|
+
geometries.add(object.geometry);
|
|
30315
|
+
object.geometry.dispose();
|
|
30316
|
+
}
|
|
30317
|
+
const objectMaterials = Array.isArray(object.material) ? object.material : [object.material];
|
|
30318
|
+
for (const material of objectMaterials.filter(Boolean)) {
|
|
30319
|
+
if (materials.has(material)) continue;
|
|
30320
|
+
materials.add(material);
|
|
30321
|
+
material.userData?.atlasImageCleanup?.();
|
|
30322
|
+
if (material.map && !textures2.has(material.map)) {
|
|
30323
|
+
textures2.add(material.map);
|
|
30324
|
+
material.map.dispose();
|
|
30325
|
+
}
|
|
30249
30326
|
material.dispose();
|
|
30250
|
-
});
|
|
30251
|
-
else {
|
|
30252
|
-
object.material?.map?.dispose();
|
|
30253
|
-
object.material?.dispose();
|
|
30254
30327
|
}
|
|
30255
30328
|
});
|
|
30256
30329
|
this.scene.remove(node.group);
|
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.26"></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.26</p>
|
|
23
23
|
</header>
|
|
24
24
|
<main>
|
|
25
25
|
<liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
|