@playcanvas/web-components 0.1.6 → 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/dist/pwc.mjs CHANGED
@@ -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
 
@@ -2360,23 +2516,38 @@ class ScriptComponentElement extends ComponentElement {
2360
2516
  }
2361
2517
  applyAttributes(script, attributes) {
2362
2518
  try {
2363
- // Parse the attributes string into an object and set them on the script
2364
2519
  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;
2520
+ const applyValue = (target, key, value) => {
2521
+ // Handle vectors
2522
+ if (Array.isArray(value)) {
2523
+ if (target[key] instanceof Vec2) {
2524
+ target[key] = tmpV2.set(value[0], value[1]);
2525
+ return;
2526
+ }
2527
+ if (target[key] instanceof Vec3) {
2528
+ target[key] = tmpV3.set(value[0], value[1], value[2]);
2529
+ return;
2530
+ }
2531
+ if (target[key] instanceof Vec4) {
2532
+ target[key] = tmpV4.set(value[0], value[1], value[2], value[3]);
2533
+ return;
2534
+ }
2370
2535
  }
2371
- if (Array.isArray(value) && script[key] instanceof Vec3) {
2372
- script[key] = tmpV3.set(value[0], value[1], value[2]);
2373
- continue;
2536
+ // Handle nested objects
2537
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
2538
+ if (!target[key] || typeof target[key] !== 'object') {
2539
+ target[key] = {};
2540
+ }
2541
+ for (const nestedKey in value) {
2542
+ applyValue(target[key], nestedKey, value[nestedKey]);
2543
+ }
2374
2544
  }
2375
- if (Array.isArray(value) && script[key] instanceof Vec4) {
2376
- script[key] = tmpV4.set(value[0], value[1], value[2], value[3]);
2377
- continue;
2545
+ else {
2546
+ target[key] = value;
2378
2547
  }
2379
- script[key] = value;
2548
+ };
2549
+ for (const key in attributesObject) {
2550
+ applyValue(script, key, attributesObject[key]);
2380
2551
  }
2381
2552
  }
2382
2553
  catch (error) {
@@ -2975,48 +3146,71 @@ class ModelElement extends AsyncElement {
2975
3146
  constructor() {
2976
3147
  super(...arguments);
2977
3148
  this._asset = '';
3149
+ this._entity = null;
2978
3150
  }
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
- }
3151
+ connectedCallback() {
3152
+ this._loadModel();
2986
3153
  this._onReady();
2987
3154
  }
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);
3155
+ disconnectedCallback() {
3156
+ this._unloadModel();
3157
+ }
3158
+ _instantiate(container) {
3159
+ this._entity = container.instantiateRenderEntity();
3160
+ // @ts-ignore
3161
+ if (container.animations.length > 0) {
3162
+ this._entity.addComponent('anim');
3163
+ // @ts-ignore
3164
+ this._entity.anim.assignAnimation('animation', container.animations[0].resource);
2997
3165
  }
2998
3166
  const parentEntityElement = this.closestEntity;
2999
3167
  if (parentEntityElement) {
3000
3168
  parentEntityElement.ready().then(() => {
3001
- parentEntityElement.entity.addChild(entity);
3169
+ parentEntityElement.entity.addChild(this._entity);
3002
3170
  });
3003
3171
  }
3004
3172
  else {
3005
3173
  const appElement = this.closestApp;
3006
3174
  if (appElement) {
3007
3175
  appElement.ready().then(() => {
3008
- appElement.app.root.addChild(entity);
3176
+ appElement.app.root.addChild(this._entity);
3009
3177
  });
3010
3178
  }
3011
3179
  }
3012
3180
  }
3181
+ async _loadModel() {
3182
+ var _a;
3183
+ this._unloadModel();
3184
+ const appElement = await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
3185
+ const app = appElement === null || appElement === void 0 ? void 0 : appElement.app;
3186
+ const asset = AssetElement.get(this._asset);
3187
+ if (!asset) {
3188
+ return;
3189
+ }
3190
+ if (asset.loaded) {
3191
+ this._instantiate(asset.resource);
3192
+ }
3193
+ else {
3194
+ asset.once('load', () => {
3195
+ this._instantiate(asset.resource);
3196
+ });
3197
+ app.assets.load(asset);
3198
+ }
3199
+ }
3200
+ _unloadModel() {
3201
+ var _a;
3202
+ (_a = this._entity) === null || _a === void 0 ? void 0 : _a.destroy();
3203
+ this._entity = null;
3204
+ }
3013
3205
  /**
3014
3206
  * Sets the asset ID of the model.
3015
3207
  * @param value - The asset ID.
3016
3208
  */
3017
3209
  set asset(value) {
3018
3210
  this._asset = value;
3019
- this._loadModel();
3211
+ if (this.isConnected) {
3212
+ this._loadModel();
3213
+ }
3020
3214
  }
3021
3215
  /**
3022
3216
  * Gets the source URL of the model.
@@ -3208,48 +3402,76 @@ class SkyElement extends AsyncElement {
3208
3402
  this._intensity = 1;
3209
3403
  this._rotation = new Vec3();
3210
3404
  this._level = 0;
3405
+ this._lighting = false;
3211
3406
  this._scale = new Vec3(100, 100, 100);
3212
3407
  this._type = 'infinite';
3408
+ this._scene = null;
3213
3409
  }
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') || '';
3410
+ connectedCallback() {
3411
+ this._loadSkybox();
3218
3412
  this._onReady();
3219
3413
  }
3220
- getScene() {
3221
- const app = this.closestApp.app;
3222
- if (!app) {
3223
- return;
3224
- }
3225
- return app.scene;
3414
+ disconnectedCallback() {
3415
+ this._unloadSkybox();
3226
3416
  }
3227
- initSkybox(source) {
3417
+ _generateSkybox(asset) {
3418
+ if (!this._scene)
3419
+ return;
3420
+ const source = asset.resource;
3228
3421
  source.anisotropy = 4;
3229
3422
  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;
3423
+ this._scene.skybox = skybox;
3424
+ if (this._lighting) {
3425
+ const lighting = EnvLighting.generateLightingSource(source);
3426
+ const envAtlas = EnvLighting.generateAtlas(lighting);
3427
+ this._scene.envAtlas = envAtlas;
3428
+ }
3429
+ const layer = this._scene.layers.getLayerById(LAYERID_SKYBOX);
3430
+ if (layer) {
3431
+ layer.enabled = this._type !== 'none';
3432
+ }
3433
+ this._scene.sky.type = this._type;
3434
+ this._scene.sky.node.setLocalScale(this._scale);
3435
+ this._scene.sky.center = this._center;
3436
+ }
3437
+ async _loadSkybox() {
3438
+ var _a;
3439
+ const appElement = await ((_a = this.closestApp) === null || _a === void 0 ? void 0 : _a.ready());
3440
+ const app = appElement === null || appElement === void 0 ? void 0 : appElement.app;
3441
+ if (!app) {
3442
+ return;
3443
+ }
3444
+ const asset = AssetElement.get(this._asset);
3445
+ if (!asset) {
3446
+ return;
3447
+ }
3448
+ this._scene = app.scene;
3449
+ if (asset.loaded) {
3450
+ this._generateSkybox(asset);
3451
+ }
3452
+ else {
3453
+ asset.once('load', () => {
3454
+ this._generateSkybox(asset);
3455
+ });
3456
+ app.assets.load(asset);
3243
3457
  }
3244
3458
  }
3459
+ _unloadSkybox() {
3460
+ var _a, _b;
3461
+ if (!this._scene)
3462
+ return;
3463
+ (_a = this._scene.skybox) === null || _a === void 0 ? void 0 : _a.destroy();
3464
+ // @ts-ignore
3465
+ this._scene.skybox = null;
3466
+ (_b = this._scene.envAtlas) === null || _b === void 0 ? void 0 : _b.destroy();
3467
+ // @ts-ignore
3468
+ this._scene.envAtlas = null;
3469
+ this._scene = null;
3470
+ }
3245
3471
  set asset(value) {
3246
3472
  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
- }
3473
+ if (this.isConnected) {
3474
+ this._loadSkybox();
3253
3475
  }
3254
3476
  }
3255
3477
  get asset() {
@@ -3257,9 +3479,8 @@ class SkyElement extends AsyncElement {
3257
3479
  }
3258
3480
  set center(value) {
3259
3481
  this._center = value;
3260
- const scene = this.getScene();
3261
- if (scene) {
3262
- scene.sky.center = this._center;
3482
+ if (this._scene) {
3483
+ this._scene.sky.center = this._center;
3263
3484
  }
3264
3485
  }
3265
3486
  get center() {
@@ -3267,19 +3488,32 @@ class SkyElement extends AsyncElement {
3267
3488
  }
3268
3489
  set intensity(value) {
3269
3490
  this._intensity = value;
3270
- const scene = this.getScene();
3271
- if (scene) {
3272
- scene.skyboxIntensity = this._intensity;
3491
+ if (this._scene) {
3492
+ this._scene.skyboxIntensity = this._intensity;
3273
3493
  }
3274
3494
  }
3275
3495
  get intensity() {
3276
3496
  return this._intensity;
3277
3497
  }
3498
+ set level(value) {
3499
+ this._level = value;
3500
+ if (this._scene) {
3501
+ this._scene.skyboxMip = this._level;
3502
+ }
3503
+ }
3504
+ get level() {
3505
+ return this._level;
3506
+ }
3507
+ set lighting(value) {
3508
+ this._lighting = value;
3509
+ }
3510
+ get lighting() {
3511
+ return this._lighting;
3512
+ }
3278
3513
  set rotation(value) {
3279
3514
  this._rotation = value;
3280
- const scene = this.getScene();
3281
- if (scene) {
3282
- scene.skyboxRotation = new Quat().setFromEulerAngles(value);
3515
+ if (this._scene) {
3516
+ this._scene.skyboxRotation = new Quat().setFromEulerAngles(value);
3283
3517
  }
3284
3518
  }
3285
3519
  get rotation() {
@@ -3287,30 +3521,18 @@ class SkyElement extends AsyncElement {
3287
3521
  }
3288
3522
  set scale(value) {
3289
3523
  this._scale = value;
3290
- const scene = this.getScene();
3291
- if (scene) {
3292
- scene.sky.node.setLocalScale(this._scale);
3524
+ if (this._scene) {
3525
+ this._scene.sky.node.setLocalScale(this._scale);
3293
3526
  }
3294
3527
  }
3295
3528
  get scale() {
3296
3529
  return this._scale;
3297
3530
  }
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
3531
  set type(value) {
3309
3532
  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);
3533
+ if (this._scene) {
3534
+ this._scene.sky.type = this._type;
3535
+ const layer = this._scene.layers.getLayerById(LAYERID_SKYBOX);
3314
3536
  if (layer) {
3315
3537
  layer.enabled = this._type !== 'none';
3316
3538
  }
@@ -3320,7 +3542,7 @@ class SkyElement extends AsyncElement {
3320
3542
  return this._type;
3321
3543
  }
3322
3544
  static get observedAttributes() {
3323
- return ['asset', 'center', 'intensity', 'level', 'rotation', 'scale', 'type'];
3545
+ return ['asset', 'center', 'intensity', 'level', 'lighting', 'rotation', 'scale', 'type'];
3324
3546
  }
3325
3547
  attributeChangedCallback(name, _oldValue, newValue) {
3326
3548
  switch (name) {
@@ -3333,12 +3555,15 @@ class SkyElement extends AsyncElement {
3333
3555
  case 'intensity':
3334
3556
  this.intensity = parseFloat(newValue);
3335
3557
  break;
3336
- case 'rotation':
3337
- this.rotation = parseVec3(newValue);
3338
- break;
3339
3558
  case 'level':
3340
3559
  this.level = parseInt(newValue, 10);
3341
3560
  break;
3561
+ case 'lighting':
3562
+ this.lighting = this.hasAttribute(name);
3563
+ break;
3564
+ case 'rotation':
3565
+ this.rotation = parseVec3(newValue);
3566
+ break;
3342
3567
  case 'scale':
3343
3568
  this.scale = parseVec3(newValue);
3344
3569
  break;