@playcanvas/web-components 0.1.6 → 0.1.8

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { basisInitialize, WasmModule, Application, Mouse, Keyboard, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO, Vec3, Vec4, Color, Quat, Vec2, Entity, Asset, XRTYPE_VR, PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE, StandardMaterial, SCALEMODE_BLEND, SCALEMODE_NONE, EnvLighting, LAYERID_SKYBOX } from 'playcanvas';
1
+ import { basisInitialize, WasmModule, Application, Keyboard, Mouse, FILLMODE_FILL_WINDOW, RESOLUTION_AUTO, Color, Quat, Vec2, Vec3, Vec4, Entity, Asset, XRTYPE_VR, PROJECTION_ORTHOGRAPHIC, PROJECTION_PERSPECTIVE, StandardMaterial, SCALEMODE_BLEND, SCALEMODE_NONE, EnvLighting, LAYERID_SKYBOX } from 'playcanvas';
2
2
 
3
3
  /**
4
4
  * Base class for all PlayCanvas web components that initialize asynchronously.
@@ -257,6 +257,157 @@ class AppElement extends AsyncElement {
257
257
  }
258
258
  customElements.define('pc-app', AppElement);
259
259
 
260
+ const CSS_COLORS = {
261
+ aliceblue: '#f0f8ff',
262
+ antiquewhite: '#faebd7',
263
+ aqua: '#00ffff',
264
+ aquamarine: '#7fffd4',
265
+ azure: '#f0ffff',
266
+ beige: '#f5f5dc',
267
+ bisque: '#ffe4c4',
268
+ black: '#000000',
269
+ blanchedalmond: '#ffebcd',
270
+ blue: '#0000ff',
271
+ blueviolet: '#8a2be2',
272
+ brown: '#a52a2a',
273
+ burlywood: '#deb887',
274
+ cadetblue: '#5f9ea0',
275
+ chartreuse: '#7fff00',
276
+ chocolate: '#d2691e',
277
+ coral: '#ff7f50',
278
+ cornflowerblue: '#6495ed',
279
+ cornsilk: '#fff8dc',
280
+ crimson: '#dc143c',
281
+ cyan: '#00ffff',
282
+ darkblue: '#00008b',
283
+ darkcyan: '#008b8b',
284
+ darkgoldenrod: '#b8860b',
285
+ darkgray: '#a9a9a9',
286
+ darkgreen: '#006400',
287
+ darkgrey: '#a9a9a9',
288
+ darkkhaki: '#bdb76b',
289
+ darkmagenta: '#8b008b',
290
+ darkolivegreen: '#556b2f',
291
+ darkorange: '#ff8c00',
292
+ darkorchid: '#9932cc',
293
+ darkred: '#8b0000',
294
+ darksalmon: '#e9967a',
295
+ darkseagreen: '#8fbc8f',
296
+ darkslateblue: '#483d8b',
297
+ darkslategray: '#2f4f4f',
298
+ darkslategrey: '#2f4f4f',
299
+ darkturquoise: '#00ced1',
300
+ darkviolet: '#9400d3',
301
+ deeppink: '#ff1493',
302
+ deepskyblue: '#00bfff',
303
+ dimgray: '#696969',
304
+ dimgrey: '#696969',
305
+ dodgerblue: '#1e90ff',
306
+ firebrick: '#b22222',
307
+ floralwhite: '#fffaf0',
308
+ forestgreen: '#228b22',
309
+ fuchsia: '#ff00ff',
310
+ gainsboro: '#dcdcdc',
311
+ ghostwhite: '#f8f8ff',
312
+ gold: '#ffd700',
313
+ goldenrod: '#daa520',
314
+ gray: '#808080',
315
+ green: '#008000',
316
+ greenyellow: '#adff2f',
317
+ grey: '#808080',
318
+ honeydew: '#f0fff0',
319
+ hotpink: '#ff69b4',
320
+ indianred: '#cd5c5c',
321
+ indigo: '#4b0082',
322
+ ivory: '#fffff0',
323
+ khaki: '#f0e68c',
324
+ lavender: '#e6e6fa',
325
+ lavenderblush: '#fff0f5',
326
+ lawngreen: '#7cfc00',
327
+ lemonchiffon: '#fffacd',
328
+ lightblue: '#add8e6',
329
+ lightcoral: '#f08080',
330
+ lightcyan: '#e0ffff',
331
+ lightgoldenrodyellow: '#fafad2',
332
+ lightgray: '#d3d3d3',
333
+ lightgreen: '#90ee90',
334
+ lightgrey: '#d3d3d3',
335
+ lightpink: '#ffb6c1',
336
+ lightsalmon: '#ffa07a',
337
+ lightseagreen: '#20b2aa',
338
+ lightskyblue: '#87cefa',
339
+ lightslategray: '#778899',
340
+ lightslategrey: '#778899',
341
+ lightsteelblue: '#b0c4de',
342
+ lightyellow: '#ffffe0',
343
+ lime: '#00ff00',
344
+ limegreen: '#32cd32',
345
+ linen: '#faf0e6',
346
+ magenta: '#ff00ff',
347
+ maroon: '#800000',
348
+ mediumaquamarine: '#66cdaa',
349
+ mediumblue: '#0000cd',
350
+ mediumorchid: '#ba55d3',
351
+ mediumpurple: '#9370db',
352
+ mediumseagreen: '#3cb371',
353
+ mediumslateblue: '#7b68ee',
354
+ mediumspringgreen: '#00fa9a',
355
+ mediumturquoise: '#48d1cc',
356
+ mediumvioletred: '#c71585',
357
+ midnightblue: '#191970',
358
+ mintcream: '#f5fffa',
359
+ mistyrose: '#ffe4e1',
360
+ moccasin: '#ffe4b5',
361
+ navajowhite: '#ffdead',
362
+ navy: '#000080',
363
+ oldlace: '#fdf5e6',
364
+ olive: '#808000',
365
+ olivedrab: '#6b8e23',
366
+ orange: '#ffa500',
367
+ orangered: '#ff4500',
368
+ orchid: '#da70d6',
369
+ palegoldenrod: '#eee8aa',
370
+ palegreen: '#98fb98',
371
+ paleturquoise: '#afeeee',
372
+ palevioletred: '#db7093',
373
+ papayawhip: '#ffefd5',
374
+ peachpuff: '#ffdab9',
375
+ peru: '#cd853f',
376
+ pink: '#ffc0cb',
377
+ plum: '#dda0dd',
378
+ powderblue: '#b0e0e6',
379
+ purple: '#800080',
380
+ rebeccapurple: '#663399',
381
+ red: '#ff0000',
382
+ rosybrown: '#bc8f8f',
383
+ royalblue: '#4169e1',
384
+ saddlebrown: '#8b4513',
385
+ salmon: '#fa8072',
386
+ sandybrown: '#f4a460',
387
+ seagreen: '#2e8b57',
388
+ seashell: '#fff5ee',
389
+ sienna: '#a0522d',
390
+ silver: '#c0c0c0',
391
+ skyblue: '#87ceeb',
392
+ slateblue: '#6a5acd',
393
+ slategray: '#708090',
394
+ slategrey: '#708090',
395
+ snow: '#fffafa',
396
+ springgreen: '#00ff7f',
397
+ steelblue: '#4682b4',
398
+ tan: '#d2b48c',
399
+ teal: '#008080',
400
+ thistle: '#d8bfd8',
401
+ tomato: '#ff6347',
402
+ turquoise: '#40e0d0',
403
+ violet: '#ee82ee',
404
+ wheat: '#f5deb3',
405
+ white: '#ffffff',
406
+ whitesmoke: '#f5f5f5',
407
+ yellow: '#ffff00',
408
+ yellowgreen: '#9acd32'
409
+ };
410
+
260
411
  /**
261
412
  * Parse a color string into a Color object. String can be in the format of '#rgb', '#rgba',
262
413
  * '#rrggbb', '#rrggbbaa', or a string of 3 or 4 comma-delimited numbers.
@@ -265,10 +416,15 @@ customElements.define('pc-app', AppElement);
265
416
  * @returns The parsed Color object.
266
417
  */
