@playcanvas/web-components 0.1.2 → 0.1.4

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/dist/pwc.cjs CHANGED
@@ -78,6 +78,11 @@ class AppElement extends HTMLElement {
78
78
  this.app.assets.add(asset);
79
79
  }
80
80
  });
81
+ // Get all pc-material elements that are direct children of the pc-app element
82
+ const materialElements = this.querySelectorAll(':scope > pc-material');
83
+ Array.from(materialElements).forEach((materialElement) => {
84
+ materialElement.createMaterial();
85
+ });
81
86
  // Load assets before starting the application
82
87
  this.app.preload(() => {
83
88
  // Start the application
@@ -146,6 +151,18 @@ const parseColor = (value) => {
146
151
  const components = value.split(',').map(Number);
147
152
  return new playcanvas.Color(components);
148
153
  };
154
+ /**
155
+ * Parse an Euler angles string into a Quat object. String can be in the format of 'x,y,z'.
156
+ *
157
+ * @param value - The Euler angles string to parse.
158
+ * @returns The parsed Quat object.
159
+ */
160
+ const parseQuat = (value) => {
161
+ const [x, y, z] = value.split(',').map(Number);
162
+ const q = new playcanvas.Quat();
163
+ q.setFromEulerAngles(x, y, z);
164
+ return q;
165
+ };
149
166
  /**
150
167
  * Parse a Vec2 string into a Vec2 object. String can be in the format of 'x,y'.
151
168
  *
@@ -207,6 +224,9 @@ class EntityElement extends HTMLElement {
207
224
  * The tags of the entity.
208
225
  */
209
226
  this._tags = [];
227
+ this._entityReady = new Promise((resolve) => {
228
+ this._resolveEntity = resolve;
229
+ });
210
230
  /**
211
231
  * The PlayCanvas entity instance.
212
232
  */
@@ -222,8 +242,11 @@ class EntityElement extends HTMLElement {
222
242
  const app = await appElement.getApplication();
223
243
  // Create a new entity
224
244
  this.entity = new playcanvas.Entity(this._name, app);
225
- if (this.parentElement && this.parentElement.tagName === 'pc-entity' && this.parentElement.entity) {
226
- this.parentElement.entity.addChild(this.entity);
245
+ this._resolveEntity(this.entity);
246
+ if (this.parentElement &&
247
+ this.parentElement.tagName.toLowerCase() === 'pc-entity') {
248
+ const parentEntity = await this.parentElement._entityReady;
249
+ parentEntity.addChild(this.entity);
227
250
  }
228
251
  else {
229
252
  app.root.addChild(this.entity);
@@ -247,9 +270,18 @@ class EntityElement extends HTMLElement {
247
270
  }
248
271
  disconnectedCallback() {
249
272
  if (this.entity) {
273
+ // Notify all children that their entities are about to become invalid
274
+ const children = this.querySelectorAll('pc-entity');
275
+ children.forEach((child) => {
276
+ child.entity = null;
277
+ });
250
278
  this.entity.destroy();
251
279
  this.entity = null;
252
280
  }
281
+ // Reset the promise for potential reconnection
282
+ this._entityReady = new Promise((resolve) => {
283
+ this._resolveEntity = resolve;
284
+ });
253
285
  }
254
286
  /**
255
287
  * Sets the enabled state of the entity.
@@ -457,6 +489,10 @@ class AssetElement extends HTMLElement {
457
489
  get preload() {
458
490
  return this._preload;
459
491
  }
492
+ static get(id) {
493
+ const assetElement = document.querySelector(`pc-asset[id="${id}"]`);
494
+ return assetElement === null || assetElement === void 0 ? void 0 : assetElement.asset;
495
+ }
460
496
  static get observedAttributes() {
461
497
  return ['preload'];
462
498
  }
@@ -578,21 +614,39 @@ class CameraComponentElement extends ComponentElement {
578
614
  */
579
615
  constructor() {
580
616
  super('camera');
581
- this._clearColor = new playcanvas.Color(1, 1, 1, 1);
617
+ this._clearColor = new playcanvas.Color(0.75, 0.75, 0.75, 1);
618
+ this._clearColorBuffer = true;
619
+ this._clearDepthBuffer = true;
620
+ this._clearStencilBuffer = false;
621
+ this._cullFaces = true;
582
622
  this._farClip = 1000;
623
+ this._flipFaces = false;
583
624
  this._fov = 45;
625
+ this._frustumCulling = true;
584
626
  this._nearClip = 0.1;
585
627
  this._orthographic = false;
586
628
  this._orthoHeight = 10;
629
+ this._priority = 0;
630
+ this._rect = new playcanvas.Vec4(0, 0, 1, 1);
631
+ this._scissorRect = new playcanvas.Vec4(0, 0, 1, 1);
587
632
  }
588
633
  getInitialComponentData() {
589
634
  return {
590
635
  clearColor: this._clearColor,
636
+ clearColorBuffer: this._clearColorBuffer,
637
+ clearDepthBuffer: this._clearDepthBuffer,
638
+ clearStencilBuffer: this._clearStencilBuffer,
639
+ cullFaces: this._cullFaces,
591
640
  farClip: this._farClip,
641
+ flipFaces: this._flipFaces,
592
642
  fov: this._fov,
643
+ frustumCulling: this._frustumCulling,
593
644
  nearClip: this._nearClip,
594
- projection: this._orthographic ? playcanvas.PROJECTION_ORTHOGRAPHIC : playcanvas.PROJECTION_PERSPECTIVE,
595
- orthoHeight: this._orthoHeight
645
+ orthographic: this._orthographic,
646
+ orthoHeight: this._orthoHeight,
647
+ priority: this._priority,
648
+ rect: this._rect,
649
+ scissorRect: this._scissorRect
596
650
  };
597
651
  }
598
652
  /**
@@ -619,6 +673,74 @@ class CameraComponentElement extends ComponentElement {
619
673
  get clearColor() {
620
674
  return this._clearColor;
621
675
  }
676
+ /**
677
+ * Sets the clear color buffer of the camera.
678
+ * @param value - The clear color buffer.
679
+ */
680
+ set clearColorBuffer(value) {
681
+ this._clearColorBuffer = value;
682
+ if (this.component) {
683
+ this.component.clearColorBuffer = value;
684
+ }
685
+ }
686
+ /**
687
+ * Gets the clear color buffer of the camera.
688
+ * @returns The clear color buffer.
689
+ */
690
+ get clearColorBuffer() {
691
+ return this._clearColorBuffer;
692
+ }
693
+ /**
694
+ * Sets the clear depth buffer of the camera.
695
+ * @param value - The clear depth buffer.
696
+ */
697
+ set clearDepthBuffer(value) {
698
+ this._clearDepthBuffer = value;
699
+ if (this.component) {
700
+ this.component.clearDepthBuffer = value;
701
+ }
702
+ }
703
+ /**
704
+ * Gets the clear depth buffer of the camera.
705
+ * @returns The clear depth buffer.
706
+ */
707
+ get clearDepthBuffer() {
708
+ return this._clearDepthBuffer;
709
+ }
710
+ /**
711
+ * Sets the clear stencil buffer of the camera.
712
+ * @param value - The clear stencil buffer.
713
+ */
714
+ set clearStencilBuffer(value) {
715
+ this._clearStencilBuffer = value;
716
+ if (this.component) {
717
+ this.component.clearStencilBuffer = value;
718
+ }
719
+ }
720
+ /**
721
+ * Gets the clear stencil buffer of the camera.
722
+ * @returns The clear stencil buffer.
723
+ */
724
+ get clearStencilBuffer() {
725
+ return this._clearStencilBuffer;
726
+ }
727
+ /**
728
+ * Sets the cull faces of the camera.
729
+ * @param value - The cull faces.
730
+ */
731
+ set cullFaces(value) {
732
+ this._cullFaces = value;
733
+ if (this.component) {
734
+ this.component.cullFaces = value;
735
+ }
736
+ }
737
+ /**
738
+ * Gets the cull faces of the camera.
739
+ * @returns The cull faces.
740
+ */
741
+ get cullFaces() {
742
+ return this._cullFaces;
743
+ }
622
744
  /**
623
745
  * Sets the far clip distance of the camera.
624
746
  * @param value - The far clip distance.
@@ -636,6 +758,23 @@ class CameraComponentElement extends ComponentElement {
636
758
  get farClip() {
637
759
  return this._farClip;
638
760
  }
761
+ /**
762
+ * Sets the flip faces of the camera.
763
+ * @param value - The flip faces.
764
+ */
765
+ set flipFaces(value) {
766
+ this._flipFaces = value;
767
+ if (this.component) {
768
+ this.component.flipFaces = value;
769
+ }
770
+ }
771
+ /**
772
+ * Gets the flip faces of the camera.
773
+ * @returns The flip faces.
774
+ */
775
+ get flipFaces() {
776
+ return this._flipFaces;
777
+ }
639
778
  /**
640
779
  * Sets the field of view of the camera.
641
780
  * @param value - The field of view.
@@ -653,6 +792,23 @@ class CameraComponentElement extends ComponentElement {
653
792
  get fov() {
654
793
  return this._fov;
655
794
  }
795
+ /**
796
+ * Sets the frustum culling of the camera.
797
+ * @param value - The frustum culling.
798
+ */
799
+ set frustumCulling(value) {
800
+ this._frustumCulling = value;
801
+ if (this.component) {
802
+ this.component.frustumCulling = value;
803
+ }
804
+ }
805
+ /**
806
+ * Gets the frustum culling of the camera.
807
+ * @returns The frustum culling.
808
+ */
809
+ get frustumCulling() {
810
+ return this._frustumCulling;
811
+ }
656
812
  /**
657
813
  * Sets the near clip distance of the camera.
658
814
  * @param value - The near clip distance.
@@ -704,8 +860,76 @@ class CameraComponentElement extends ComponentElement {
704
860
  get orthoHeight() {
705
861
  return this._orthoHeight;
706
862
  }
863
+ /**
864
+ * Sets the priority of the camera.
865
+ * @param value - The priority.
866
+ */
867
+ set priority(value) {
868
+ this._priority = value;
869
+ if (this.component) {
870
+ this.component.priority = value;
871
+ }
872
+ }
873
+ /**
874
+ * Gets the priority of the camera.
875
+ * @returns The priority.
876
+ */
877
+ get priority() {
878
+ return this._priority;
879
+ }
880
+ /**
881
+ * Sets the rect of the camera.
882
+ * @param value - The rect.
883
+ */
884
+ set rect(value) {
885
+ this._rect = value;
886
+ if (this.component) {
887
+ this.component.rect = value;
888
+ }
889
+ }
890
+ /**
891
+ * Gets the rect of the camera.
892
+ * @returns The rect.
893
+ */
894
+ get rect() {
895
+ return this._rect;
896
+ }
897
+ /**
898
+ * Sets the scissor rect of the camera.
899
+ * @param value - The scissor rect.
900
+ */
901
+ set scissorRect(value) {
902
+ this._scissorRect = value;
903
+ if (this.component) {
904
+ this.component.scissorRect = value;
905
+ }
906
+ }
907
+ /**
908
+ * Gets the scissor rect of the camera.
909
+ * @returns The scissor rect.
910
+ */
911
+ get scissorRect() {
912
+ return this._scissorRect;
913
+ }
707
914
  static get observedAttributes() {
708
- return [...super.observedAttributes, 'clear-color', 'near-clip', 'far-clip', 'fov', 'orthographic', 'ortho-height'];
915
+ return [
916
+ ...super.observedAttributes,
917
+ 'clear-color',
918
+ 'clear-color-buffer',
919
+ 'clear-depth-buffer',
920
+ 'clear-stencil-buffer',
921
+ 'cull-faces',
922
+ 'far-clip',
923
+ 'flip-faces',
924
+ 'fov',
925
+ 'frustum-culling',
926
+ 'near-clip',
927
+ 'orthographic',
928
+ 'ortho-height',
929
+ 'priority',
930
+ 'rect',
931
+ 'scissor-rect'
932
+ ];
709
933
  }
710
934
  attributeChangedCallback(name, _oldValue, newValue) {
711
935
  super.attributeChangedCallback(name, _oldValue, newValue);
@@ -713,12 +937,30 @@ class CameraComponentElement extends ComponentElement {
713
937
  case 'clear-color':
714
938
  this.clearColor = parseColor(newValue);
715
939
  break;
940
+ case 'clear-color-buffer':
941
+ this.clearColorBuffer = newValue !== 'false';
942
+ break;
943
+ case 'clear-depth-buffer':
944
+ this.clearDepthBuffer = newValue !== 'false';
945
+ break;
946
+ case 'clear-stencil-buffer':
947
+ this.clearStencilBuffer = newValue !== 'false';
948
+ break;
949
+ case 'cull-faces':
950
+ this.cullFaces = newValue !== 'false';
951
+ break;
716
952
  case 'far-clip':
717
953
  this.farClip = parseFloat(newValue);
718
954
  break;
955
+ case 'flip-faces':
956
+ this.flipFaces = newValue !== 'true';
957
+ break;
719
958
  case 'fov':
720
959
  this.fov = parseFloat(newValue);
721
960
  break;
961
+ case 'frustum-culling':
962
+ this.frustumCulling = newValue !== 'false';
963
+ break;
722
964
  case 'near-clip':
723
965
  this.nearClip = parseFloat(newValue);
724
966
  break;
@@ -728,6 +970,15 @@ class CameraComponentElement extends ComponentElement {
728
970
  case 'ortho-height':
729
971
  this.orthoHeight = parseFloat(newValue);
730
972
  break;
973
+ case 'priority':
974
+ this.priority = parseFloat(newValue);
975
+ break;
976
+ case 'rect':
977
+ this.rect = parseVec4(newValue);
978
+ break;
979
+ case 'scissor-rect':
980
+ this.scissorRect = parseVec4(newValue);
981
+ break;
731
982
  }
732
983
  }
733
984
  }
@@ -744,19 +995,23 @@ class CollisionComponentElement extends ComponentElement {
744
995
  */
745
996
  constructor() {
746
997
  super('collision');
998
+ this._angularOffset = new playcanvas.Quat();
747
999
  this._axis = 1;
748
1000
  this._convexHull = false;
749
1001
  this._halfExtents = new playcanvas.Vec3(0.5, 0.5, 0.5);
750
1002
  this._height = 2;
1003
+ this._linearOffset = new playcanvas.Vec3();
751
1004
  this._radius = 0.5;
752
1005
  this._type = 'box';
753
1006
  }
754
1007
  getInitialComponentData() {
755
1008
  return {
756
1009
  axis: this._axis,
1010
+ angularOffset: this._angularOffset,
757
1011
  convexHull: this._convexHull,
758
1012
  halfExtents: this._halfExtents,
759
1013
  height: this._height,
1014
+ linearOffset: this._linearOffset,
760
1015
  radius: this._radius,
761
1016
  type: this._type
762
1017
  };
@@ -768,6 +1023,15 @@ class CollisionComponentElement extends ComponentElement {
768
1023
  get component() {
769
1024
  return super.component;
770
1025
  }
1026
+ set angularOffset(value) {
1027
+ this._angularOffset = value;
1028
+ if (this.component) {
1029
+ this.component.angularOffset = value;
1030
+ }
1031
+ }
1032
+ get angularOffset() {
1033
+ return this._angularOffset;
1034
+ }
771
1035
  set axis(value) {
772
1036
  this._axis = value;
773
1037
  if (this.component) {
@@ -804,6 +1068,15 @@ class CollisionComponentElement extends ComponentElement {
804
1068
  get height() {
805
1069
  return this._height;
806
1070
  }
1071
+ set linearOffset(value) {
1072
+ this._linearOffset = value;
1073
+ if (this.component) {
1074
+ this.component.linearOffset = value;
1075
+ }
1076
+ }
1077
+ get linearOffset() {
1078
+ return this._linearOffset;
1079
+ }
807
1080
  set radius(value) {
808
1081
  this._radius = value;
809
1082
  if (this.component) {
@@ -823,11 +1096,14 @@ class CollisionComponentElement extends ComponentElement {
823
1096
  return this._type;
824
1097
  }
825
1098
  static get observedAttributes() {
826
- return [...super.observedAttributes, 'axis', 'convex-hull', 'half-extents', 'height', 'radius', 'type'];
1099
+ return [...super.observedAttributes, 'angular-offset', 'axis', 'convex-hull', 'half-extents', 'height', 'linear-offset', 'radius', 'type'];
827
1100
  }
828
1101
  attributeChangedCallback(name, _oldValue, newValue) {
829
1102
  super.attributeChangedCallback(name, _oldValue, newValue);
830
1103
  switch (name) {
1104
+ case 'angular-offset':
1105
+ this.angularOffset = parseQuat(newValue);
1106
+ break;
831
1107
  case 'axis':
832
1108
  this.axis = parseInt(newValue, 10);
833
1109
  break;
@@ -840,6 +1116,9 @@ class CollisionComponentElement extends ComponentElement {
840
1116
  case 'height':
841
1117
  this.height = parseFloat(newValue);
842
1118
  break;
1119
+ case 'linear-offset':
1120
+ this.linearOffset = parseVec3(newValue);
1121
+ break;
843
1122
  case 'radius':
844
1123
  this.radius = parseFloat(newValue);
845
1124
  break;
@@ -875,16 +1154,12 @@ class ElementComponentElement extends ComponentElement {
875
1154
  await super.connectedCallback();
876
1155
  this.component._text._material.useFog = true;
877
1156
  }
878
- getAsset() {
879
- const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
880
- return assetElement.asset;
881
- }
882
1157
  getInitialComponentData() {
883
1158
  return {
884
1159
  anchor: this._anchor,
885
1160
  autoWidth: this._autoWidth,
886
1161
  color: this._color,
887
- fontAsset: this.getAsset().id,
1162
+ fontAsset: AssetElement.get(this._asset).id,
888
1163
  fontSize: this._fontSize,
889
1164
  lineHeight: this._lineHeight,
890
1165
  pivot: this._pivot,
@@ -912,7 +1187,7 @@ class ElementComponentElement extends ComponentElement {
912
1187
  }
913
1188
  set asset(value) {
914
1189
  this._asset = value;
915
- const asset = this.getAsset();
1190
+ const asset = AssetElement.get(value);
916
1191
  if (this.component && asset) {
917
1192
  this.component.fontAsset = asset.id;
918
1193
  }
@@ -1063,13 +1338,9 @@ class GSplatComponentElement extends ComponentElement {
1063
1338
  super('gsplat');
1064
1339
  this._asset = '';
1065
1340
  }
1066
- getAsset() {
1067
- const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
1068
- return assetElement.asset;
1069
- }
1070
1341
  getInitialComponentData() {
1071
1342
  return {
1072
- asset: this.getAsset()
1343
+ asset: AssetElement.get(this._asset)
1073
1344
  };
1074
1345
  }
1075
1346
  /**
@@ -1081,7 +1352,7 @@ class GSplatComponentElement extends ComponentElement {
1081
1352
  }
1082
1353
  set asset(value) {
1083
1354
  this._asset = value;
1084
- const asset = this.getAsset();
1355
+ const asset = AssetElement.get(value);
1085
1356
  if (this.component && asset) {
1086
1357
  this.component.asset = asset;
1087
1358
  }
@@ -1373,6 +1644,120 @@ class LightComponentElement extends ComponentElement {
1373
1644
  }
1374
1645
  customElements.define('pc-light', LightComponentElement);
1375
1646
 
1647
+ /**
1648
+ * Represents a material in the PlayCanvas engine.
1649
+ */
1650
+ class MaterialElement extends HTMLElement {
1651
+ constructor() {
1652
+ super(...arguments);
1653
+ this._diffuse = new playcanvas.Color(1, 1, 1);
1654
+ this._diffuseMap = '';
1655
+ this._metalnessMap = '';
1656
+ this._normalMap = '';
1657
+ this._roughnessMap = '';
1658
+ this.material = null;
1659
+ }
1660
+ createMaterial() {
1661
+ this.material = new playcanvas.StandardMaterial();
1662
+ this.material.glossInvert = true;
1663
+ this.material.useMetalness = true;
1664
+ this.material.diffuse = this._diffuse;
1665
+ this.diffuseMap = this._diffuseMap;
1666
+ this.metalnessMap = this._metalnessMap;
1667
+ this.normalMap = this._normalMap;
1668
+ this.roughnessMap = this._roughnessMap;
1669
+ this.material.update();
1670
+ }
1671
+ disconnectedCallback() {
1672
+ if (this.material) {
1673
+ this.material.destroy();
1674
+ this.material = null;
1675
+ }
1676
+ }
1677
+ setMap(map, property) {
1678
+ if (this.material) {
1679
+ const asset = AssetElement.get(map);
1680
+ if (asset) {
1681
+ if (asset.loaded) {
1682
+ this.material[property] = asset.resource;
1683
+ this.material[property].anisotropy = 4;
1684
+ }
1685
+ else {
1686
+ asset.once('load', () => {
1687
+ this.material[property] = asset.resource;
1688
+ this.material[property].anisotropy = 4;
1689
+ this.material.update();
1690
+ });
1691
+ }
1692
+ }
1693
+ }
1694
+ }
1695
+ set diffuse(value) {
1696
+ this._diffuse = value;
1697
+ if (this.material) {
1698
+ this.material.diffuse = value;
1699
+ }
1700
+ }
1701
+ get diffuse() {
1702
+ return this._diffuse;
1703
+ }
1704
+ set diffuseMap(value) {
1705
+ this._diffuseMap = value;
1706
+ this.setMap(value, 'diffuseMap');
1707
+ }
1708
+ get diffuseMap() {
1709
+ return this._diffuseMap;
1710
+ }
1711
+ set metalnessMap(value) {
1712
+ this._metalnessMap = value;
1713
+ this.setMap(value, 'metalnessMap');
1714
+ }
1715
+ get metalnessMap() {
1716
+ return this._metalnessMap;
1717
+ }
1718
+ set normalMap(value) {
1719
+ this._normalMap = value;
1720
+ this.setMap(value, 'normalMap');
1721
+ }
1722
+ get normalMap() {
1723
+ return this._normalMap;
1724
+ }
1725
+ set roughnessMap(value) {
1726
+ this._roughnessMap = value;
1727
+ this.setMap(value, 'glossMap');
1728
+ }
1729
+ get roughnessMap() {
1730
+ return this._roughnessMap;
1731
+ }
1732
+ static get(id) {
1733
+ const materialElement = document.querySelector(`pc-material[id="${id}"]`);
1734
+ return materialElement === null || materialElement === void 0 ? void 0 : materialElement.material;
1735
+ }
1736
+ static get observedAttributes() {
1737
+ return ['diffuse', 'diffuse-map', 'metalness-map', 'normal-map', 'roughness-map'];
1738
+ }
1739
+ attributeChangedCallback(name, _oldValue, newValue) {
1740
+ switch (name) {
1741
+ case 'diffuse':
1742
+ this.diffuse = parseColor(newValue);
1743
+ break;
1744
+ case 'diffuse-map':
1745
+ this.diffuseMap = newValue;
1746
+ break;
1747
+ case 'metalness-map':
1748
+ this.metalnessMap = newValue;
1749
+ break;
1750
+ case 'normal-map':
1751
+ this.normalMap = newValue;
1752
+ break;
1753
+ case 'roughness-map':
1754
+ this.roughnessMap = newValue;
1755
+ break;
1756
+ }
1757
+ }
1758
+ }
1759
+ customElements.define('pc-material', MaterialElement);
1760
+
1376
1761
  /**
1377
1762
  * Represents a render component in the PlayCanvas engine.
1378
1763
  *
@@ -1381,9 +1766,14 @@ customElements.define('pc-light', LightComponentElement);
1381
1766
  class RenderComponentElement extends ComponentElement {
1382
1767
  constructor() {
1383
1768
  super('render');
1384
- this._type = 'asset';
1385
1769
  this._castShadows = true;
1770
+ this._material = '';
1386
1771
  this._receiveShadows = true;
1772
+ this._type = 'asset';
1773
+ }
1774
+ async connectedCallback() {
1775
+ await super.connectedCallback();
1776
+ this.material = this._material;
1387
1777
  }
1388
1778
  getInitialComponentData() {
1389
1779
  return {
@@ -1433,6 +1823,23 @@ class RenderComponentElement extends ComponentElement {
1433
1823
  get castShadows() {
1434
1824
  return this._castShadows;
1435
1825
  }
1826
+ /**
1827
+ * Sets the material of the render component.
1828
+ * @param value - The id of the material asset to use.
1829
+ */
1830
+ set material(value) {
1831
+ this._material = value;
1832
+ if (this.component) {
1833
+ this.component.material = MaterialElement.get(value);
1834
+ }
1835
+ }
1836
+ /**
1837
+ * Gets the id of the material asset used by the render component.
1838
+ * @returns The id of the material asset.
1839
+ */
1840
+ get material() {
1841
+ return this._material;
1842
+ }
1436
1843
  /**
1437
1844
  * Sets the receive shadows flag of the render component.
1438
1845
  * @param value - The receive shadows flag.
@@ -1451,20 +1858,23 @@ class RenderComponentElement extends ComponentElement {
1451
1858
  return this._receiveShadows;
1452
1859
  }
1453
1860
  static get observedAttributes() {
1454
- return [...super.observedAttributes, 'cast-shadows', 'receive-shadows', 'type'];
1861
+ return [...super.observedAttributes, 'cast-shadows', 'material', 'receive-shadows', 'type'];
1455
1862
  }
1456
1863
  attributeChangedCallback(name, _oldValue, newValue) {
1457
1864
  super.attributeChangedCallback(name, _oldValue, newValue);
1458
1865
  switch (name) {
1459
- case 'type':
1460
- this.type = newValue;
1461
- break;
1462
1866
  case 'cast-shadows':
1463
1867
  this.castShadows = newValue !== 'false';
1464
1868
  break;
1869
+ case 'material':
1870
+ this.material = newValue;
1871
+ break;
1465
1872
  case 'receive-shadows':
1466
1873
  this.receiveShadows = newValue !== 'false';
1467
1874
  break;
1875
+ case 'type':
1876
+ this.type = newValue;
1877
+ break;
1468
1878
  }
1469
1879
  }
1470
1880
  }
@@ -1657,6 +2067,129 @@ class RigidBodyComponentElement extends ComponentElement {
1657
2067
  }
1658
2068
  customElements.define('pc-rigidbody', RigidBodyComponentElement);
1659
2069
 
2070
+ /**
2071
+ * Represents a screen component in the PlayCanvas engine.
2072
+ *
2073
+ * @category Components
2074
+ */
2075
+ class ScreenComponentElement extends ComponentElement {
2076
+ constructor() {
2077
+ super('screen');
2078
+ this._screenSpace = false;
2079
+ this._resolution = new playcanvas.Vec2(640, 320);
2080
+ this._referenceResolution = new playcanvas.Vec2(640, 320);
2081
+ this._priority = 0;
2082
+ this._blend = false;
2083
+ this._scaleBlend = 0.5;
2084
+ }
2085
+ getInitialComponentData() {
2086
+ return {
2087
+ priority: this._priority,
2088
+ referenceResolution: this._referenceResolution,
2089
+ resolution: this._resolution,
2090
+ scaleBlend: this._scaleBlend,
2091
+ scaleMode: this._blend ? playcanvas.SCALEMODE_BLEND : playcanvas.SCALEMODE_NONE,
2092
+ screenSpace: this._screenSpace
2093
+ };
2094
+ }
2095
+ /**
2096
+ * Gets the screen component.
2097
+ * @returns The screen component.
2098
+ */
2099
+ get component() {
2100
+ return super.component;
2101
+ }
2102
+ set priority(value) {
2103
+ this._priority = value;
2104
+ if (this.component) {
2105
+ this.component.priority = this._priority;
2106
+ }
2107
+ }
2108
+ get priority() {
2109
+ return this._priority;
2110
+ }
2111
+ set referenceResolution(value) {
2112
+ this._referenceResolution = value;
2113
+ if (this.component) {
2114
+ this.component.referenceResolution = this._referenceResolution;
2115
+ }
2116
+ }
2117
+ get referenceResolution() {
2118
+ return this._referenceResolution;
2119
+ }
2120
+ set resolution(value) {
2121
+ this._resolution = value;
2122
+ if (this.component) {
2123
+ this.component.resolution = this._resolution;
2124
+ }
2125
+ }
2126
+ get resolution() {
2127
+ return this._resolution;
2128
+ }
2129
+ set scaleBlend(value) {
2130
+ this._scaleBlend = value;
2131
+ if (this.component) {
2132
+ this.component.scaleBlend = this._scaleBlend;
2133
+ }
2134
+ }
2135
+ get scaleBlend() {
2136
+ return this._scaleBlend;
2137
+ }
2138
+ set blend(value) {
2139
+ this._blend = value;
2140
+ if (this.component) {
2141
+ this.component.scaleMode = this._blend ? playcanvas.SCALEMODE_BLEND : playcanvas.SCALEMODE_NONE;
2142
+ }
2143
+ }
2144
+ get blend() {
2145
+ return this._blend;
2146
+ }
2147
+ set screenSpace(value) {
2148
+ this._screenSpace = value;
2149
+ if (this.component) {
2150
+ this.component.screenSpace = this._screenSpace;
2151
+ }
2152
+ }
2153
+ get screenSpace() {
2154
+ return this._screenSpace;
2155
+ }
2156
+ static get observedAttributes() {
2157
+ return [
2158
+ ...super.observedAttributes,
2159
+ 'blend',
2160
+ 'screen-space',
2161
+ 'resolution',
2162
+ 'reference-resolution',
2163
+ 'priority',
2164
+ 'scale-blend'
2165
+ ];
2166
+ }
2167
+ attributeChangedCallback(name, _oldValue, newValue) {
2168
+ super.attributeChangedCallback(name, _oldValue, newValue);
2169
+ switch (name) {
2170
+ case 'priority':
2171
+ this.priority = parseInt(newValue, 10);
2172
+ break;
2173
+ case 'reference-resolution':
2174
+ this.referenceResolution = parseVec2(newValue);
2175
+ break;
2176
+ case 'resolution':
2177
+ this.resolution = parseVec2(newValue);
2178
+ break;
2179
+ case 'scale-blend':
2180
+ this.scaleBlend = parseFloat(newValue);
2181
+ break;
2182
+ case 'blend':
2183
+ this.blend = this.hasAttribute('blend');
2184
+ break;
2185
+ case 'screen-space':
2186
+ this.screenSpace = this.hasAttribute('screen-space');
2187
+ break;
2188
+ }
2189
+ }
2190
+ }
2191
+ customElements.define('pc-screen', ScreenComponentElement);
2192
+
1660
2193
  /**
1661
2194
  * Represents a script component in the PlayCanvas engine.
1662
2195
  *
@@ -1962,10 +2495,6 @@ class SoundSlotElement extends HTMLElement {
1962
2495
  */
1963
2496
  this.soundSlot = null;
1964
2497
  }
1965
- getAsset() {
1966
- const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
1967
- return assetElement.asset;
1968
- }
1969
2498
  async connectedCallback() {
1970
2499
  const appElement = this.closest('pc-app');
1971
2500
  if (!appElement) {
@@ -2007,7 +2536,7 @@ class SoundSlotElement extends HTMLElement {
2007
2536
  var _a;
2008
2537
  this._asset = value;
2009
2538
  if (this.soundSlot) {
2010
- const id = (_a = this.getAsset()) === null || _a === void 0 ? void 0 : _a.id;
2539
+ const id = (_a = AssetElement.get(value)) === null || _a === void 0 ? void 0 : _a.id;
2011
2540
  if (id) {
2012
2541
  this.soundSlot.asset = id;
2013
2542
  }
@@ -2211,12 +2740,8 @@ class ModelElement extends HTMLElement {
2211
2740
  this.asset = asset;
2212
2741
  }
2213
2742
  }
2214
- getAsset() {
2215
- const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
2216
- return assetElement.asset;
2217
- }
2218
2743
  _loadModel() {
2219
- const asset = this.getAsset();
2744
+ const asset = AssetElement.get(this._asset);
2220
2745
  if (!asset) {
2221
2746
  return;
2222
2747
  }
@@ -2444,10 +2969,6 @@ class SkyElement extends HTMLElement {
2444
2969
  this.asset = this.getAttribute('asset') || '';
2445
2970
  this.solidColor = this.hasAttribute('solid-color');
2446
2971
  }
2447
- getAsset() {
2448
- const assetElement = document.querySelector(`pc-asset[id="${this._asset}"]`);
2449
- return assetElement.asset;
2450
- }
2451
2972
  getScene() {
2452
2973
  const appElement = this.closest('pc-app');
2453
2974
  if (!appElement) {
@@ -2463,7 +2984,7 @@ class SkyElement extends HTMLElement {
2463
2984
  this._asset = value;
2464
2985
  const scene = this.getScene();
2465
2986
  if (scene) {
2466
- const asset = this.getAsset();
2987
+ const asset = AssetElement.get(value);
2467
2988
  if (asset) {
2468
2989
  if (asset.resource) {
2469
2990
  scene.envAtlas = asset.resource;
@@ -2557,11 +3078,13 @@ exports.EntityElement = EntityElement;
2557
3078
  exports.GSplatComponentElement = GSplatComponentElement;
2558
3079
  exports.LightComponentElement = LightComponentElement;
2559
3080
  exports.ListenerComponentElement = ListenerComponentElement;
3081
+ exports.MaterialElement = MaterialElement;
2560
3082
  exports.ModelElement = ModelElement;
2561
3083
  exports.ModuleElement = ModuleElement;
2562
3084
  exports.RenderComponentElement = RenderComponentElement;
2563
3085
  exports.RigidBodyComponentElement = RigidBodyComponentElement;
2564
3086
  exports.SceneElement = SceneElement;
3087
+ exports.ScreenComponentElement = ScreenComponentElement;
2565
3088
  exports.ScriptComponentElement = ScriptComponentElement;
2566
3089
  exports.ScriptElement = ScriptElement;
2567
3090
  exports.SkyElement = SkyElement;