@liquidcars/atlas 0.1.13 → 0.1.15
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 +11 -2
- package/demo/index.html +2 -2
- package/dist/liquidcars-atlas.js +420 -21
- package/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,6 +52,13 @@ atlas.model = model;
|
|
|
52
52
|
atlas.select('distribution-agreement');
|
|
53
53
|
atlas.setRelationMode('all'); // 'all' | 'selected' | 'none'
|
|
54
54
|
atlas.setToolbarVisible(true); // también se puede usar toolbar="on" | "off"
|
|
55
|
+
atlas.zoomIn();
|
|
56
|
+
atlas.zoomOut();
|
|
57
|
+
atlas.fit();
|
|
58
|
+
atlas.frontView();
|
|
59
|
+
atlas.setShellLabels(true);
|
|
60
|
+
atlas.openAllContainers();
|
|
61
|
+
atlas.closeAllContainers();
|
|
55
62
|
atlas.setTheme({
|
|
56
63
|
background: { color: '#07121e', glow: '#20394b' },
|
|
57
64
|
lighting: { ambient: 1.8, directional: 3.0 },
|
|
@@ -81,6 +88,8 @@ Geometrías incluidas en esta primera versión: `box`, `cylinder`, `sphere`, `co
|
|
|
81
88
|
|
|
82
89
|
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.
|
|
83
90
|
|
|
91
|
+
Las acciones de navegación y exploración de la toolbar también están disponibles para la página anfitriona: `zoomIn()`, `zoomOut()`, `fit()`, `frontView()`, `setShellLabels()`, `toggleShellLabels()`, `openAllContainers()` y `closeAllContainers()`. Así se puede construir una barra de controles propia sin depender de la toolbar interna.
|
|
92
|
+
|
|
84
93
|
## Distribución
|
|
85
94
|
|
|
86
95
|
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:
|
|
@@ -94,9 +103,9 @@ Una vez publicado, los consumidores podrán instalarlo con `npm install @liquidc
|
|
|
94
103
|
Para probar el paquete sin publicarlo, basta con instalar el tarball generado:
|
|
95
104
|
|
|
96
105
|
```bash
|
|
97
|
-
npm install ./liquidcars-atlas-0.1.
|
|
106
|
+
npm install ./liquidcars-atlas-0.1.15.tgz
|
|
98
107
|
```
|
|
99
108
|
|
|
100
109
|
## Estado
|
|
101
110
|
|
|
102
|
-
`0.1.
|
|
111
|
+
`0.1.15` 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 con el atributo `toolbar="on"`/`"off"` y `setToolbarVisible()`, desacopla la paleta por defecto de nombres de dominio, añade actualización programática de la paleta con `setPalette`, expone las acciones de navegación para controles externos y mantiene siempre visibles las ayudas de interacción dentro del viewport.
|
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.15"></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.15</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.15 | MIT */
|
|
2
2
|
|
|
3
3
|
// src/three.core.js
|
|
4
4
|
var REVISION = "180";
|
|
@@ -221,6 +221,7 @@ var EventDispatcher = class {
|
|
|
221
221
|
}
|
|
222
222
|
};
|
|
223
223
|
var _lut = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"];
|
|
224
|
+
var _seed = 1234567;
|
|
224
225
|
var DEG2RAD = Math.PI / 180;
|
|
225
226
|
var RAD2DEG = 180 / Math.PI;
|
|
226
227
|
function generateUUID() {
|
|
@@ -237,9 +238,102 @@ function clamp(value, min, max) {
|
|
|
237
238
|
function euclideanModulo(n, m) {
|
|
238
239
|
return (n % m + m) % m;
|
|
239
240
|
}
|
|
241
|
+
function mapLinear(x, a1, a2, b1, b2) {
|
|
242
|
+
return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
|
|
243
|
+
}
|
|
244
|
+
function inverseLerp(x, y, value) {
|
|
245
|
+
if (x !== y) {
|
|
246
|
+
return (value - x) / (y - x);
|
|
247
|
+
} else {
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
240
251
|
function lerp(x, y, t) {
|
|
241
252
|
return (1 - t) * x + t * y;
|
|
242
253
|
}
|
|
254
|
+
function damp(x, y, lambda, dt) {
|
|
255
|
+
return lerp(x, y, 1 - Math.exp(-lambda * dt));
|
|
256
|
+
}
|
|
257
|
+
function pingpong(x, length = 1) {
|
|
258
|
+
return length - Math.abs(euclideanModulo(x, length * 2) - length);
|
|
259
|
+
}
|
|
260
|
+
function smoothstep(x, min, max) {
|
|
261
|
+
if (x <= min) return 0;
|
|
262
|
+
if (x >= max) return 1;
|
|
263
|
+
x = (x - min) / (max - min);
|
|
264
|
+
return x * x * (3 - 2 * x);
|
|
265
|
+
}
|
|
266
|
+
function smootherstep(x, min, max) {
|
|
267
|
+
if (x <= min) return 0;
|
|
268
|
+
if (x >= max) return 1;
|
|
269
|
+
x = (x - min) / (max - min);
|
|
270
|
+
return x * x * x * (x * (x * 6 - 15) + 10);
|
|
271
|
+
}
|
|
272
|
+
function randInt(low, high) {
|
|
273
|
+
return low + Math.floor(Math.random() * (high - low + 1));
|
|
274
|
+
}
|
|
275
|
+
function randFloat(low, high) {
|
|
276
|
+
return low + Math.random() * (high - low);
|
|
277
|
+
}
|
|
278
|
+
function randFloatSpread(range) {
|
|
279
|
+
return range * (0.5 - Math.random());
|
|
280
|
+
}
|
|
281
|
+
function seededRandom(s) {
|
|
282
|
+
if (s !== void 0) _seed = s;
|
|
283
|
+
let t = _seed += 1831565813;
|
|
284
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
285
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
286
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
287
|
+
}
|
|
288
|
+
function degToRad(degrees) {
|
|
289
|
+
return degrees * DEG2RAD;
|
|
290
|
+
}
|
|
291
|
+
function radToDeg(radians) {
|
|
292
|
+
return radians * RAD2DEG;
|
|
293
|
+
}
|
|
294
|
+
function isPowerOfTwo(value) {
|
|
295
|
+
return (value & value - 1) === 0 && value !== 0;
|
|
296
|
+
}
|
|
297
|
+
function ceilPowerOfTwo(value) {
|
|
298
|
+
return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
|
|
299
|
+
}
|
|
300
|
+
function floorPowerOfTwo(value) {
|
|
301
|
+
return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
|
|
302
|
+
}
|
|
303
|
+
function setQuaternionFromProperEuler(q, a, b, c, order) {
|
|
304
|
+
const cos = Math.cos;
|
|
305
|
+
const sin = Math.sin;
|
|
306
|
+
const c2 = cos(b / 2);
|
|
307
|
+
const s2 = sin(b / 2);
|
|
308
|
+
const c13 = cos((a + c) / 2);
|
|
309
|
+
const s13 = sin((a + c) / 2);
|
|
310
|
+
const c1_3 = cos((a - c) / 2);
|
|
311
|
+
const s1_3 = sin((a - c) / 2);
|
|
312
|
+
const c3_1 = cos((c - a) / 2);
|
|
313
|
+
const s3_1 = sin((c - a) / 2);
|
|
314
|
+
switch (order) {
|
|
315
|
+
case "XYX":
|
|
316
|
+
q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13);
|
|
317
|
+
break;
|
|
318
|
+
case "YZY":
|
|
319
|
+
q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13);
|
|
320
|
+
break;
|
|
321
|
+
case "ZXZ":
|
|
322
|
+
q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13);
|
|
323
|
+
break;
|
|
324
|
+
case "XZX":
|
|
325
|
+
q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13);
|
|
326
|
+
break;
|
|
327
|
+
case "YXY":
|
|
328
|
+
q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13);
|
|
329
|
+
break;
|
|
330
|
+
case "ZYZ":
|
|
331
|
+
q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13);
|
|
332
|
+
break;
|
|
333
|
+
default:
|
|
334
|
+
console.warn("THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: " + order);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
243
337
|
function denormalize(value, array) {
|
|
244
338
|
switch (array.constructor) {
|
|
245
339
|
case Float32Array:
|
|
@@ -280,6 +374,250 @@ function normalize(value, array) {
|
|
|
280
374
|
throw new Error("Invalid component type.");
|
|
281
375
|
}
|
|
282
376
|
}
|
|
377
|
+
var MathUtils = {
|
|
378
|
+
DEG2RAD,
|
|
379
|
+
RAD2DEG,
|
|
380
|
+
/**
|
|
381
|
+
* Generate a [UUID]{@link https://en.wikipedia.org/wiki/Universally_unique_identifier}
|
|
382
|
+
* (universally unique identifier).
|
|
383
|
+
*
|
|
384
|
+
* @static
|
|
385
|
+
* @method
|
|
386
|
+
* @return {string} The UUID.
|
|
387
|
+
*/
|
|
388
|
+
generateUUID,
|
|
389
|
+
/**
|
|
390
|
+
* Clamps the given value between min and max.
|
|
391
|
+
*
|
|
392
|
+
* @static
|
|
393
|
+
* @method
|
|
394
|
+
* @param {number} value - The value to clamp.
|
|
395
|
+
* @param {number} min - The min value.
|
|
396
|
+
* @param {number} max - The max value.
|
|
397
|
+
* @return {number} The clamped value.
|
|
398
|
+
*/
|
|
399
|
+
clamp,
|
|
400
|
+
/**
|
|
401
|
+
* Computes the Euclidean modulo of the given parameters that
|
|
402
|
+
* is `( ( n % m ) + m ) % m`.
|
|
403
|
+
*
|
|
404
|
+
* @static
|
|
405
|
+
* @method
|
|
406
|
+
* @param {number} n - The first parameter.
|
|
407
|
+
* @param {number} m - The second parameter.
|
|
408
|
+
* @return {number} The Euclidean modulo.
|
|
409
|
+
*/
|
|
410
|
+
euclideanModulo,
|
|
411
|
+
/**
|
|
412
|
+
* Performs a linear mapping from range `<a1, a2>` to range `<b1, b2>`
|
|
413
|
+
* for the given value.
|
|
414
|
+
*
|
|
415
|
+
* @static
|
|
416
|
+
* @method
|
|
417
|
+
* @param {number} x - The value to be mapped.
|
|
418
|
+
* @param {number} a1 - Minimum value for range A.
|
|
419
|
+
* @param {number} a2 - Maximum value for range A.
|
|
420
|
+
* @param {number} b1 - Minimum value for range B.
|
|
421
|
+
* @param {number} b2 - Maximum value for range B.
|
|
422
|
+
* @return {number} The mapped value.
|
|
423
|
+
*/
|
|
424
|
+
mapLinear,
|
|
425
|
+
/**
|
|
426
|
+
* Returns the percentage in the closed interval `[0, 1]` of the given value
|
|
427
|
+
* between the start and end point.
|
|
428
|
+
*
|
|
429
|
+
* @static
|
|
430
|
+
* @method
|
|
431
|
+
* @param {number} x - The start point
|
|
432
|
+
* @param {number} y - The end point.
|
|
433
|
+
* @param {number} value - A value between start and end.
|
|
434
|
+
* @return {number} The interpolation factor.
|
|
435
|
+
*/
|
|
436
|
+
inverseLerp,
|
|
437
|
+
/**
|
|
438
|
+
* Returns a value linearly interpolated from two known points based on the given interval -
|
|
439
|
+
* `t = 0` will return `x` and `t = 1` will return `y`.
|
|
440
|
+
*
|
|
441
|
+
* @static
|
|
442
|
+
* @method
|
|
443
|
+
* @param {number} x - The start point
|
|
444
|
+
* @param {number} y - The end point.
|
|
445
|
+
* @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
|
|
446
|
+
* @return {number} The interpolated value.
|
|
447
|
+
*/
|
|
448
|
+
lerp,
|
|
449
|
+
/**
|
|
450
|
+
* Smoothly interpolate a number from `x` to `y` in a spring-like manner using a delta
|
|
451
|
+
* time to maintain frame rate independent movement. For details, see
|
|
452
|
+
* [Frame rate independent damping using lerp]{@link http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/}.
|
|
453
|
+
*
|
|
454
|
+
* @static
|
|
455
|
+
* @method
|
|
456
|
+
* @param {number} x - The current point.
|
|
457
|
+
* @param {number} y - The target point.
|
|
458
|
+
* @param {number} lambda - A higher lambda value will make the movement more sudden,
|
|
459
|
+
* and a lower value will make the movement more gradual.
|
|
460
|
+
* @param {number} dt - Delta time in seconds.
|
|
461
|
+
* @return {number} The interpolated value.
|
|
462
|
+
*/
|
|
463
|
+
damp,
|
|
464
|
+
/**
|
|
465
|
+
* Returns a value that alternates between `0` and the given `length` parameter.
|
|
466
|
+
*
|
|
467
|
+
* @static
|
|
468
|
+
* @method
|
|
469
|
+
* @param {number} x - The value to pingpong.
|
|
470
|
+
* @param {number} [length=1] - The positive value the function will pingpong to.
|
|
471
|
+
* @return {number} The alternated value.
|
|
472
|
+
*/
|
|
473
|
+
pingpong,
|
|
474
|
+
/**
|
|
475
|
+
* Returns a value in the range `[0,1]` that represents the percentage that `x` has
|
|
476
|
+
* moved between `min` and `max`, but smoothed or slowed down the closer `x` is to
|
|
477
|
+
* the `min` and `max`.
|
|
478
|
+
*
|
|
479
|
+
* See [Smoothstep]{@link http://en.wikipedia.org/wiki/Smoothstep} for more details.
|
|
480
|
+
*
|
|
481
|
+
* @static
|
|
482
|
+
* @method
|
|
483
|
+
* @param {number} x - The value to evaluate based on its position between min and max.
|
|
484
|
+
* @param {number} min - The min value. Any x value below min will be `0`.
|
|
485
|
+
* @param {number} max - The max value. Any x value above max will be `1`.
|
|
486
|
+
* @return {number} The alternated value.
|
|
487
|
+
*/
|
|
488
|
+
smoothstep,
|
|
489
|
+
/**
|
|
490
|
+
* A [variation on smoothstep]{@link https://en.wikipedia.org/wiki/Smoothstep#Variations}
|
|
491
|
+
* that has zero 1st and 2nd order derivatives at x=0 and x=1.
|
|
492
|
+
*
|
|
493
|
+
* @static
|
|
494
|
+
* @method
|
|
495
|
+
* @param {number} x - The value to evaluate based on its position between min and max.
|
|
496
|
+
* @param {number} min - The min value. Any x value below min will be `0`.
|
|
497
|
+
* @param {number} max - The max value. Any x value above max will be `1`.
|
|
498
|
+
* @return {number} The alternated value.
|
|
499
|
+
*/
|
|
500
|
+
smootherstep,
|
|
501
|
+
/**
|
|
502
|
+
* Returns a random integer from `<low, high>` interval.
|
|
503
|
+
*
|
|
504
|
+
* @static
|
|
505
|
+
* @method
|
|
506
|
+
* @param {number} low - The lower value boundary.
|
|
507
|
+
* @param {number} high - The upper value boundary
|
|
508
|
+
* @return {number} A random integer.
|
|
509
|
+
*/
|
|
510
|
+
randInt,
|
|
511
|
+
/**
|
|
512
|
+
* Returns a random float from `<low, high>` interval.
|
|
513
|
+
*
|
|
514
|
+
* @static
|
|
515
|
+
* @method
|
|
516
|
+
* @param {number} low - The lower value boundary.
|
|
517
|
+
* @param {number} high - The upper value boundary
|
|
518
|
+
* @return {number} A random float.
|
|
519
|
+
*/
|
|
520
|
+
randFloat,
|
|
521
|
+
/**
|
|
522
|
+
* Returns a random integer from `<-range/2, range/2>` interval.
|
|
523
|
+
*
|
|
524
|
+
* @static
|
|
525
|
+
* @method
|
|
526
|
+
* @param {number} range - Defines the value range.
|
|
527
|
+
* @return {number} A random float.
|
|
528
|
+
*/
|
|
529
|
+
randFloatSpread,
|
|
530
|
+
/**
|
|
531
|
+
* Returns a deterministic pseudo-random float in the interval `[0, 1]`.
|
|
532
|
+
*
|
|
533
|
+
* @static
|
|
534
|
+
* @method
|
|
535
|
+
* @param {number} [s] - The integer seed.
|
|
536
|
+
* @return {number} A random float.
|
|
537
|
+
*/
|
|
538
|
+
seededRandom,
|
|
539
|
+
/**
|
|
540
|
+
* Converts degrees to radians.
|
|
541
|
+
*
|
|
542
|
+
* @static
|
|
543
|
+
* @method
|
|
544
|
+
* @param {number} degrees - A value in degrees.
|
|
545
|
+
* @return {number} The converted value in radians.
|
|
546
|
+
*/
|
|
547
|
+
degToRad,
|
|
548
|
+
/**
|
|
549
|
+
* Converts radians to degrees.
|
|
550
|
+
*
|
|
551
|
+
* @static
|
|
552
|
+
* @method
|
|
553
|
+
* @param {number} radians - A value in radians.
|
|
554
|
+
* @return {number} The converted value in degrees.
|
|
555
|
+
*/
|
|
556
|
+
radToDeg,
|
|
557
|
+
/**
|
|
558
|
+
* Returns `true` if the given number is a power of two.
|
|
559
|
+
*
|
|
560
|
+
* @static
|
|
561
|
+
* @method
|
|
562
|
+
* @param {number} value - The value to check.
|
|
563
|
+
* @return {boolean} Whether the given number is a power of two or not.
|
|
564
|
+
*/
|
|
565
|
+
isPowerOfTwo,
|
|
566
|
+
/**
|
|
567
|
+
* Returns the smallest power of two that is greater than or equal to the given number.
|
|
568
|
+
*
|
|
569
|
+
* @static
|
|
570
|
+
* @method
|
|
571
|
+
* @param {number} value - The value to find a POT for.
|
|
572
|
+
* @return {number} The smallest power of two that is greater than or equal to the given number.
|
|
573
|
+
*/
|
|
574
|
+
ceilPowerOfTwo,
|
|
575
|
+
/**
|
|
576
|
+
* Returns the largest power of two that is less than or equal to the given number.
|
|
577
|
+
*
|
|
578
|
+
* @static
|
|
579
|
+
* @method
|
|
580
|
+
* @param {number} value - The value to find a POT for.
|
|
581
|
+
* @return {number} The largest power of two that is less than or equal to the given number.
|
|
582
|
+
*/
|
|
583
|
+
floorPowerOfTwo,
|
|
584
|
+
/**
|
|
585
|
+
* Sets the given quaternion from the [Intrinsic Proper Euler Angles]{@link https://en.wikipedia.org/wiki/Euler_angles}
|
|
586
|
+
* defined by the given angles and order.
|
|
587
|
+
*
|
|
588
|
+
* Rotations are applied to the axes in the order specified by order:
|
|
589
|
+
* rotation by angle `a` is applied first, then by angle `b`, then by angle `c`.
|
|
590
|
+
*
|
|
591
|
+
* @static
|
|
592
|
+
* @method
|
|
593
|
+
* @param {Quaternion} q - The quaternion to set.
|
|
594
|
+
* @param {number} a - The rotation applied to the first axis, in radians.
|
|
595
|
+
* @param {number} b - The rotation applied to the second axis, in radians.
|
|
596
|
+
* @param {number} c - The rotation applied to the third axis, in radians.
|
|
597
|
+
* @param {('XYX'|'XZX'|'YXY'|'YZY'|'ZXZ'|'ZYZ')} order - A string specifying the axes order.
|
|
598
|
+
*/
|
|
599
|
+
setQuaternionFromProperEuler,
|
|
600
|
+
/**
|
|
601
|
+
* Normalizes the given value according to the given typed array.
|
|
602
|
+
*
|
|
603
|
+
* @static
|
|
604
|
+
* @method
|
|
605
|
+
* @param {number} value - The float value in the range `[0,1]` to normalize.
|
|
606
|
+
* @param {TypedArray} array - The typed array that defines the data type of the value.
|
|
607
|
+
* @return {number} The normalize value.
|
|
608
|
+
*/
|
|
609
|
+
normalize,
|
|
610
|
+
/**
|
|
611
|
+
* Denormalizes the given value according to the given typed array.
|
|
612
|
+
*
|
|
613
|
+
* @static
|
|
614
|
+
* @method
|
|
615
|
+
* @param {number} value - The value to denormalize.
|
|
616
|
+
* @param {TypedArray} array - The typed array that defines the data type of the value.
|
|
617
|
+
* @return {number} The denormalize (float) value in the range `[0,1]`.
|
|
618
|
+
*/
|
|
619
|
+
denormalize
|
|
620
|
+
};
|
|
283
621
|
var Vector2 = class _Vector2 {
|
|
284
622
|
/**
|
|
285
623
|
* Constructs a new 2D vector.
|
|
@@ -29021,7 +29359,7 @@ function normalizeTheme(value) {
|
|
|
29021
29359
|
}
|
|
29022
29360
|
var CSS = [
|
|
29023
29361
|
":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}",
|
|
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:
|
|
29362
|
+
"*{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;overflow:hidden;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:28px;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;z-index:9;top:8px;bottom:auto;left:0;right:0;text-align:center;padding:2px 8px;font-size:11px;line-height:16px;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:24px}.hint{top:8px;bottom:auto;display:block}}"
|
|
29025
29363
|
].join("");
|
|
29026
29364
|
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>';
|
|
29027
29365
|
function escapeHtml(value) {
|
|
@@ -29256,6 +29594,8 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29256
29594
|
this.relations = [];
|
|
29257
29595
|
this.animationFrame = 0;
|
|
29258
29596
|
this.ready = false;
|
|
29597
|
+
this._toolbarVisible = this.getAttribute("toolbar") !== "off";
|
|
29598
|
+
this.toolbar = this.shadowRoot.querySelector(".toolbar");
|
|
29259
29599
|
this._bindControls();
|
|
29260
29600
|
this.resizeObserver = new ResizeObserver(() => this.resize());
|
|
29261
29601
|
this.resizeObserver.observe(this.canvas);
|
|
@@ -29278,7 +29618,10 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29278
29618
|
this.showShellLabels = value !== "false";
|
|
29279
29619
|
this.invalidate();
|
|
29280
29620
|
}
|
|
29281
|
-
if (name === "toolbar"
|
|
29621
|
+
if (name === "toolbar") {
|
|
29622
|
+
this._toolbarVisible = value !== "off";
|
|
29623
|
+
if (this.ready) this._applyTheme();
|
|
29624
|
+
}
|
|
29282
29625
|
}
|
|
29283
29626
|
get model() {
|
|
29284
29627
|
return this.modelData;
|
|
@@ -29305,11 +29648,76 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29305
29648
|
return this;
|
|
29306
29649
|
}
|
|
29307
29650
|
get toolbarVisible() {
|
|
29308
|
-
|
|
29309
|
-
return value === "off" ? false : value === "on" ? true : this.theme.ui.toolbar !== false;
|
|
29651
|
+
return this.hasAttribute("toolbar") ? this._toolbarVisible : this.theme.ui.toolbar !== false;
|
|
29310
29652
|
}
|
|
29311
29653
|
setToolbarVisible(value) {
|
|
29654
|
+
this._toolbarVisible = Boolean(value);
|
|
29312
29655
|
this.setAttribute("toolbar", value ? "on" : "off");
|
|
29656
|
+
this._applyTheme();
|
|
29657
|
+
return this;
|
|
29658
|
+
}
|
|
29659
|
+
zoomIn() {
|
|
29660
|
+
this.targetZoom = Math.min(2.8, this.targetZoom * 1.18);
|
|
29661
|
+
this.invalidate();
|
|
29662
|
+
return this;
|
|
29663
|
+
}
|
|
29664
|
+
zoomOut() {
|
|
29665
|
+
this.targetZoom = Math.max(0.55, this.targetZoom / 1.18);
|
|
29666
|
+
this.invalidate();
|
|
29667
|
+
return this;
|
|
29668
|
+
}
|
|
29669
|
+
fit() {
|
|
29670
|
+
const bounds = new Box3();
|
|
29671
|
+
for (const node of this.nodes.values()) {
|
|
29672
|
+
const center2 = this._worldPosition(node);
|
|
29673
|
+
const half = new Vector3(node.s[0] / 2, node.s[1] / 2, node.s[2] / 2);
|
|
29674
|
+
bounds.expandByPoint(center2.clone().sub(half));
|
|
29675
|
+
bounds.expandByPoint(center2.clone().add(half));
|
|
29676
|
+
}
|
|
29677
|
+
const center = bounds.isEmpty() ? new Vector3() : bounds.getCenter(new Vector3());
|
|
29678
|
+
const size = bounds.isEmpty() ? new Vector3(1, 1, 1) : bounds.getSize(new Vector3());
|
|
29679
|
+
const radius = Math.max(1, size.length() / 2);
|
|
29680
|
+
const fov2 = MathUtils.degToRad(this.camera.fov);
|
|
29681
|
+
const requiredDistance = radius / Math.sin(fov2 / 2) * 1.12;
|
|
29682
|
+
const baseDistance = Math.max(29, 39.5 / Math.max(this.camera.aspect, 0.5));
|
|
29683
|
+
this.targetZoom = Math.max(0.55, Math.min(2.8, baseDistance / requiredDistance));
|
|
29684
|
+
this.targetFocus.copy(center);
|
|
29685
|
+
this.invalidate();
|
|
29686
|
+
return this;
|
|
29687
|
+
}
|
|
29688
|
+
frontView() {
|
|
29689
|
+
this.yaw = 0;
|
|
29690
|
+
this.pitch = 0;
|
|
29691
|
+
this.invalidate();
|
|
29692
|
+
return this;
|
|
29693
|
+
}
|
|
29694
|
+
setShellLabels(value) {
|
|
29695
|
+
this.showShellLabels = Boolean(value);
|
|
29696
|
+
this.setAttribute("shell-labels", this.showShellLabels ? "on" : "false");
|
|
29697
|
+
const button = this.shadowRoot.querySelector('[data-action="labels"]');
|
|
29698
|
+
if (button) {
|
|
29699
|
+
button.classList.toggle("active", this.showShellLabels);
|
|
29700
|
+
button.setAttribute("aria-pressed", String(this.showShellLabels));
|
|
29701
|
+
}
|
|
29702
|
+
this.invalidate();
|
|
29703
|
+
return this;
|
|
29704
|
+
}
|
|
29705
|
+
toggleShellLabels() {
|
|
29706
|
+
return this.setShellLabels(!this.showShellLabels);
|
|
29707
|
+
}
|
|
29708
|
+
openAllContainers() {
|
|
29709
|
+
for (const node of this.nodes.values()) if (node.type === "shell") this.open.add(node.id);
|
|
29710
|
+
this._renderPanel();
|
|
29711
|
+
this._rebuildRelations();
|
|
29712
|
+
this.invalidate();
|
|
29713
|
+
return this;
|
|
29714
|
+
}
|
|
29715
|
+
closeAllContainers() {
|
|
29716
|
+
this.open.clear();
|
|
29717
|
+
this.selected = null;
|
|
29718
|
+
this._renderPanel();
|
|
29719
|
+
this._rebuildRelations();
|
|
29720
|
+
this.invalidate();
|
|
29313
29721
|
return this;
|
|
29314
29722
|
}
|
|
29315
29723
|
get styles() {
|
|
@@ -29363,7 +29771,7 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29363
29771
|
if (toolbar) {
|
|
29364
29772
|
toolbar.dataset.hidden = String(!toolbarVisible);
|
|
29365
29773
|
toolbar.hidden = !toolbarVisible;
|
|
29366
|
-
toolbar.style.display
|
|
29774
|
+
toolbar.style.setProperty("display", toolbarVisible ? "flex" : "none", "important");
|
|
29367
29775
|
}
|
|
29368
29776
|
if (panel) {
|
|
29369
29777
|
panel.dataset.hidden = String(!panelVisible);
|
|
@@ -29655,6 +30063,7 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29655
30063
|
this.targetZoom = 1;
|
|
29656
30064
|
this.focus.set(0, 0, 0);
|
|
29657
30065
|
this.targetFocus.set(0, 0, 0);
|
|
30066
|
+
this.fit();
|
|
29658
30067
|
this._renderPanel();
|
|
29659
30068
|
this._rebuildRelations();
|
|
29660
30069
|
this.invalidate();
|
|
@@ -29766,21 +30175,11 @@ var LiquidCarsAtlas = class extends HTMLElement {
|
|
|
29766
30175
|
_bindControls() {
|
|
29767
30176
|
this.shadowRoot.addEventListener("click", (event) => {
|
|
29768
30177
|
const action = event.target.closest?.("[data-action]")?.dataset.action;
|
|
29769
|
-
if (action === "minus") this.
|
|
29770
|
-
if (action === "plus") this.
|
|
29771
|
-
if (action === "fit")
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
}
|
|
29775
|
-
if (action === "front") {
|
|
29776
|
-
this.yaw = 0;
|
|
29777
|
-
this.pitch = 0;
|
|
29778
|
-
}
|
|
29779
|
-
if (action === "labels") {
|
|
29780
|
-
this.showShellLabels = !this.showShellLabels;
|
|
29781
|
-
event.target.classList.toggle("active", this.showShellLabels);
|
|
29782
|
-
event.target.setAttribute("aria-pressed", String(this.showShellLabels));
|
|
29783
|
-
}
|
|
30178
|
+
if (action === "minus") this.zoomOut();
|
|
30179
|
+
if (action === "plus") this.zoomIn();
|
|
30180
|
+
if (action === "fit") this.fit();
|
|
30181
|
+
if (action === "front") this.frontView();
|
|
30182
|
+
if (action === "labels") this.toggleShellLabels();
|
|
29784
30183
|
if (action === "relations-all") this.setRelationMode("all");
|
|
29785
30184
|
if (action === "relations-selected") this.setRelationMode("selected");
|
|
29786
30185
|
if (action === "relations-none") this.setRelationMode("none");
|
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.15"></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.15</p>
|
|
23
23
|
</header>
|
|
24
24
|
<main>
|
|
25
25
|
<liquidcars-atlas id="atlas" height="720" relation-mode="selected" shell-labels="on"></liquidcars-atlas>
|