@playcanvas/web-components 0.5.0 → 0.7.0

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.
Files changed (36) hide show
  1. package/dist/asset.d.ts +8 -0
  2. package/dist/components/button-component.d.ts +184 -0
  3. package/dist/components/camera-component.d.ts +1 -1
  4. package/dist/components/element-component.d.ts +162 -16
  5. package/dist/components/gsplat-component.d.ts +79 -0
  6. package/dist/components/layoutchild-component.d.ts +110 -0
  7. package/dist/components/layoutgroup-component.d.ts +134 -0
  8. package/dist/components/light-component.d.ts +1 -1
  9. package/dist/components/scrollbar-component.d.ts +68 -0
  10. package/dist/components/scrollview-component.d.ts +173 -0
  11. package/dist/entity.d.ts +4 -0
  12. package/dist/index.d.ts +7 -2
  13. package/dist/pwc.cjs +1957 -59
  14. package/dist/pwc.cjs.map +1 -1
  15. package/dist/pwc.js +1957 -59
  16. package/dist/pwc.js.map +1 -1
  17. package/dist/pwc.min.js +1 -1
  18. package/dist/pwc.min.js.map +1 -1
  19. package/dist/pwc.mjs +1953 -60
  20. package/dist/pwc.mjs.map +1 -1
  21. package/dist/utils.d.ts +20 -1
  22. package/package.json +9 -9
  23. package/src/app.ts +5 -0
  24. package/src/asset.ts +75 -2
  25. package/src/components/button-component.ts +450 -0
  26. package/src/components/element-component.ts +415 -5
  27. package/src/components/gsplat-component.ts +161 -0
  28. package/src/components/layoutchild-component.ts +232 -0
  29. package/src/components/layoutgroup-component.ts +297 -0
  30. package/src/components/scrollbar-component.ts +166 -0
  31. package/src/components/scrollview-component.ts +427 -0
  32. package/src/entity.ts +15 -1
  33. package/src/index.ts +12 -2
  34. package/src/utils.ts +49 -1
  35. package/dist/components/splat-component.d.ts +0 -48
  36. package/src/components/splat-component.ts +0 -102
