@playcanvas/web-components 0.1.5 → 0.1.7

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/src/sky.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EnvLighting, LAYERID_SKYBOX, Quat, Texture, Vec3 } from 'playcanvas';
1
+ import { Asset, EnvLighting, LAYERID_SKYBOX, Quat, Scene, Texture, Vec3 } from 'playcanvas';
2
2
 
3
3
  import { AssetElement } from './asset';
4
4
  import { AsyncElement } from './async-element';
@@ -18,56 +18,89 @@ class SkyElement extends AsyncElement {
18
18
 
19
19
  private _level = 0;
20
20
 
21
+ private _lighting = false;
22
+
21
23
  private _scale = new Vec3(100, 100, 100);
22
24
 
23
25
  private _type: 'box' | 'dome' | 'infinite' | 'none' = 'infinite';
24
26
 
25
- async connectedCallback() {
26
- await this.closestApp?.ready();
27
-
28
- this.asset = this.getAttribute('asset') || '';
27
+ private _scene: Scene | null = null;
29
28
 
29
+ connectedCallback() {
30
+ this._loadSkybox();
30
31
  this._onReady();
31
32
  }
32
33
 
33
- getScene() {
34
- const app = this.closestApp!.app;
35
- if (!app) {
36
- return;
37
- }
38
- return app.scene;
34
+ disconnectedCallback() {
35
+ this._unloadSkybox();
39
36
  }
40
37
 
41
- private initSkybox(source: Texture) {
38
+ private _generateSkybox(asset: Asset) {
39
+ if (!this._scene) return;
40
+
41
+ const source = asset.resource as Texture;
42
42
  source.anisotropy = 4;
43
43
 
44
44
  const skybox = EnvLighting.generateSkyboxCubemap(source);
45
- const lighting = EnvLighting.generateLightingSource(source);
46
- const envAtlas = EnvLighting.generateAtlas(lighting);
47
- const app = this.closestApp!.app;
48
- if (app) {
49
- app.scene.envAtlas = envAtlas;
50
- app.scene.skybox = skybox;
51
-
52
- const layer = app.scene.layers.getLayerById(LAYERID_SKYBOX);
53
- if (layer) {
54
- layer.enabled = this._type !== 'none';
55
- }
45
+ this._scene.skybox = skybox;
46
+
47
+ if (this._lighting) {
48
+ const lighting = EnvLighting.generateLightingSource(source);
49
+ const envAtlas = EnvLighting.generateAtlas(lighting);
50
+ this._scene.envAtlas = envAtlas;
51
+ }
56
52
 
57
- app.scene.sky.type = this._type;
58
- app.scene.sky.node.setLocalScale(this._scale);
59
- app.scene.sky.center = this._center;
53
+ const layer = this._scene.layers.getLayerById(LAYERID_SKYBOX);
54
+ if (layer) {
55
+ layer.enabled = this._type !== 'none';
60
56
  }
57
+
58
+ this._scene.sky.type = this._type;
59
+ this._scene.sky.node.setLocalScale(this._scale);
60
+ this._scene.sky.center = this._center;
61
+ }
62
+
63
+ private async _loadSkybox() {
64
+ const appElement = await this.closestApp?.ready();
65
+ const app = appElement?.app;
66
+ if (!app) {
67
+ return;
68
+ }
69
+
70
+ const asset = AssetElement.get(this._asset);
71
+ if (!asset) {
72
+ return;
73
+ }
74
+
75
+ this._scene = app.scene;
76
+
77
+ if (asset.loaded) {
78
+ this._generateSkybox(asset);
79
+ } else {
80
+ asset.once('load', () => {
81
+ this._generateSkybox(asset);
82
+ });
83
+ app.assets.load(asset);
84
+ }
85
+ }
86
+
87
+ private _unloadSkybox() {
88
+ if (!this._scene) return;
89
+
90
+ this._scene.skybox?.destroy();
91
+ // @ts-ignore
92
+ this._scene.skybox = null;
93
+ this._scene.envAtlas?.destroy();
94
+ // @ts-ignore
95
+ this._scene.envAtlas = null;
96
+
97
+ this._scene = null;
61
98
  }
62
99
 
63
100
  set asset(value: string) {
64
101
  this._asset = value;
65
- const scene = this.getScene();
66
- if (scene) {
67
- const asset = AssetElement.get(value);
68
- if (asset) {
69
- this.initSkybox(asset.resource);
70
- }
102
+ if (this.isConnected) {
103
+ this._loadSkybox();
71
104
  }
72
105
  }
73
106
 
@@ -77,9 +110,8 @@ class SkyElement extends AsyncElement {
77
110
 
78
111
  set center(value: Vec3) {
79
112
  this._center = value;
80
- const scene = this.getScene();
81
- if (scene) {
82
- scene.sky.center = this._center;
113
+ if (this._scene) {
114
+ this._scene.sky.center = this._center;
83
115
  }
84
116
  }
85
117
 
@@ -89,9 +121,8 @@ class SkyElement extends AsyncElement {
89
121
 
90
122
  set intensity(value: number) {
91
123
  this._intensity = value;
92
- const scene = this.getScene();
93
- if (scene) {
94
- scene.skyboxIntensity = this._intensity;
124
+ if (this._scene) {
125
+ this._scene.skyboxIntensity = this._intensity;
95
126
  }
96
127
  }
97
128
 
@@ -99,11 +130,29 @@ class SkyElement extends AsyncElement {
99
130
  return this._intensity;
100
131
  }
101
132
 
133
+ set level(value: number) {
134
+ this._level = value;
135
+ if (this._scene) {
136
+ this._scene.skyboxMip = this._level;
137
+ }
138
+ }
139
+
140
+ get level() {
141
+ return this._level;
142
+ }
143
+
144
+ set lighting(value: boolean) {
145
+ this._lighting = value;
146
+ }
147
+
148
+ get lighting() {
149
+ return this._lighting;
150
+ }
151
+
102
152
  set rotation(value: Vec3) {
103
153
  this._rotation = value;
104
- const scene = this.getScene();
105
- if (scene) {
106
- scene.skyboxRotation = new Quat().setFromEulerAngles(value);
154
+ if (this._scene) {
155
+ this._scene.skyboxRotation = new Quat().setFromEulerAngles(value);
107
156
  }
108
157
  }
109
158
 
@@ -113,9 +162,8 @@ class SkyElement extends AsyncElement {
113
162
 
114
163
  set scale(value: Vec3) {
115
164
  this._scale = value;
116
- const scene = this.getScene();
117
- if (scene) {
118
- scene.sky.node.setLocalScale(this._scale);
165
+ if (this._scene) {
166
+ this._scene.sky.node.setLocalScale(this._scale);
119
167
  }
120
168
  }
121
169
 
@@ -123,24 +171,11 @@ class SkyElement extends AsyncElement {
123
171
  return this._scale;
124
172
  }
125
173
 
126
- set level(value: number) {
127
- this._level = value;
128
- const scene = this.getScene();
129
- if (scene) {
130
- scene.skyboxMip = this._level;
131
- }
132
- }
133
-
134
- get level() {
135
- return this._level;
136
- }
137
-
138
174
  set type(value: 'box' | 'dome' | 'infinite' | 'none') {
139
175
  this._type = value;
140
- const scene = this.getScene();
141
- if (scene) {
142
- scene.sky.type = this._type;
143
- const layer = scene.layers.getLayerById(LAYERID_SKYBOX);
176
+ if (this._scene) {
177
+ this._scene.sky.type = this._type;
178
+ const layer = this._scene.layers.getLayerById(LAYERID_SKYBOX);
144
179
  if (layer) {
145
180
  layer.enabled = this._type !== 'none';
146
181
  }
@@ -152,7 +187,7 @@ class SkyElement extends AsyncElement {
152
187
  }
153
188
 
154
189
  static get observedAttributes() {
155
- return ['asset', 'center', 'intensity', 'level', 'rotation', 'scale', 'type'];
190
+ return ['asset', 'center', 'intensity', 'level', 'lighting', 'rotation', 'scale', 'type'];
156
191
  }
157
192
 
158
193
  attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
@@ -166,12 +201,15 @@ class SkyElement extends AsyncElement {
166
201
  case 'intensity':
167
202
  this.intensity = parseFloat(newValue);
168
203
  break;
169
- case 'rotation':
170
- this.rotation = parseVec3(newValue);
171
- break;
172
204
  case 'level':
173
205
  this.level = parseInt(newValue, 10);
174
206
  break;
207
+ case 'lighting':
208
+ this.lighting = this.hasAttribute(name);
209
+ break;
210
+ case 'rotation':
211
+ this.rotation = parseVec3(newValue);
212
+ break;
175
213
  case 'scale':
176
214
  this.scale = parseVec3(newValue);
177
215
  break;
package/src/utils.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { Color, Quat, Vec2, Vec3, Vec4 } from 'playcanvas';
2
2
 
3
+ import { CSS_COLORS } from './colors';
4
+
3
5
  /**
4
6
  * Parse a color string into a Color object. String can be in the format of '#rgb', '#rgba',
5
7
  * '#rrggbb', '#rrggbbaa', or a string of 3 or 4 comma-delimited numbers.
@@ -8,11 +10,17 @@ import { Color, Quat, Vec2, Vec3, Vec4 } from 'playcanvas';
8
10
  * @returns The parsed Color object.
9
11
  */
10
12
  export const parseColor = (value: string): Color => {
13
+ // Check if it's a CSS color name first
14
+ const hexColor = CSS_COLORS[value.toLowerCase()];
15
+ if (hexColor) {
16
+ return new Color().fromString(hexColor);
17
+ }
18
+
11
19
  if (value.startsWith('#')) {
12
20
  return new Color().fromString(value);
13
21
  }
14
22
 
15
- const components = value.split(',').map(Number);
23
+ const components = value.split(' ').map(Number);
16
24
  return new Color(components);
17
25
  };
18
26
 
@@ -23,7 +31,7 @@ export const parseColor = (value: string): Color => {
23
31
  * @returns The parsed Quat object.
24
32
  */
25
33
  export const parseQuat = (value: string): Quat => {
26
- const [x, y, z] = value.split(',').map(Number);
34
+ const [x, y, z] = value.split(' ').map(Number);
27
35
  const q = new Quat();
28
36
  q.setFromEulerAngles(x, y, z);
29
37
  return q;
@@ -36,7 +44,7 @@ export const parseQuat = (value: string): Quat => {
36
44
  * @returns The parsed Vec2 object.
37
45
  */
38
46
  export const parseVec2 = (value: string): Vec2 => {
39
- const components = value.split(',').map(Number);
47
+ const components = value.split(' ').map(Number);
40
48
  return new Vec2(components);
41
49
  };
42
50
 
@@ -47,7 +55,7 @@ export const parseVec2 = (value: string): Vec2 => {
47
55
  * @returns The parsed Vec3 object.
48
56
  */
49
57
  export const parseVec3 = (value: string): Vec3 => {
50
- const components = value.split(',').map(Number);
58
+ const components = value.split(' ').map(Number);
51
59
  return new Vec3(components);
52
60
  };
53
61
 
@@ -58,6 +66,6 @@ export const parseVec3 = (value: string): Vec3 => {
58
66
  * @returns The parsed Vec4 object.
59
67
  */
60
68
  export const parseVec4 = (value: string): Vec4 => {
61
- const components = value.split(',').map(Number);
69
+ const components = value.split(' ').map(Number);
62
70
  return new Vec4(components);
63
71
  };