@liquidcars/atlas 0.1.26 → 0.1.27

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 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. Para planos con imagen, `imageFit` admite `cover`, `contain` y
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,14 @@ 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.26.tgz
225
+ npm install ./liquidcars-atlas-0.1.27.tgz
226
226
  ```
227
227
 
228
228
  ## Estado
229
229
 
230
- `0.1.26` mantiene el centro como anclaje implícito de toda relación y utiliza
230
+ `0.1.27` añade carga automática de imágenes SVG remotas, SVG mediante data URI
231
+ y SVG inline, manteniendo las mismas opciones de cara y ajuste que las imágenes
232
+ raster. `0.1.26` mantiene el centro como anclaje implícito de toda relación y utiliza
231
233
  los puertos de geometrías externas únicamente cuando el modelo los solicita.
232
234
  También evita recorrer los materiales de geometrías compuestas en cada frame,
233
235
  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.26"></script>
17
+ <script type="module" src="../dist/liquidcars-atlas.js?v=0.1.27"></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>&lt;liquidcars-atlas&gt;</code> · v0.1.26</p>
22
+ <p>Prueba de distribución del componente <code>&lt;liquidcars-atlas&gt;</code> · v0.1.27</p>
23
23
  </header>
24
24
  <main>
25
25
  <liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
@@ -1,4 +1,4 @@
1
- /*! LiquidCars Atlas 0.1.26 | MIT */
1
+ /*! LiquidCars Atlas 0.1.27 | MIT */
2
2
 
3
3
  // src/three.core.js
4
4
  /**
@@ -29650,12 +29650,20 @@ 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
+ const abortController = new AbortController();
29655
+ const releaseObjectUrl = () => {
29656
+ if (!objectUrl) return;
29657
+ URL.revokeObjectURL(objectUrl);
29658
+ objectUrl = null;
29659
+ };
29653
29660
  const removeListeners = () => {
29654
29661
  bitmap.removeEventListener("load", onLoad);
29655
29662
  bitmap.removeEventListener("error", onError);
29656
29663
  };
29657
29664
  const onLoad = () => {
29658
29665
  removeListeners();
29666
+ releaseObjectUrl();
29659
29667
  if (cancelled || !material.map) return;
29660
29668
  const fit = part.imageFit || part.fit || "stretch";
29661
29669
  const imageAspect = bitmap.naturalWidth / Math.max(1, bitmap.naturalHeight);
@@ -29679,16 +29687,45 @@ function createGeometryContent(definition, entity, modelPalette, invalidate) {
29679
29687
  };
29680
29688
  const onError = () => {
29681
29689
  removeListeners();
29690
+ releaseObjectUrl();
29682
29691
  if (!cancelled) invalidate?.();
29683
29692
  };
29684
29693
  material.userData.atlasImageCleanup = () => {
29685
29694
  cancelled = true;
29695
+ abortController.abort();
29686
29696
  removeListeners();
29697
+ releaseObjectUrl();
29687
29698
  bitmap.src = "";
29688
29699
  };
29689
29700
  bitmap.addEventListener("load", onLoad);
29690
29701
  bitmap.addEventListener("error", onError);
29691
- bitmap.src = image;
29702
+ const assignImageSource = async () => {
29703
+ const inlineSvg = /^\s*<svg(?:\s|>)/i.test(image);
29704
+ if (inlineSvg) {
29705
+ objectUrl = URL.createObjectURL(new Blob([image], { type: "image/svg+xml" }));
29706
+ bitmap.src = objectUrl;
29707
+ return;
29708
+ }
29709
+ if (/^(?:data|blob):/i.test(image)) {
29710
+ bitmap.src = image;
29711
+ return;
29712
+ }
29713
+ try {
29714
+ const response = await fetch(image, { mode: "cors", signal: abortController.signal });
29715
+ if (!response.ok) throw new Error(`Image request failed with ${response.status}`);
29716
+ let blob = await response.blob();
29717
+ const contentType = response.headers.get("content-type") || blob.type;
29718
+ const looksLikeSvg = /image\/svg\+xml/i.test(contentType) || /\.svg(?:[?#]|$)/i.test(image);
29719
+ if (looksLikeSvg && blob.type !== "image/svg+xml") blob = new Blob([await blob.text()], { type: "image/svg+xml" });
29720
+ if (cancelled) return;
29721
+ objectUrl = URL.createObjectURL(blob);
29722
+ bitmap.src = objectUrl;
29723
+ } catch (error) {
29724
+ if (cancelled || error?.name === "AbortError") return;
29725
+ bitmap.src = image;
29726
+ }
29727
+ };
29728
+ assignImageSource();
29692
29729
  material.map.colorSpace = SRGBColorSpace;
29693
29730
  material.needsUpdate = true;
29694
29731
  } else if (icon != null && icon !== "") {
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.26"></script>
17
+ <script type="module" src="./dist/liquidcars-atlas.js?v=0.1.27"></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>&lt;liquidcars-atlas&gt;</code> · v0.1.26</p>
22
+ <p>Prueba de distribución del componente <code>&lt;liquidcars-atlas&gt;</code> · v0.1.27</p>
23
23
  </header>
24
24
  <main>
25
25
  <liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liquidcars/atlas",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "description": "Reusable 3D conceptual atlas Web Component for LiquidCars-style models",
5
5
  "type": "module",
6
6
  "main": "./dist/liquidcars-atlas.js",