@liquidcars/atlas 0.1.44 → 0.1.45

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
@@ -159,14 +159,23 @@ La misma funcionalidad puede controlarse explícitamente:
159
159
 
160
160
  ```js
161
161
  const atlas = document.querySelector("liquidcars-atlas");
162
- const frame = atlas.captureFrame(); // canvas 2D con el framebuffer actual
162
+ const transparent = atlas.captureFrame(); // canvas 2D con alfa
163
+ const themed = atlas.captureFrame({ background: "theme" }); // añade el fondo visual del componente
164
+ const white = atlas.captureFrame({ background: "#ffffff" }); // fondo sólido opcional
165
+ const presentation = atlas.captureFrame({ background: "transparent", scale: 2 }); // salida HD
163
166
  atlas.prepareForPrint();
164
167
  atlas.restoreAfterPrint();
165
168
  ```
166
169
 
167
170
  `captureFrame()` usa `WebGLRenderingContext.readPixels()` para funcionar también
168
171
  en navegadores que no permiten copiar directamente un canvas WebGL sin
169
- `preserveDrawingBuffer`. Para evitar que un bloque se divida entre páginas, el
172
+ `preserveDrawingBuffer`. El framebuffer permanece transparente: el fondo de tema
173
+ se compone en el canvas 2D únicamente cuando se solicita y no recibe luces ni
174
+ sombras de la escena. `scale` vuelve a renderizar temporalmente entre 1× y 4×,
175
+ respetando el límite de framebuffer del navegador, y restaura inmediatamente el
176
+ canvas interactivo. Los colores WebGL semitransparentes se convierten de alfa
177
+ premultiplicado a alfa directo para conservar el tono de los contenedores
178
+ abiertos cuando el PNG se coloca sobre un fondo claro. Para evitar que un bloque se divida entre páginas, el
170
179
  componente aplica `break-inside: avoid` durante la impresión.
171
180
 
172
181
  ## Contrato de datos
@@ -11890,7 +11890,7 @@ var Qc = class {
11890
11890
  }