267
418
  const parseColor = (value) => {
419
+ // Check if it's a CSS color name first
420
+ const hexColor = CSS_COLORS[value.toLowerCase()];
421
+ if (hexColor) {
422
+ return new Color().fromString(hexColor);
423
+ }
268
424
  if (value.startsWith('#')) {
269
425
  return new Color().fromString(value);
270
426
  }
271
- const components = value.split(',').map(Number);
427
+ const components = value.split(' ').map(Number);
272
428
  return new Color(components);
273
429
  };
274
430
  /**
@@ -278,7 +434,7 @@ const parseColor = (value) => {
278
434
  * @returns The parsed Quat object.
279
435
  */
280
436
  const parseQuat = (value) => {
281
- const [x, y, z] = value.split(',').map(Number);
437
+ const [x, y, z] = value.split(' ').map(Number);
282
438
  const q = new Quat();
283
439
  q.setFromEulerAngles(x, y, z);
284
440
  return q;
@@ -290,7 +446,7 @@ const parseQuat = (value) => {
290
446
  * @returns The parsed Vec2 object.
291
447
  */
292
448
  const parseVec2 = (value) => {
293
- const components = value.split(',').map(Number);
449
+ const components = value.split(' ').map(Number);
294
450
  return new Vec2(components);
295
451
  };
296
452
  /**
@@ -300,7 +456,7 @@ const parseVec2 = (value) => {
300
456
  * @returns The parsed Vec3 object.
301
457
  */
302
458
  const parseVec3 = (value) => {
303
- const components = value.split(',').map(Number);
459
+ const components = value.split(' ').map(Number);
304
460
  return new Vec3(components);
305
461
  };
306
462
  /**
@@ -310,7 +466,7 @@ const parseVec3 = (value) => {
310
466
  * @returns The parsed Vec4 object.
311
467
  */
312
468
  const parseVec4 = (value) => {
313
- const components = value.split(',').map(Number);
469
+ const components = value.split(' ').map(Number);
314
470
  return new Vec4(components);
315
471
  };
316
472
 
@@ -359,11 +515,14 @@ class EntityElement extends AsyncElement {
359
515
  // Create a new entity
360
516
  this.entity = new Entity(this._name, app);
361
517
  // Initialize from attributes
518
+ const enabledAttr = this.getAttribute('enabled');
362
519
  const nameAttr = this.getAttribute('name');
363
520
  const positionAttr = this.getAttribute('position');
364
521
  const rotationAttr = this.getAttribute('rotation');
365
522
  const scaleAttr = this.getAttribute('scale');
366
523
  const tagsAttr = this.getAttribute('tags');
524
+ if (enabledAttr)
525
+ this.enabled = enabledAttr !== 'false';
367
526
  if (nameAttr)
368
527
  this.name = nameAttr;
369
528
  if (positionAttr)
@@ -1535,6 +1694,7 @@ class LightComponentElement extends ComponentElement {
1535
1694
  this._range = 10;
1536
1695
  this._shadowBias = 0.2;
1537
1696
  this._shadowDistance = 16;
1697
+ this._shadowResolution = 1024;
1538
1698
  this._type = 'directional';
1539
1699
  }
1540
1700
  getInitialComponentData() {
@@ -1548,6 +1708,7 @@ class LightComponentElement extends ComponentElement {
1548
1708
  range: this._range,
1549
1709
  shadowBias: this._shadowBias,
1550
1710
  shadowDistance: this._shadowDistance,
1711
+ shadowResolution: this._shadowResolution,
1551
1712
  type: this._type
1552
1713
  };
1553
1714
  }
@@ -1711,6 +1872,23 @@ class LightComponentElement extends ComponentElement {
1711
1872
  get shadowDistance() {
1712
1873
  return this._shadowDistance;
1713
1874
  }
1875
+ /**
1876
+ * Sets the shadow resolution of the light.
1877
+ * @param value - The shadow resolution.
1878
+ */
1879
+ set shadowResolution(value) {
1880
+ this._shadowResolution = value;
1881
+ if (this.component) {
1882
+ this.component.shadowResolution = value;
1883
+ }
1884
+ }
1885
+ /**
1886
+ * Gets the shadow resolution of the light.
1887
+ * @returns The shadow resolution.
1888
+ */
1889
+ get shadowResolution() {
1890
+ return this._shadowResolution;
1891
+ }
1714
1892
  /**
1715
1893
  * Sets the type of the light.
1716
1894
  * @param value - The type.
@@ -1744,6 +1922,7 @@ class LightComponentElement extends ComponentElement {
1744
1922
  'range',
1745
1923
  'shadow-bias',
1746
1924
  'shadow-distance',
1925
+ 'shadow-resolution',
1747
1926
  'type'
1748
1927
  ];
1749
1928
  }
@@ -1777,6 +1956,9 @@ class LightComponentElement extends ComponentElement {
1777
1956
  case 'shadow-distance':
1778
1957
  this.shadowDistance = Number(newValue);
1779
1958
  break;
1959
+ case 'shadow-resolution':
1960
+ this.shadowResolution = Number(newValue);
1961
+ break;
1780
1962
  case 'type':
1781
1963
  this.type = newValue;
1782
1964
  break;
@@ -2360,23 +2542,47 @@ class ScriptComponentElement extends ComponentElement {
2360
2542
  }
2361
2543
  applyAttributes(script, attributes) {
2362
2544
  try {
2363
- // Parse the attributes string into an object and set them on the script
2364
2545
  const attributesObject = attributes ? JSON.parse(attributes) : {};
2365
- for (const key in attributesObject) {
2366
- const value = attributesObject[key];
2367
- if (Array.isArray(value) && script[key] instanceof Vec2) {
2368
- script[key] = tmpV2.set(value[0], value[1]);
2369
- continue;
2546
+ const applyValue = (target, key, value) => {
2547
+ // Handle asset references
2548
+ if (typeof value === 'string' && value.startsWith('asset:')) {
2549
+ const assetId = value.slice(6);
2550
+ const assetElement = document.querySelector(`pc-asset#${assetId}`);
2551
+ if (assetElement) {
2552
+ target[key] = assetElement.asset;
2553
+ return;
2554
+ }
2555
+ }
2556
+ // Handle vectors
2557
+ if (Array.isArray(value)) {
2558
+ if (target[key] instanceof Vec2) {
2559
+ target[key] = tmpV2.set(value[0], value[1]);
2560
+ return;
2561
+ }
2562
+ if (target[key] instanceof Vec3) {
2563
+ target[key] = tmpV3.set(value[0], value[1], value[2]);
2564
+ return;
2565
+ }
2566
+ if (target[key] instanceof Vec4) {
2567
+ target[key] = tmpV4.set(value[0], value[1], value[2], value[3]);
2568
+ return;
2569
+ }
2370
2570
  }
2371
- if (Array.isArray(value) && script[key] instanceof Vec3) {
2372
- script[key] = tmpV3.set(value[0], value[1], value[2]);
2373
- continue;
2571
+ // Handle nested objects
2572
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
2573
+ if (!target[key] || typeof target[key] !== 'object') {
2574
+ target[key] = {};
2575
+ }
2576
+ for (const nestedKey in value) {
2577
+ applyValue(target[key], nestedKey, value[nestedKey]);
2578
+ }
2374
2579
  }
2375
- if (Array.isArray(value) && script[key] instanceof Vec4) {
2376
- script[key] = tmpV4.set(value[0], value[1], value[2], value[3]);
2377
- continue;
2580
+ else {
2581
+ target[key] = value;
2378
2582
  }
2379
- script[key] = value;
2583
+ };
2584
+ for (const key in attributesObject) {
2585
+ applyValue(script, key, attributesObject[key]);
2380
2586
  }
2381
2587
  }
2382
2588
  catch (error) {
@@ -2975,48 +3181,71 @@ class ModelElement extends AsyncElement {
2975
3181
  constructor() {
2976
3182
  super(...arguments);
2977
3183
  this._asset = '';
3184
+ this._entity = null;
2978
3185
  }
2979
- async connectedCallback() {
2980
- var _a;
2981
- await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
2982
- const asset = this.getAttribute('asset');
2983
- if (asset) {
2984
- this.asset = asset;
2985
- }
3186
+ connectedCallback() {
3187
+ this._loadModel();
2986
3188
  this._onReady();
2987
3189
  }
2988
- _loadModel() {
2989
- const asset = AssetElement.get(this._asset);
2990
- if (!asset) {
2991
- return;
2992
- }
2993
- const entity = asset.resource.instantiateRenderEntity();
2994
- if (asset.resource.animations.length > 0) {
2995
- entity.addComponent('anim');
2996
- entity.anim.assignAnimation('animation', asset.resource.animations[0].resource);
3190
+ disconnectedCallback() {
3191
+ this._unloadModel();
3192
+ }
3193
+ _instantiate(container) {
3194
+ this._entity = container.instantiateRenderEntity();
3195
+ // @ts-ignore
3196
+ if (container.animations.length > 0) {
3197
+ this._entity.addComponent('anim');
3198
+ // @ts-ignore
3199
+ this._entity.anim.assignAnimation('animation', container.animations[0].resource);
2997
3200
  }
2998
3201
  const parentEntityElement = this.closestEntity;
2999
3202
  if (parentEntityElement) {
3000
3203
  parentEntityElement.ready().then(() => {
3001
- parentEntityElement.entity.addChild(entity);
3204
+ parentEntityElement.entity.addChild(this._entity);
3002
3205
  });
3003
3206
  }
3004
3207
  else {
3005
3208
  const appElement = this.closestApp;
3006
3209
  if (appElement) {
3007
3210
  appElement.ready().then(() => {
3008
- appElement.app.root.addChild(entity);
3211
+ appElement.app.root.addChild(this._entity);
3009
3212
  });
3010
3213
  }
3011
3214
  }
3012
3215
  }
3216
+ async _loadModel() {
3217
+ var _a;
3218
+ this._unloadModel();
3219
+ const appElement = await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
3220
+ const app = appElement === null || appElement === void 0 ? void 0 : appElement.app;
3221
+ const asset = AssetElement.get(this._asset);
3222
+ if (!asset) {
3223
+ return;
3224
+ }
3225
+ if (asset.loaded) {
3226
+ this._instantiate(asset.resource);
3227
+ }
3228
+ else {
3229
+ asset.once('load', () => {
3230
+ this._instantiate(asset.resource);
3231
+ });
3232
+ app.assets.load(asset);
3233
+ }
3234
+ }
3235
+ _unloadModel() {
3236
+ var _a;
3237
+ (_a = this._entity) === null || _a === void 0 ? void 0 : _a.destroy();
3238
+ this._entity = null;
3239
+ }
3013
3240
  /**
3014
3241
  * Sets the asset ID of the model.
3015
3242
  * @param value - The asset ID.
3016
3243
  */
3017
3244
  set asset(value) {
3018
3245
  this._asset = value;
3019
- this._loadModel();
3246
+ if (this.isConnected) {
3247
+ this._loadModel();
3248
+ }
3020
3249
  }
3021
3250
  /**
3022
3251
  * Gets the source URL of the model.
@@ -3208,48 +3437,77 @@ class SkyElement extends AsyncElement {
3208
3437
  this._intensity = 1;
3209
3438
  this._rotation = new Vec3();
3210
3439
  this._level = 0;
3440
+ this._lighting = false;
3211
3441
  this._scale = new Vec3(100, 100, 100);
3212
3442
  this._type = 'infinite';
3443
+ this._scene = null;
3213
3444
  }
3214
- async connectedCallback() {
3215
- var _a;
3216
- await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
3217
- this.asset = this.getAttribute('asset') || '';
3445
+ connectedCallback() {
3446
+ this._loadSkybox();
3218
3447
  this._onReady();
3219
3448
  }
3220
- getScene() {
3221
- const app = this.closestApp.app;
3449
+ disconnectedCallback() {
3450
+ this._unloadSkybox();
3451
+ }
3452
+ _generateSkybox(asset) {
3453
+ if (!this._scene)
3454
+ return;
3455
+ const source = asset.resource;
3456
+ const skybox = EnvLighting.generateSkyboxCubemap(source);
3457
+ skybox.anisotropy = 4;
3458
+ this._scene.skybox = skybox;
3459
+ if (this._lighting) {
3460
+ const lighting = EnvLighting.generateLightingSource(source);
3461
+ const envAtlas = EnvLighting.generateAtlas(lighting);
3462
+ this._scene.envAtlas = envAtlas;
3463
+ }
3464
+ const layer = this._scene.layers.getLayerById(LAYERID_SKYBOX);
3465
+ if (layer) {
3466
+ layer.enabled = this._type !== 'none';
3467
+ }
3468
+ this._scene.sky.type = this._type;
3469
+ this._scene.sky.node.setLocalScale(this._scale);
3470
+ this._scene.sky.center = this._center;
3471
+ this._scene.skyboxIntensity = this._intensity;
3472
+ }
3473
+ async _loadSkybox() {
3474
+ var _a;
3475
+ const appElement = await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
3476
+ const app = appElement === null || appElement === void 0 ? void 0 : appElement.app;
3222
3477
  if (!app) {
3223
3478
  return;
3224
3479
  }
3225
- return app.scene;
3226
- }
3227
- initSkybox(source) {
3228
- source.anisotropy = 4;
3229
- const skybox = EnvLighting.generateSkyboxCubemap(source);
3230
- const lighting = EnvLighting.generateLightingSource(source);
3231
- const envAtlas = EnvLighting.generateAtlas(lighting);
3232
- const app = this.closestApp.app;
3233
- if (app) {
3234
- app.scene.envAtlas = envAtlas;
3235
- app.scene.skybox = skybox;
3236
- const layer = app.scene.layers.getLayerById(LAYERID_SKYBOX);
3237
- if (layer) {
3238
- layer.enabled = this._type !== 'none';
3239
- }
3240
- app.scene.sky.type = this._type;
3241
- app.scene.sky.node.setLocalScale(this._scale);
3242
- app.scene.sky.center = this._center;
3480
+ const asset = AssetElement.get(this._asset);
3481
+ if (!asset) {
3482
+ return;
3483
+ }
3484
+ this._scene = app.scene;
3485
+ if (asset.loaded) {
3486
+ this._generateSkybox(asset);
3487
+ }
3488
+ else {
3489
+ asset.once('load', () => {
3490
+ this._generateSkybox(asset);
3491
+ });
3492
+ app.assets.load(asset);
3243
3493
  }
3244
3494
  }
3495
+ _unloadSkybox() {
3496
+ var _a, _b;
3497
+ if (!this._scene)
3498
+ return;
3499
+ (_a = this._scene.skybox) === null || _a === void 0 ? void 0 : _a.destroy();
3500
+ // @ts-ignore
3501
+ this._scene.skybox = null;
3502
+ (_b = this._scene.envAtlas) === null || _b === void 0 ? void 0 : _b.destroy();
3503
+ // @ts-ignore
3504
+ this._scene.envAtlas = null;
3505
+ this._scene = null;
3506
+ }
3245
3507
  set asset(value) {
3246
3508
  this._asset = value;
3247
- const scene = this.getScene();
3248
- if (scene) {
3249
- const asset = AssetElement.get(value);
3250
- if (asset) {
3251
- this.initSkybox(asset.resource);
3252
- }
3509
+ if (this.isConnected) {
3510
+ this._loadSkybox();
3253
3511
  }
3254
3512
  }
3255
3513
  get asset() {
@@ -3257,9 +3515,8 @@ class SkyElement extends AsyncElement {
3257
3515
  }
3258
3516
  set center(value) {
3259
3517
  this._center = value;
3260
- const scene = this.getScene();
3261
- if (scene) {
3262
- scene.sky.center = this._center;
3518
+ if (this._scene) {
3519
+ this._scene.sky.center = this._center;
3263
3520
  }
3264
3521
  }
3265
3522
  get center() {
@@ -3267,19 +3524,32 @@ class SkyElement extends AsyncElement {
3267
3524
  }
3268
3525
  set intensity(value) {
3269
3526
  this._intensity = value;
3270
- const scene = this.getScene();
3271
- if (scene) {
3272
- scene.skyboxIntensity = this._intensity;
3527
+ if (this._scene) {
3528
+ this._scene.skyboxIntensity = this._intensity;
3273
3529
  }
3274
3530
  }
3275
3531
  get intensity() {
3276
3532
  return this._intensity;
3277
3533
  }
3534
+ set level(value) {
3535
+ this._level = value;
3536
+ if (this._scene) {
3537
+ this._scene.skyboxMip = this._level;
3538
+ }
3539
+ }
3540
+ get level() {
3541
+ return this._level;
3542
+ }
3543
+ set lighting(value) {
3544
+ this._lighting = value;
3545
+ }
3546
+ get lighting() {
3547
+ return this._lighting;
3548
+ }
3278
3549
  set rotation(value) {
3279
3550
  this._rotation = value;
3280
- const scene = this.getScene();
3281
- if (scene) {
3282
- scene.skyboxRotation = new Quat().setFromEulerAngles(value);
3551
+ if (this._scene) {
3552
+ this._scene.skyboxRotation = new Quat().setFromEulerAngles(value);
3283
3553
  }
3284
3554
  }
3285
3555
  get rotation() {
@@ -3287,30 +3557,18 @@ class SkyElement extends AsyncElement {
3287
3557
  }
3288
3558
  set scale(value) {
3289
3559
  this._scale = value;
3290
- const scene = this.getScene();
3291
- if (scene) {
3292
- scene.sky.node.setLocalScale(this._scale);
3560
+ if (this._scene) {
3561
+ this._scene.sky.node.setLocalScale(this._scale);
3293
3562
  }
3294
3563
  }
3295
3564
  get scale() {
3296
3565
  return this._scale;
3297
3566
  }
3298
- set level(value) {
3299
- this._level = value;
3300
- const scene = this.getScene();
3301
- if (scene) {
3302
- scene.skyboxMip = this._level;
3303
- }
3304
- }
3305
- get level() {
3306
- return this._level;
3307
- }
3308
3567
  set type(value) {
3309
3568
  this._type = value;
3310
- const scene = this.getScene();
3311
- if (scene) {
3312
- scene.sky.type = this._type;
3313
- const layer = scene.layers.getLayerById(LAYERID_SKYBOX);
3569
+ if (this._scene) {
3570
+ this._scene.sky.type = this._type;
3571
+ const layer = this._scene.layers.getLayerById(LAYERID_SKYBOX);
3314
3572
  if (layer) {
3315
3573
  layer.enabled = this._type !== 'none';
3316
3574
  }
@@ -3320,7 +3578,7 @@ class SkyElement extends AsyncElement {
3320
3578
  return this._type;
3321
3579
  }
3322
3580
  static get observedAttributes() {
3323
- return ['asset', 'center', 'intensity', 'level', 'rotation', 'scale', 'type'];
3581
+ return ['asset', 'center', 'intensity', 'level', 'lighting', 'rotation', 'scale', 'type'];
3324
3582
  }
3325
3583
  attributeChangedCallback(name, _oldValue, newValue) {
3326
3584
  switch (name) {
@@ -3333,12 +3591,15 @@ class SkyElement extends AsyncElement {
3333
3591
  case 'intensity':
3334
3592
  this.intensity = parseFloat(newValue);
3335
3593
  break;
3336
- case 'rotation':
3337
- this.rotation = parseVec3(newValue);
3338
- break;
3339
3594
  case 'level':
3340
3595
  this.level = parseInt(newValue, 10);
3341
3596
  break;
3597
+ case 'lighting':
3598
+ this.lighting = this.hasAttribute(name);
3599
+ break;
3600
+ case 'rotation':
3601
+ this.rotation = parseVec3(newValue);
3602
+ break;
3342
3603
  case 'scale':
3343
3604
  this.scale = parseVec3(newValue);
3344
3605
  break;