@liquidcars/atlas 0.1.26 → 0.1.28
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 +7 -4
- package/demo/index.html +2 -2
- package/dist/liquidcars-atlas.js +67 -6
- package/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -180,8 +180,8 @@ 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
|
-
`stretch`. El renderer mantiene Three.js encapsulado para evitar que los packs
|
|
183
|
+
URL/data URI; los SVG también pueden proporcionarse inline. Para planos con
|
|
184
|
+
imagen, `imageFit` admite `cover`, `contain` y `stretch`. El renderer mantiene Three.js encapsulado para evitar que los packs
|
|
185
185
|
dependan de su versión interna. Las relaciones parten del centro por defecto;
|
|
186
186
|
`fromAnchor` y `toAnchor` quedan como overrides explícitos para casos
|
|
187
187
|
excepcionales.
|
|
@@ -222,12 +222,15 @@ Una vez publicado, los consumidores podrán instalarlo con `npm install @liquidc
|
|
|
222
222
|
Para probar el paquete sin publicarlo, basta con instalar el tarball generado:
|
|
223
223
|
|
|
224
224
|
```bash
|
|
225
|
-
npm install ./liquidcars-atlas-0.1.
|
|
225
|
+
npm install ./liquidcars-atlas-0.1.28.tgz
|
|
226
226
|
```
|
|
227
227
|
|
|
228
228
|
## Estado
|
|
229
229
|
|
|
230
|
-
`0.1.
|
|
230
|
+
`0.1.28` rasteriza explícitamente los SVG sobre un canvas antes de subirlos a
|
|
231
|
+
WebGL y emite diagnósticos cuando falla la carga o la conversión. `0.1.27` añade carga automática de imágenes SVG remotas, SVG mediante data URI
|
|
232
|
+
y SVG inline, manteniendo las mismas opciones de cara y ajuste que las imágenes
|
|
233
|
+
raster. `0.1.26` mantiene el centro como anclaje implícito de toda relación y utiliza
|
|
231
234
|
los puertos de geometrías externas únicamente cuando el modelo los solicita.
|
|
232
235
|
También evita recorrer los materiales de geometrías compuestas en cada frame,
|
|
233
236
|
refuerza la liberación de recursos y expone `getRenderStats()`.
|
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.28"></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.28</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.28 | MIT */
|
|
2
2
|
|
|
3
3
|
// src/three.core.js
|
|
4
4
|
/**
|
|
@@ -29615,7 +29615,7 @@ function partGeometry(part) {
|
|
|
29615
29615
|
if (part.shape === "plane") return new PlaneGeometry(1, 1);
|
|
29616
29616
|
return makeGeometry(part.shape || part.geometry || "box", part.radius, part.segments, part.size);
|
|
29617
29617
|
}
|
|
29618
|
-
function createGeometryContent(definition, entity, modelPalette, invalidate) {
|
|
29618
|
+
function createGeometryContent(definition, entity, modelPalette, invalidate, reportWarning) {
|
|
29619
29619
|
const parameters = resolveGeometryParameters(entity, definition);
|
|
29620
29620
|
const localPalette = {
|
|
29621
29621
|
...modelPalette,
|
|
@@ -29650,13 +29650,41 @@ function createGeometryContent(definition, entity, modelPalette, invalidate) {
|
|
|
29650
29650
|
bitmap.crossOrigin = "anonymous";
|
|
29651
29651
|
material.map = new Texture(bitmap);
|
|
29652
29652
|
let cancelled = false;
|
|
29653
|
+
let objectUrl = null;
|
|
29654
|
+
let svgSource = /^\s*<svg(?:\s|>)/i.test(image) || /^data:image\/svg\+xml/i.test(image) || /\.svg(?:[?#]|$)/i.test(image);
|
|
29655
|
+
const abortController = new AbortController();
|
|
29656
|
+
const releaseObjectUrl = () => {
|
|
29657
|
+
if (!objectUrl) return;
|
|
29658
|
+
URL.revokeObjectURL(objectUrl);
|
|
29659
|
+
objectUrl = null;
|
|
29660
|
+
};
|
|
29653
29661
|
const removeListeners = () => {
|
|
29654
29662
|
bitmap.removeEventListener("load", onLoad);
|
|
29655
29663
|
bitmap.removeEventListener("error", onError);
|
|
29656
29664
|
};
|
|
29657
29665
|
const onLoad = () => {
|
|
29658
29666
|
removeListeners();
|
|
29659
|
-
if (cancelled || !material.map)
|
|
29667
|
+
if (cancelled || !material.map) {
|
|
29668
|
+
releaseObjectUrl();
|
|
29669
|
+
return;
|
|
29670
|
+
}
|
|
29671
|
+
if (svgSource) {
|
|
29672
|
+
try {
|
|
29673
|
+
const aspect = (bitmap.naturalWidth || 1) / Math.max(1, bitmap.naturalHeight || 1);
|
|
29674
|
+
const longestSide = 1024;
|
|
29675
|
+
const canvas = document.createElement("canvas");
|
|
29676
|
+
canvas.width = aspect >= 1 ? longestSide : Math.max(1, Math.round(longestSide * aspect));
|
|
29677
|
+
canvas.height = aspect >= 1 ? Math.max(1, Math.round(longestSide / aspect)) : longestSide;
|
|
29678
|
+
const context = canvas.getContext("2d");
|
|
29679
|
+
if (!context) throw new Error("Canvas 2D is unavailable");
|
|
29680
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
29681
|
+
context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
|
|
29682
|
+
material.map.image = canvas;
|
|
29683
|
+
} catch (error) {
|
|
29684
|
+
reportWarning?.({ code: "SVG_RASTERIZE_FAILED", geometry: definition.id, entityId: entity.id, image, error });
|
|
29685
|
+
}
|
|
29686
|
+
}
|
|
29687
|
+
releaseObjectUrl();
|
|
29660
29688
|
const fit = part.imageFit || part.fit || "stretch";
|
|
29661
29689
|
const imageAspect = bitmap.naturalWidth / Math.max(1, bitmap.naturalHeight);
|
|
29662
29690
|
const baseWidth = Math.abs(Number(part.size?.[0])) || 1;
|
|
@@ -29679,16 +29707,49 @@ function createGeometryContent(definition, entity, modelPalette, invalidate) {
|
|
|
29679
29707
|
};
|
|
29680
29708
|
const onError = () => {
|
|
29681
29709
|
removeListeners();
|
|
29682
|
-
|
|
29710
|
+
releaseObjectUrl();
|
|
29711
|
+
if (!cancelled) {
|
|
29712
|
+
reportWarning?.({ code: "IMAGE_LOAD_FAILED", geometry: definition.id, entityId: entity.id, image });
|
|
29713
|
+
invalidate?.();
|
|
29714
|
+
}
|
|
29683
29715
|
};
|
|
29684
29716
|
material.userData.atlasImageCleanup = () => {
|
|
29685
29717
|
cancelled = true;
|
|
29718
|
+
abortController.abort();
|
|
29686
29719
|
removeListeners();
|
|
29720
|
+
releaseObjectUrl();
|
|
29687
29721
|
bitmap.src = "";
|
|
29688
29722
|
};
|
|
29689
29723
|
bitmap.addEventListener("load", onLoad);
|
|
29690
29724
|
bitmap.addEventListener("error", onError);
|
|
29691
|
-
|
|
29725
|
+
const assignImageSource = async () => {
|
|
29726
|
+
const inlineSvg = /^\s*<svg(?:\s|>)/i.test(image);
|
|
29727
|
+
if (inlineSvg) {
|
|
29728
|
+
objectUrl = URL.createObjectURL(new Blob([image], { type: "image/svg+xml" }));
|
|
29729
|
+
bitmap.src = objectUrl;
|
|
29730
|
+
return;
|
|
29731
|
+
}
|
|
29732
|
+
if (/^(?:data|blob):/i.test(image)) {
|
|
29733
|
+
bitmap.src = image;
|
|
29734
|
+
return;
|
|
29735
|
+
}
|
|
29736
|
+
try {
|
|
29737
|
+
const response = await fetch(image, { mode: "cors", signal: abortController.signal });
|
|
29738
|
+
if (!response.ok) throw new Error(`Image request failed with ${response.status}`);
|
|
29739
|
+
let blob = await response.blob();
|
|
29740
|
+
const contentType = response.headers.get("content-type") || blob.type;
|
|
29741
|
+
const looksLikeSvg = /image\/svg\+xml/i.test(contentType) || /\.svg(?:[?#]|$)/i.test(image);
|
|
29742
|
+
svgSource = svgSource || looksLikeSvg;
|
|
29743
|
+
if (looksLikeSvg && blob.type !== "image/svg+xml") blob = new Blob([await blob.text()], { type: "image/svg+xml" });
|
|
29744
|
+
if (cancelled) return;
|
|
29745
|
+
objectUrl = URL.createObjectURL(blob);
|
|
29746
|
+
bitmap.src = objectUrl;
|
|
29747
|
+
} catch (error) {
|
|
29748
|
+
if (cancelled || error?.name === "AbortError") return;
|
|
29749
|
+
bitmap.src = image;
|
|
29750
|
+
}
|
|
29751
|
+
};
|
|
29752
|
+
assignImageSource();
|
|
29692
29753
|
material.map.colorSpace = SRGBColorSpace;
|
|
29693
29754
|
material.needsUpdate = true;
|
|
29694
29755
|
} else if (icon != null && icon !== "") {
|
|
@@ -30376,7 +30437,7 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
30376
30437
|
node.ports = { ...definition?.anchors || {}, ...entity.ports || {} };
|
|
30377
30438
|
if (isCustom) {
|
|
30378
30439
|
try {
|
|
30379
|
-
const content = createGeometryContent(definition, entity, this.modelData.palette, () => this.invalidate());
|
|
30440
|
+
const content = createGeometryContent(definition, entity, this.modelData.palette, () => this.invalidate(), (detail) => this.dispatchEvent(new CustomEvent("lc-warning", { detail })));
|
|
30380
30441
|
content.root.scale.multiply(new Vector3().fromArray(entity.s));
|
|
30381
30442
|
node.appearanceMaterials = [];
|
|
30382
30443
|
content.root.traverse((object) => {
|
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.28"></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.28</p>
|
|
23
23
|
</header>
|
|
24
24
|
<main>
|
|
25
25
|
<liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
|