11891
11891
  }, $c = {
11892
11892
  name: "@liquidcars/atlas",
11893
- version: "0.1.44",
11893
+ version: "0.1.45",
11894
11894
  description: "Reusable 3D conceptual atlas Web Component for LiquidCars-style models",
11895
11895
  type: "module",
11896
11896
  scripts: {
@@ -12760,7 +12760,23 @@ function pu(e, t, n, r, i = .025) {
12760
12760
  backRotation: Math.PI / 2
12761
12761
  };
12762
12762
  }
12763
- function mu(e, t, n, r = "", i = !0) {
12763
+ function mu(e, t, n = null, r = .08) {
12764
+ let i = (Number(e?.x) || 0) - (Number(t?.x) || 0), a = (Number(e?.y) || 0) - (Number(t?.y) || 0), o = (Number(e?.z) || 0) - (Number(t?.z) || 0), s = Math.hypot(i, a, o), c = [
12765
+ "front",
12766
+ "back",
12767
+ "top"
12768
+ ];
12769
+ if (!s) return c.includes(n) ? n : "front";
12770
+ let l = {
12771
+ front: o / s,
12772
+ back: -o / s,
12773
+ top: a / s
12774
+ }, u = "front";
12775
+ for (let e of c.slice(1)) l[e] > l[u] && (u = e);
12776
+ let d = Math.max(0, Math.min(.5, Number(r) || 0));
12777
+ return c.includes(n) && l[n] > 0 && l[n] + d >= l[u] ? n : l[u] > 0 ? u : c.includes(n) ? n : "front";
12778
+ }
12779
+ function hu(e, t, n, r = "", i = !0) {
12764
12780
  let a = document.createElement("canvas"), o = a.getContext("2d"), s = n.x * .88, c = Math.min(.82, n.y * .64);
12765
12781
  a.width = Math.ceil(s * 320), a.height = Math.ceil(c * 320), o.imageSmoothingEnabled = !0, o.imageSmoothingQuality = "high", o.clearRect(0, 0, a.width, a.height);
12766
12782
  let l = a.height * .62;
@@ -12805,29 +12821,69 @@ function mu(e, t, n, r = "", i = !0) {
12805
12821
  ]) e.renderOrder = 20, e.frustumCulled = !1, e.material.depthTest = !0, e.material.depthWrite = !1, e.material.transparent = !0;
12806
12822
  return x.renderOrder = 20, x.frustumCulled = !1, x.userData.front = S, x.userData.back = C, x.userData.top = w, x.userData.height = c, x.userData.width = s, x.userData.textOffsetX = h, x.userData.textOffsetY = g, x.userData.nodeLabel = !0, x;
12807
12823
  }
12808
- function hu(e, t, n, r = globalThis.document) {
12824
+ function gu(e, t, n, r) {
12825
+ if (!r || r === "transparent" || !e?.fillRect) return;
12826
+ let i = typeof r == "string" ? { color: r } : r, a = i.fade || i.color || "#0a111a", o = i.glow || a;
12827
+ if (e.save?.(), e.globalCompositeOperation = "destination-over", o !== a && e.createRadialGradient && e.scale) {
12828
+ e.scale(t, n);
12829
+ let r = e.createRadialGradient(.5, .45, 0, .5, .45, .75);
12830
+ r.addColorStop(0, o), r.addColorStop(.82, a), r.addColorStop(1, a), e.fillStyle = r, e.fillRect(0, 0, 1, 1);
12831
+ } else e.fillStyle = a, e.fillRect(0, 0, t, n);
12832
+ e.restore?.();
12833
+ }
12834
+ function _u(e) {
12835
+ for (let t = 0; t < e.length; t += 4) {
12836
+ let n = e[t + 3];
12837
+ if (!n || n === 255) continue;
12838
+ let r = 255 / n;
12839
+ e[t] = Math.min(255, Math.round(e[t] * r)), e[t + 1] = Math.min(255, Math.round(e[t + 1] * r)), e[t + 2] = Math.min(255, Math.round(e[t + 2] * r));
12840
+ }
12841
+ }
12842
+ function vu(e, t, n, r = 8192) {
12843
+ let i = Math.max(1, Math.min(4, Number(n) || 1));
12844
+ if (i === 1 || !e?.getPixelRatio || !e?.getSize || !e?.setPixelRatio || !e?.setSize) return null;
12845
+ let a = e.getPixelRatio(), o = {
12846
+ x: 0,
12847
+ y: 0,
12848
+ set(e, t) {
12849
+ return this.x = e, this.y = t, this;
12850
+ }
12851
+ };
12852
+ if (e.getSize(o), !o.x || !o.y) return null;
12853
+ let s = t?.getParameter && t?.MAX_RENDERBUFFER_SIZE ? Number(t.getParameter(t.MAX_RENDERBUFFER_SIZE)) : 0, c = Math.max(1, Math.min(Number(r) || 8192, s || Infinity)), l = t?.drawingBufferWidth || o.x * a, u = t?.drawingBufferHeight || o.y * a, d = Math.max(1, Math.min(i, c / l, c / u));
12854
+ return d <= 1 ? null : (e.setPixelRatio(a * d), e.setSize(o.x, o.y, !1), () => {
12855
+ e.setPixelRatio(a), e.setSize(o.x, o.y, !1);
12856
+ });
12857
+ }
12858
+ function yu(e, t, n, r = globalThis.document, i = {}) {
12809
12859
  if (!e || !t || !n || !r?.createElement) return null;
12860
+ let a = null;
12810
12861
  try {
12811
- e.render(t, n);
12812
- let i = e.getContext?.(), a = i?.drawingBufferWidth || e.domElement?.width || 0, o = i?.drawingBufferHeight || e.domElement?.height || 0;
12813
- if (!i?.readPixels || !a || !o) return null;
12814
- let s = new Uint8Array(a * o * 4);
12815
- i.readPixels(0, 0, a, o, i.RGBA, i.UNSIGNED_BYTE, s);
12816
- let c = r.createElement("canvas");
12817
- c.className = "atlas-print-snapshot", c.width = a, c.height = o, c.setAttribute("aria-hidden", "true");
12818
- let l = c.getContext?.("2d");
12819
- if (!l) return null;
12820
- let u = l.createImageData(a, o), d = a * 4;
12821
- for (let e = 0; e < o; e += 1) {
12822
- let t = o - e - 1;
12823
- u.data.set(s.subarray(t * d, (t + 1) * d), e * d);
12824
- }
12825
- return l.putImageData(u, 0, 0), c;
12862
+ let o = e.getContext?.();
12863
+ a = vu(e, o, i.scale, i.maximumDimension), e.render(t, n);
12864
+ let s = e.getContext?.(), c = s?.drawingBufferWidth || e.domElement?.width || 0, l = s?.drawingBufferHeight || e.domElement?.height || 0;
12865
+ if (!s?.readPixels || !c || !l) return null;
12866
+ let u = new Uint8Array(c * l * 4);
12867
+ s.readPixels(0, 0, c, l, s.RGBA, s.UNSIGNED_BYTE, u);
12868
+ let d = r.createElement("canvas");
12869
+ d.className = "atlas-print-snapshot", d.width = c, d.height = l, d.setAttribute("aria-hidden", "true");
12870
+ let f = d.getContext?.("2d");
12871
+ if (!f) return null;
12872
+ let p = f.createImageData(c, l), m = c * 4;
12873
+ for (let e = 0; e < l; e += 1) {
12874
+ let t = l - e - 1;
12875
+ p.data.set(u.subarray(t * m, (t + 1) * m), e * m);
12876
+ }
12877
+ return s.getContextAttributes?.().premultipliedAlpha !== !1 && _u(p.data), f.putImageData(p, 0, 0), gu(f, c, l, i.background), d;
12826
12878
  } catch {
12827
12879
  return null;
12880
+ } finally {
12881
+ if (a) try {
12882
+ a(), e.render(t, n);
12883
+ } catch {}
12828
12884
  }
12829
12885
  }
12830
- var gu = class extends HTMLElement {
12886
+ var bu = class extends HTMLElement {
12831
12887
  static version = $c;
12832
12888
  static get observedAttributes() {
12833
12889
  return [
@@ -12916,8 +12972,12 @@ var gu = class extends HTMLElement {
12916
12972
  set palette(e) {
12917
12973
  this.setPalette(e);
12918
12974
  }
12919
- captureFrame() {
12920
- return hu(this.renderer, this.scene, this.camera, this.ownerDocument);
12975
+ captureFrame(e = {}) {
12976
+ let t = e.background === "theme" ? this.theme?.background || jl.background : e.background;
12977
+ return yu(this.renderer, this.scene, this.camera, this.ownerDocument, {
12978
+ ...e,
12979
+ background: t
12980
+ });
12921
12981
  }
12922
12982
  prepareForPrint() {
12923
12983
  if (this._printState) return this;
@@ -13663,7 +13723,7 @@ var gu = class extends HTMLElement {
13663
13723
  1
13664
13724
  ] : e.s), t.group.add(t.edge);
13665
13725
  }
13666
- t.label = mu(e.name, a, t.labelSize, e.type, this.showShellLabels), t.labelAnchor = fu(e, this.modelData.style), t.label.userData.node = t, t.label.traverse((e) => {
13726
+ t.label = hu(e.name, a, t.labelSize, e.type, this.showShellLabels), t.labelAnchor = fu(e, this.modelData.style), t.label.userData.node = t, t.label.traverse((e) => {
13667
13727
  e.userData.node = t;
13668
13728
  }), t.group.add(t.label), this.scene.add(t.group);
13669
13729
  }
@@ -13953,10 +14013,10 @@ var gu = class extends HTMLElement {
13953
14013
  e.label.userData.textOffsetY;
13954
14014
  let m = e.labelSize || new U().fromArray(e.s), h = pu(e.labelAnchor, m, f, d);
13955
14015
  e.label.visible = n;
13956
- let g = this._worldPosition(e), _ = this.itemFacing === "camera" && !wl(e.type) || this.camera.position.z >= g.z, v = this.camera.position.y > g.y + .25;
13957
- if (h) c.visible = _, l.visible = !_, u.visible = !1, c.scale.setScalar(1), l.scale.setScalar(1), c.position.set(h.x, h.y, m.z / 2 + .025), l.position.set(h.x, h.y, -m.z / 2 - .025), c.rotation.z = h.frontRotation, l.rotation.z = h.backRotation, c.material.color.set(15923964), l.material.color.set(15923964), c.material.opacity = t, l.material.opacity = t;
14016
+ let g = this._worldPosition(e), _ = this.itemFacing === "camera" && !wl(e.type) || this.camera.position.z >= g.z, v = e.label.userData.visibleFace || (_ ? "front" : "back"), y = o ? mu(this.camera.position, g, v) : null;
14017
+ if (y && (e.label.userData.visibleFace = y), h) c.visible = _, l.visible = !_, u.visible = !1, c.scale.setScalar(1), l.scale.setScalar(1), c.position.set(h.x, h.y, m.z / 2 + .025), l.position.set(h.x, h.y, -m.z / 2 - .025), c.rotation.z = h.frontRotation, l.rotation.z = h.backRotation, c.material.color.set(15923964), l.material.color.set(15923964), c.material.opacity = t, l.material.opacity = t;
13958
14018
  else if (wl(e.type)) {
13959
- c.rotation.z = 0, l.rotation.z = 0, c.visible = _ && (!o || s), l.visible = !_ && (!o || s), u.visible = s && v;
14019
+ c.rotation.z = 0, l.rotation.z = 0, c.visible = o ? y === "front" : _, l.visible = o ? y === "back" : !_, u.visible = s && y === "top";
13960
14020
  let e = s ? .52 : 1;
13961
14021
  c.scale.setScalar(e), c.position.x = s ? -m.x / 2 + .18 + f * e / 2 - p * e : 0;
13962
14022
  let n = .18;
@@ -14139,8 +14199,8 @@ var gu = class extends HTMLElement {
14139
14199
  n ? n.textContent = e : t.insertAdjacentHTML("beforeend", "<div class=\"error\" role=\"alert\">" + Ul(e) + "</div>");
14140
14200
  }
14141
14201
  };
14142
- customElements.get("liquidcars-atlas") || customElements.define("liquidcars-atlas", gu);
14202
+ customElements.get("liquidcars-atlas") || customElements.define("liquidcars-atlas", bu);
14143
14203
  //#endregion
14144
- export { $c as ATLAS_VERSION, tl as DEFAULT_RELATION_MARKER, gu as LiquidCarsAtlas, nl as RELATION_DISPLAY_MODES, hu as captureRendererFrame, su as createSvgExtrudeGeometry, xl as getGeometryCatalog, Sl as getGeometryPackCatalog, pu as labelPlacementForAnchor, du as normalizeLabelAnchor, ql as normalizeModel, yl as registerGeometryPack, fu as resolveEntityLabelAnchor, bl as unregisterGeometryPack };
14204
+ export { $c as ATLAS_VERSION, tl as DEFAULT_RELATION_MARKER, bu as LiquidCarsAtlas, nl as RELATION_DISPLAY_MODES, yu as captureRendererFrame, su as createSvgExtrudeGeometry, xl as getGeometryCatalog, Sl as getGeometryPackCatalog, pu as labelPlacementForAnchor, du as normalizeLabelAnchor, ql as normalizeModel, mu as preferredContainerLabelFace, yl as registerGeometryPack, fu as resolveEntityLabelAnchor, bl as unregisterGeometryPack };
14145
14205
 
14146
14206
  //# sourceMappingURL=liquidcars-atlas.js.map