@@ -19,20 +19,48 @@ class ElementComponentElement extends ComponentElement {
19
19
 
20
20
  private _autoWidth: boolean = true;
21
21
 
22
+ private _autoHeight: boolean = true;
23
+
24
+ private _autoFitWidth: boolean = false;
25
+
26
+ private _autoFitHeight: boolean = false;
27
+
22
28
  private _color: Color = new Color(1, 1, 1, 1);
23
29
 
24
30
  private _enableMarkup: boolean = false;
25
31
 
26
32
  private _fontSize: number = 32;
27
33
 
34
+ private _maxFontSize: number = 32;
35
+
36
+ private _minFontSize: number = 8;
37
+
38
+ private _height: number = 0;
39
+
28
40
  private _lineHeight: number = 32;
29
41
 
42
+ private _margin: Vec4 | null = null;
43
+
44
+ private _mask: boolean = false;
45
+
46
+ private _opacity: number = 1;
47
+
30
48
  private _pivot: Vec2 = new Vec2(0.5, 0.5);
31
49
 
50
+ private _pixelsPerUnit: number | null = null;
51
+
52
+ private _spriteAsset: string = '';
53
+
54
+ private _spriteFrame: number = 0;
55
+
32
56
  private _text: string = '';
33
57
 
58
+ private _textureAsset: string = '';
59
+
34
60
  private _type: 'group' | 'image' | 'text' = 'group';
35
61
 
62
+ private _useInput: boolean = false;
63
+
36
64
  private _width: number = 0;
37
65
 
38
66
  private _wrapLines: boolean = false;
@@ -43,24 +71,77 @@ class ElementComponentElement extends ComponentElement {
43
71
  }
44
72
 
45
73
  initComponent() {
46
- this.component!._text._material.useFog = true;
74
+ const component = this.component as any;
75
+ if (!component) {
76
+ return;
77
+ }
78
+
79
+ // Text elements render through their own material; enable fog on it so 3D text respects
80
+ // scene fog. Image/group elements have no text material, so guard the access.
81
+ if (component._text?._material) {
82
+ component._text._material.useFog = true;
83
+ }
84
+
85
+ // The engine establishes element masking in ElementComponent._onInsert, which fires when an
86
+ // entity is inserted into the hierarchy. Web-components inserts the entity first and adds
87
+ // the element component afterwards, so that pass is missed. Re-dirty the mask state here so
88
+ // masks (e.g. a scroll view viewport) correctly clip this element and any added at runtime.
89
+ component._dirtifyMask?.();
47
90
  }
48
91
 
49
92
  getInitialComponentData() {
50
- return {
93
+ const data: Record<string, any> = {
51
94
  anchor: this._anchor,
52
95
  autoWidth: this._autoWidth,
96
+ autoHeight: this._autoHeight,
97
+ autoFitWidth: this._autoFitWidth,
98
+ autoFitHeight: this._autoFitHeight,
53
99
  color: this._color,
54
100
  enableMarkup: this._enableMarkup,
55
- fontAsset: AssetElement.get(this._asset)!.id,
56
101
  fontSize: this._fontSize,
102
+ maxFontSize: this._maxFontSize,
103
+ minFontSize: this._minFontSize,
104
+ height: this._height,
57
105
  lineHeight: this._lineHeight,
106
+ mask: this._mask,
107
+ opacity: this._opacity,
58
108
  pivot: this._pivot,
109
+ spriteFrame: this._spriteFrame,
59
110
  type: this._type,
60
111
  text: this._text,
112
+ useInput: this._useInput,
61
113
  width: this._width,
62
114
  wrapLines: this._wrapLines
63
115
  };
116
+
117
+ // Asset references are resolved from `<pc-asset>` element ids to engine asset ids. They are
118
+ // only included when they resolve, so image/group elements (with no font) don't error.
119
+ const fontAsset = AssetElement.get(this._asset);
120
+ if (fontAsset) {
121
+ data.fontAsset = fontAsset.id;
122
+ }
123
+
124
+ const spriteAsset = AssetElement.get(this._spriteAsset);
125
+ if (spriteAsset) {
126
+ data.spriteAsset = spriteAsset.id;
127
+ }
128
+
129
+ const textureAsset = AssetElement.get(this._textureAsset);
130
+ if (textureAsset) {
131
+ data.textureAsset = textureAsset.id;
132
+ }
133
+
134
+ // Margin is only applied when explicitly set. For stretched (split) anchors it governs the
135
+ // element size; for point anchors width/height take over (handled by the engine).
136
+ if (this._margin) {
137
+ data.margin = this._margin;
138
+ }
139
+
140
+ if (this._pixelsPerUnit !== null) {
141
+ data.pixelsPerUnit = this._pixelsPerUnit;
142
+ }
143
+
144
+ return data;
64
145
  }
65
146
 
66
147
  /**
@@ -91,7 +172,7 @@ class ElementComponentElement extends ComponentElement {
91
172
  }
92
173
 
93
174
  /**
94
- * Sets the id of the `pc-asset` to use for the font.
175
+ * Sets the id of the `pc-asset` to use for the font (text elements).
95
176
  * @param value - The asset ID.
96
177
  */
97
178
  set asset(value: string) {
@@ -111,7 +192,8 @@ class ElementComponentElement extends ComponentElement {
111
192
  }
112
193
 
113
194
  /**
114
- * Sets whether the element component should automatically adjust its width.
195
+ * Sets whether the element component should automatically adjust its width to the text content
196
+ * (text elements only).
115
197
  * @param value - Whether to automatically adjust the width.
116
198
  */
117
199
  set autoWidth(value: boolean) {
@@ -129,6 +211,26 @@ class ElementComponentElement extends ComponentElement {
129
211
  return this._autoWidth;
130
212
  }
131
213
 
214
+ /**
215
+ * Sets whether the element component should automatically adjust its height to the text content
216
+ * (text elements only).
217
+ * @param value - Whether to automatically adjust the height.
218
+ */
219
+ set autoHeight(value: boolean) {
220
+ this._autoHeight = value;
221
+ if (this.component) {
222
+ this.component.autoHeight = value;
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Gets whether the element component should automatically adjust its height.
228
+ * @returns Whether to automatically adjust the height.
229
+ */
230
+ get autoHeight() {
231
+ return this._autoHeight;
232
+ }
233
+
132
234
  /**
133
235
  * Sets the color of the element component.
134
236
  * @param value - The color.
@@ -186,6 +288,25 @@ class ElementComponentElement extends ComponentElement {
186
288
  return this._fontSize;
187
289
  }
188
290
 
291
+ /**
292
+ * Sets the height of the element component.
293
+ * @param value - The height.
294
+ */
295
+ set height(value: number) {
296
+ this._height = value;
297
+ if (this.component) {
298
+ this.component.height = value;
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Gets the height of the element component.
304
+ * @returns The height.
305
+ */
306
+ get height() {
307
+ return this._height;
308
+ }
309
+
189
310
  /**
190
311
  * Sets the line height of the element component.
191
312
  * @param value - The line height.
@@ -205,6 +326,64 @@ class ElementComponentElement extends ComponentElement {
205
326
  return this._lineHeight;
206
327
  }
207
328
 
329
+ /**
330
+ * Sets the margin of the element component (used to inset the element from stretched anchors).
331
+ * @param value - The margin as a Vec4 (left, bottom, right, top).
332
+ */
333
+ set margin(value: Vec4 | null) {
334
+ this._margin = value;
335
+ if (this.component && value) {
336
+ this.component.margin = value;
337
+ }
338
+ }
339
+
340
+ /**
341
+ * Gets the margin of the element component.
342
+ * @returns The margin.
343
+ */
344
+ get margin() {
345
+ return this._margin;
346
+ }
347
+
348
+ /**
349
+ * Sets whether the element component is a mask, clipping its descendants to its bounds (image
350
+ * elements only).
351
+ * @param value - Whether the element is a mask.
352
+ */
353
+ set mask(value: boolean) {
354
+ this._mask = value;
355
+ if (this.component) {
356
+ this.component.mask = value;
357
+ }
358
+ }
359
+
360
+ /**
361
+ * Gets whether the element component is a mask.
362
+ * @returns Whether the element is a mask.
363
+ */
364
+ get mask() {
365
+ return this._mask;
366
+ }
367
+
368
+ /**
369
+ * Sets the opacity of the element component.
370
+ * @param value - The opacity (0 to 1).
371
+ */
372
+ set opacity(value: number) {
373
+ this._opacity = value;
374
+ if (this.component) {
375
+ this.component.opacity = value;
376
+ }
377
+ }
378
+
379
+ /**
380
+ * Gets the opacity of the element component.
381
+ * @returns The opacity.
382
+ */
383
+ get opacity() {
384
+ return this._opacity;
385
+ }
386
+
208
387
  /**
209
388
  * Sets the pivot of the element component.
210
389
  * @param value - The pivot.
@@ -224,6 +403,64 @@ class ElementComponentElement extends ComponentElement {
224
403
  return this._pivot;
225
404
  }
226
405
 
406
+ /**
407
+ * Sets the number of pixels per unit to use when rendering a sprite (image elements only).
408
+ * @param value - The pixels per unit.
409
+ */
410
+ set pixelsPerUnit(value: number | null) {
411
+ this._pixelsPerUnit = value;
412
+ if (this.component && value !== null) {
413
+ this.component.pixelsPerUnit = value;
414
+ }
415
+ }
416
+
417
+ /**
418
+ * Gets the number of pixels per unit used when rendering a sprite.
419
+ * @returns The pixels per unit.
420
+ */
421
+ get pixelsPerUnit() {
422
+ return this._pixelsPerUnit;
423
+ }
424
+
425
+ /**
426
+ * Sets the id of the `pc-asset` to use for the sprite (image elements only).
427
+ * @param value - The sprite asset ID.
428
+ */
429
+ set spriteAsset(value: string) {
430
+ this._spriteAsset = value;
431
+ const asset = AssetElement.get(value);
432
+ if (this.component && asset) {
433
+ this.component.spriteAsset = asset.id;
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Gets the id of the `pc-asset` to use for the sprite.
439
+ * @returns The sprite asset ID.
440
+ */
441
+ get spriteAsset() {
442
+ return this._spriteAsset;
443
+ }
444
+
445
+ /**
446
+ * Sets the frame of the sprite to render (image elements only).
447
+ * @param value - The sprite frame index.
448
+ */
449
+ set spriteFrame(value: number) {
450
+ this._spriteFrame = value;
451
+ if (this.component) {
452
+ this.component.spriteFrame = value;
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Gets the frame of the sprite to render.
458
+ * @returns The sprite frame index.
459
+ */
460
+ get spriteFrame() {
461
+ return this._spriteFrame;
462
+ }
463
+
227
464
  /**
228
465
  * Sets the text of the element component.
229
466
  * @param value - The text.
@@ -243,6 +480,26 @@ class ElementComponentElement extends ComponentElement {
243
480
  return this._text;
244
481
  }
245
482
 
483
+ /**
484
+ * Sets the id of the `pc-asset` to use for the texture (image elements only).
485
+ * @param value - The texture asset ID.
486
+ */
487
+ set textureAsset(value: string) {
488
+ this._textureAsset = value;
489
+ const asset = AssetElement.get(value);
490
+ if (this.component && asset) {
491
+ this.component.textureAsset = asset.id;
492
+ }
493
+ }
494
+
495
+ /**
496
+ * Gets the id of the `pc-asset` to use for the texture.
497
+ * @returns The texture asset ID.
498
+ */
499
+ get textureAsset() {
500
+ return this._textureAsset;
501
+ }
502
+
246
503
  /**
247
504
  * Sets the type of the element component.
248
505
  * @param value - The type.
@@ -262,6 +519,25 @@ class ElementComponentElement extends ComponentElement {
262
519
  return this._type;
263
520
  }
264
521
 
522
+ /**
523
+ * Sets whether the element component accepts input events (required for buttons and scrolling).
524
+ * @param value - Whether the element accepts input.
525
+ */
526
+ set useInput(value: boolean) {
527
+ this._useInput = value;
528
+ if (this.component) {
529
+ this.component.useInput = value;
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Gets whether the element component accepts input events.
535
+ * @returns Whether the element accepts input.
536
+ */
537
+ get useInput() {
538
+ return this._useInput;
539
+ }
540
+
265
541
  /**
266
542
  * Sets the width of the element component.
267
543
  * @param value - The width.
@@ -300,19 +576,111 @@ class ElementComponentElement extends ComponentElement {
300
576
  return this._wrapLines;
301
577
  }
302
578
 
579
+ /**
580
+ * Sets whether a text element should automatically reduce its font size (down to `min-font-size`)
581
+ * so the text fits within the element's width. Requires `auto-width` to be `false`.
582
+ * @param value - Whether to auto-fit the width.
583
+ */
584
+ set autoFitWidth(value: boolean) {
585
+ this._autoFitWidth = value;
586
+ if (this.component) {
587
+ this.component.autoFitWidth = value;
588
+ }
589
+ }
590
+
591
+ /**
592
+ * Gets whether a text element automatically reduces its font size to fit its width.
593
+ * @returns Whether the width is auto-fit.
594
+ */
595
+ get autoFitWidth() {
596
+ return this._autoFitWidth;
597
+ }
598
+
599
+ /**
600
+ * Sets whether a text element should automatically reduce its font size (down to `min-font-size`)
601
+ * so the text fits within the element's height. Requires `auto-height` to be `false`.
602
+ * @param value - Whether to auto-fit the height.
603
+ */
604
+ set autoFitHeight(value: boolean) {
605
+ this._autoFitHeight = value;
606
+ if (this.component) {
607
+ this.component.autoFitHeight = value;
608
+ }
609
+ }
610
+
611
+ /**
612
+ * Gets whether a text element automatically reduces its font size to fit its height.
613
+ * @returns Whether the height is auto-fit.
614
+ */
615
+ get autoFitHeight() {
616
+ return this._autoFitHeight;
617
+ }
618
+
619
+ /**
620
+ * Sets the smallest font size a text element may use when auto-fitting.
621
+ * @param value - The minimum font size.
622
+ */
623
+ set minFontSize(value: number) {
624
+ this._minFontSize = value;
625
+ if (this.component) {
626
+ this.component.minFontSize = value;
627
+ }
628
+ }
629
+
630
+ /**
631
+ * Gets the smallest font size a text element may use when auto-fitting.
632
+ * @returns The minimum font size.
633
+ */
634
+ get minFontSize() {
635
+ return this._minFontSize;
636
+ }
637
+
638
+ /**
639
+ * Sets the largest font size a text element may use when auto-fitting.
640
+ * @param value - The maximum font size.
641
+ */
642
+ set maxFontSize(value: number) {
643
+ this._maxFontSize = value;
644
+ if (this.component) {
645
+ this.component.maxFontSize = value;
646
+ }
647
+ }
648
+
649
+ /**
650
+ * Gets the largest font size a text element may use when auto-fitting.
651
+ * @returns The maximum font size.
652
+ */
653
+ get maxFontSize() {
654
+ return this._maxFontSize;
655
+ }
656
+
303
657
  static get observedAttributes() {
304
658
  return [
305
659
  ...super.observedAttributes,
306
660
  'anchor',
307
661
  'asset',
308
662
  'auto-width',
663
+ 'auto-height',
664
+ 'auto-fit-width',
665
+ 'auto-fit-height',
309
666
  'color',
310
667
  'enable-markup',
311
668
  'font-size',
669
+ 'max-font-size',
670
+ 'min-font-size',
671
+ 'height',
312
672
  'line-height',
673
+ 'margin',
674
+ 'mask',
675
+ 'opacity',
313
676
  'pivot',
677
+ 'pixels-per-unit',
678
+ 'sprite-asset',
679
+ 'sprite-frame',
314
680
  'text',
681
+ 'texture-asset',
315
682
  'type',
683
+ 'use-input',
316
684
  'width',
317
685
  'wrap-lines'
318
686
  ];
@@ -331,6 +699,15 @@ class ElementComponentElement extends ComponentElement {
331
699
  case 'auto-width':
332
700
  this.autoWidth = newValue !== 'false';
333
701
  break;
702
+ case 'auto-height':
703
+ this.autoHeight = newValue !== 'false';
704
+ break;
705
+ case 'auto-fit-width':
706
+ this.autoFitWidth = newValue !== 'false';
707
+ break;
708
+ case 'auto-fit-height':
709
+ this.autoFitHeight = newValue !== 'false';
710
+ break;
334
711
  case 'color':
335
712
  this.color = parseColor(newValue);
336
713
  break;
@@ -340,18 +717,51 @@ class ElementComponentElement extends ComponentElement {
340
717
  case 'font-size':
341
718
  this.fontSize = Number(newValue);
342
719
  break;
720
+ case 'max-font-size':
721
+ this.maxFontSize = Number(newValue);
722
+ break;
723
+ case 'min-font-size':
724
+ this.minFontSize = Number(newValue);
725
+ break;
726
+ case 'height':
727
+ this.height = Number(newValue);
728
+ break;
343
729
  case 'line-height':
344
730
  this.lineHeight = Number(newValue);
345
731
  break;
732
+ case 'margin':
733
+ this.margin = parseVec4(newValue);
734
+ break;
735
+ case 'mask':
736
+ this.mask = this.hasAttribute(name);
737
+ break;
738
+ case 'opacity':
739
+ this.opacity = Number(newValue);
740
+ break;
346
741
  case 'pivot':
347
742
  this.pivot = parseVec2(newValue);
348
743
  break;
744
+ case 'pixels-per-unit':
745
+ this.pixelsPerUnit = Number(newValue);
746
+ break;
747
+ case 'sprite-asset':
748
+ this.spriteAsset = newValue;
749
+ break;
750
+ case 'sprite-frame':
751
+ this.spriteFrame = Number(newValue);
752
+ break;
349
753
  case 'text':
350
754
  this.text = newValue;
351
755
  break;
756
+ case 'texture-asset':
757
+ this.textureAsset = newValue;
758
+ break;
352
759
  case 'type':
353
760
  this.type = newValue as 'group' | 'image' | 'text';
354
761
  break;
762
+ case 'use-input':
763
+ this.useInput = this.hasAttribute(name);
764
+ break;
355
765
  case 'width':
356
766
  this.width = Number(newValue);
357
767
  break;
@@ -0,0 +1,161 @@
1
+ import { GSplatComponent } from 'playcanvas';
2
+
3
+ import { ComponentElement } from './component';
4
+ import { AssetElement } from '../asset';
5
+
6
+ /**
7
+ * The GSplatComponentElement interface provides properties and methods for manipulating
8
+ * {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-gsplat/ | `<pc-gsplat>`} elements.
9
+ * The GSplatComponentElement interface also inherits the properties and methods of the
10
+ * {@link HTMLElement} interface.
11
+ *
12
+ * @category Components
13
+ */
14
+ class GSplatComponentElement extends ComponentElement {
15
+ private _asset = '';
16
+
17
+ private _castShadows = false;
18
+
19
+ private _lodBaseDistance = 5;
20
+
21
+ private _lodMultiplier = 3;
22
+
23
+ /** @ignore */
24
+ constructor() {
25
+ super('gsplat');
26
+ }
27
+
28
+ getInitialComponentData() {
29
+ return {
30
+ asset: AssetElement.get(this._asset),
31
+ castShadows: this._castShadows,
32
+ lodBaseDistance: this._lodBaseDistance,
33
+ lodMultiplier: this._lodMultiplier
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Gets the underlying PlayCanvas gsplat component.
39
+ * @returns The gsplat component.
40
+ */
41
+ get component(): GSplatComponent | null {
42
+ return super.component as GSplatComponent | null;
43
+ }
44
+
45
+ /**
46
+ * Sets id of the `pc-asset` to use for the splat.
47
+ * @param value - The asset ID.
48
+ */
49
+ set asset(value: string) {
50
+ this._asset = value;
51
+ const asset = AssetElement.get(value);
52
+ if (this.component && asset) {
53
+ this.component.asset = asset;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Gets the id of the `pc-asset` to use for the splat.
59
+ * @returns The asset ID.
60
+ */
61
+ get asset() {
62
+ return this._asset;
63
+ }
64
+
65
+ /**
66
+ * Sets whether the splat casts shadows.
67
+ * @param value - Whether the splat casts shadows.
68
+ */
69
+ set castShadows(value: boolean) {
70
+ this._castShadows = value;
71
+ if (this.component) {
72
+ this.component.castShadows = value;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Gets whether the splat casts shadows.
78
+ * @returns Whether the splat casts shadows.
79
+ */
80
+ get castShadows() {
81
+ return this._castShadows;
82
+ }
83
+
84
+ /**
85
+ * Sets the base distance for the first LOD transition (LOD 0 to LOD 1). Splats closer than
86
+ * this distance use the highest quality LOD. Each subsequent LOD level transitions at a
87
+ * progressively larger distance, controlled by {@link lodMultiplier}. Clamped to a minimum of
88
+ * 0.1. Defaults to 5. Only affects assets that contain LOD levels (e.g. `.lod-meta.json`).
89
+ * @param value - The LOD base distance.
90
+ */
91
+ set lodBaseDistance(value: number) {
92
+ this._lodBaseDistance = value;
93
+ if (this.component) {
94
+ this.component.lodBaseDistance = value;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Gets the base distance for the first LOD transition.
100
+ * @returns The LOD base distance.
101
+ */
102
+ get lodBaseDistance() {
103
+ return this._lodBaseDistance;
104
+ }
105
+
106
+ /**
107
+ * Sets the multiplier between successive LOD distance thresholds. Each LOD level transitions
108
+ * at this factor times the previous level's distance, creating a geometric progression. Lower
109
+ * values keep higher quality at distance; higher values switch to coarser LODs sooner. Clamped
110
+ * to a minimum of 1.2. Defaults to 3. Only affects assets that contain LOD levels (e.g.
111
+ * `.lod-meta.json`).
112
+ * @param value - The LOD multiplier.
113
+ */
114
+ set lodMultiplier(value: number) {
115
+ this._lodMultiplier = value;
116
+ if (this.component) {
117
+ this.component.lodMultiplier = value;
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Gets the multiplier between successive LOD distance thresholds.
123
+ * @returns The LOD multiplier.
124
+ */
125
+ get lodMultiplier() {
126
+ return this._lodMultiplier;
127
+ }
128
+
129
+ static get observedAttributes() {
130
+ return [
131
+ ...super.observedAttributes,
132
+ 'asset',
133
+ 'cast-shadows',
134
+ 'lod-base-distance',
135
+ 'lod-multiplier'
136
+ ];
137
+ }
138
+
139
+ attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
140
+ super.attributeChangedCallback(name, _oldValue, newValue);
141
+
142
+ switch (name) {
143
+ case 'asset':
144
+ this.asset = newValue;
145
+ break;
146
+ case 'cast-shadows':
147
+ this.castShadows = this.hasAttribute('cast-shadows');
148
+ break;
149
+ case 'lod-base-distance':
150
+ this.lodBaseDistance = Number(newValue);
151
+ break;
152
+ case 'lod-multiplier':
153
+ this.lodMultiplier = Number(newValue);
154
+ break;
155
+ }
156
+ }
157
+ }
158
+
159
+ customElements.define('pc-gsplat', GSplatComponentElement);
160
+
161
+ export { GSplatComponentElement };