@playcanvas/web-components 0.8.2 → 0.9.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.
- package/dist/app.d.ts +10 -2
- package/dist/asset.d.ts +18 -3
- package/dist/async-element.d.ts +51 -4
- package/dist/components/button-component.d.ts +10 -4
- package/dist/components/camera-component.d.ts +9 -4
- package/dist/components/collision-component.d.ts +9 -4
- package/dist/components/component.d.ts +7 -1
- package/dist/components/element-component.d.ts +17 -12
- package/dist/components/gsplat-component.d.ts +6 -1
- package/dist/components/layoutchild-component.d.ts +6 -1
- package/dist/components/layoutgroup-component.d.ts +21 -15
- package/dist/components/light-component.d.ts +12 -6
- package/dist/components/listener-component.d.ts +6 -1
- package/dist/components/particlesystem-component.d.ts +6 -1
- package/dist/components/render-component.d.ts +13 -4
- package/dist/components/rigidbody-component.d.ts +9 -4
- package/dist/components/screen-component.d.ts +6 -1
- package/dist/components/script-component.d.ts +116 -16
- package/dist/components/script.d.ts +72 -8
- package/dist/components/scrollbar-component.d.ts +10 -4
- package/dist/components/scrollview-component.d.ts +17 -10
- package/dist/components/sound-component.d.ts +6 -1
- package/dist/components/sound-slot.d.ts +8 -3
- package/dist/entity.d.ts +26 -2
- package/dist/index.d.ts +3 -2
- package/dist/material.d.ts +10 -0
- package/dist/model.d.ts +5 -0
- package/dist/module.d.ts +5 -0
- package/dist/pwc.cjs +1574 -853
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +1574 -853
- package/dist/pwc.js.map +1 -1
- package/dist/pwc.min.js +1 -1
- package/dist/pwc.min.js.map +1 -1
- package/dist/pwc.mjs +1575 -855
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.ts +14 -5
- package/dist/sky.d.ts +6 -0
- package/dist/utils.d.ts +81 -23
- package/package.json +7 -7
- package/src/app.ts +38 -12
- package/src/asset.ts +61 -8
- package/src/async-element.ts +86 -5
- package/src/components/button-component.ts +26 -19
- package/src/components/camera-component.ts +29 -23
- package/src/components/collision-component.ts +19 -13
- package/src/components/component.ts +32 -13
- package/src/components/element-component.ts +58 -52
- package/src/components/gsplat-component.ts +14 -7
- package/src/components/layoutchild-component.ts +16 -9
- package/src/components/layoutgroup-component.ts +38 -31
- package/src/components/light-component.ts +33 -31
- package/src/components/listener-component.ts +8 -2
- package/src/components/particlesystem-component.ts +8 -2
- package/src/components/render-component.ts +19 -8
- package/src/components/rigidbody-component.ts +21 -15
- package/src/components/screen-component.ts +15 -9
- package/src/components/script-component.ts +512 -125
- package/src/components/script.ts +116 -16
- package/src/components/scrollbar-component.ts +19 -12
- package/src/components/scrollview-component.ts +37 -29
- package/src/components/sound-component.ts +16 -9
- package/src/components/sound-slot.ts +23 -14
- package/src/entity.ts +61 -71
- package/src/index.ts +5 -2
- package/src/material.ts +34 -1
- package/src/model.ts +6 -0
- package/src/module.ts +6 -0
- package/src/scene.ts +25 -12
- package/src/sky.ts +34 -16
- package/src/utils.ts +180 -40
package/src/entity.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AppBase, Entity, Vec3 } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
import { AsyncElement } from './async-element';
|
|
4
|
-
import { parseVec3 } from './utils';
|
|
4
|
+
import { parseBool, parseVec3 } from './utils';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The EntityElement interface provides properties and methods for manipulating
|
|
@@ -45,76 +45,48 @@ class EntityElement extends AsyncElement {
|
|
|
45
45
|
*/
|
|
46
46
|
private _listeners: { [key: string]: EventListener[] } = {};
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* The event types for which an inline `onpointer*` attribute is currently present.
|
|
50
|
+
*/
|
|
51
|
+
private _inlineHandlerTypes = new Set<string>();
|
|
52
|
+
|
|
48
53
|
/**
|
|
49
54
|
* Whether the hierarchy has been built for this entity.
|
|
50
55
|
*/
|
|
51
56
|
private _built = false;
|
|
52
57
|
|
|
58
|
+
private _entity: Entity | null = null;
|
|
59
|
+
|
|
53
60
|
/**
|
|
54
|
-
* The PlayCanvas entity instance.
|
|
61
|
+
* The PlayCanvas entity instance. Available once the element is ready — await
|
|
62
|
+
* {@link whenReady} or the element's `ready()` promise before accessing it.
|
|
63
|
+
* @returns The entity instance.
|
|
55
64
|
*/
|
|
56
|
-
entity: Entity
|
|
65
|
+
get entity(): Entity {
|
|
66
|
+
return this._entity!;
|
|
67
|
+
}
|
|
57
68
|
|
|
58
69
|
createEntity(app: AppBase) {
|
|
59
70
|
// Guard against double creation. When a subtree is inserted at runtime (e.g. cloning a
|
|
60
71
|
// `<template>`), an ancestor's connectedCallback eagerly creates descendant entities; the
|
|
61
72
|
// descendants' own connectedCallbacks would otherwise create them a second time.
|
|
62
|
-
if (this.
|
|
73
|
+
if (this._entity) {
|
|
63
74
|
return;
|
|
64
75
|
}
|
|
65
76
|
|
|
66
77
|
// Create a new entity
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const enabled = this.getAttribute('enabled');
|
|
70
|
-
if (enabled) {
|
|
71
|
-
this.entity.enabled = enabled !== 'false';
|
|
72
|
-
}
|
|
78
|
+
const entity = new Entity(this.getAttribute('name') || this._name, app);
|
|
79
|
+
this._entity = entity;
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const rotation = this.getAttribute('rotation');
|
|
80
|
-
if (rotation) {
|
|
81
|
-
this.entity.setLocalEulerAngles(parseVec3(rotation));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const scale = this.getAttribute('scale');
|
|
85
|
-
if (scale) {
|
|
86
|
-
this.entity.setLocalScale(parseVec3(scale));
|
|
87
|
-
}
|
|
81
|
+
entity.enabled = parseBool(this.getAttribute('enabled'), true);
|
|
82
|
+
entity.setLocalPosition(parseVec3(this.getAttribute('position'), Vec3.ZERO, 'position'));
|
|
83
|
+
entity.setLocalEulerAngles(parseVec3(this.getAttribute('rotation'), Vec3.ZERO, 'rotation'));
|
|
84
|
+
entity.setLocalScale(parseVec3(this.getAttribute('scale'), Vec3.ONE, 'scale'));
|
|
88
85
|
|
|
89
86
|
const tags = this.getAttribute('tags');
|
|
90
87
|
if (tags) {
|
|
91
|
-
|
|
88
|
+
entity.tags.add(tags.split(',').map(tag => tag.trim()));
|
|
92
89
|
}
|
|
93
|
-
|
|
94
|
-
// Handle pointer events
|
|
95
|
-
const pointerEvents = [
|
|
96
|
-
'onpointerenter',
|
|
97
|
-
'onpointerleave',
|
|
98
|
-
'onpointerdown',
|
|
99
|
-
'onpointerup',
|
|
100
|
-
'onpointermove'
|
|
101
|
-
];
|
|
102
|
-
|
|
103
|
-
pointerEvents.forEach((eventName) => {
|
|
104
|
-
const handler = this.getAttribute(eventName);
|
|
105
|
-
if (handler) {
|
|
106
|
-
const eventType = eventName.substring(2); // remove 'on' prefix
|
|
107
|
-
const eventHandler = (event: Event) => {
|
|
108
|
-
try {
|
|
109
|
-
/* eslint-disable-next-line no-new-func */
|
|
110
|
-
new Function('event', handler).call(this, event);
|
|
111
|
-
} catch (e) {
|
|
112
|
-
console.error('Error in event handler:', e);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
this.addEventListener(eventType, eventHandler);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
90
|
}
|
|
119
91
|
|
|
120
92
|
buildHierarchy(app: AppBase) {
|
|
@@ -159,12 +131,12 @@ class EntityElement extends AsyncElement {
|
|
|
159
131
|
// Notify all children that their entities are about to become invalid
|
|
160
132
|
const children = this.querySelectorAll('pc-entity');
|
|
161
133
|
children.forEach((child) => {
|
|
162
|
-
(child as EntityElement).
|
|
134
|
+
(child as EntityElement)._entity = null;
|
|
163
135
|
});
|
|
164
136
|
|
|
165
137
|
// Destroy the entity
|
|
166
138
|
this.entity.destroy();
|
|
167
|
-
this.
|
|
139
|
+
this._entity = null;
|
|
168
140
|
this._built = false;
|
|
169
141
|
}
|
|
170
142
|
}
|
|
@@ -284,6 +256,31 @@ class EntityElement extends AsyncElement {
|
|
|
284
256
|
return this._tags;
|
|
285
257
|
}
|
|
286
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Tracks whether an inline `onpointer*` attribute is present. The browser itself compiles and
|
|
261
|
+
* runs these attributes — they are standard `GlobalEventHandlers`, so setting one replaces
|
|
262
|
+
* the previous handler and removing it removes the handler, exactly like `onclick` on any
|
|
263
|
+
* HTML element. But because they bypass {@link addEventListener}, the connect/disconnect
|
|
264
|
+
* bookkeeping that lets the application lazily attach its canvas pointer handlers must be
|
|
265
|
+
* kept in sync here.
|
|
266
|
+
*
|
|
267
|
+
* @param name - The attribute name (e.g. 'onpointerdown').
|
|
268
|
+
* @param value - The attribute value, or `null` when the attribute has been removed.
|
|
269
|
+
*/
|
|
270
|
+
private _updateInlineHandler(name: string, value: string | null) {
|
|
271
|
+
const type = name.substring(2);
|
|
272
|
+
const had = this._inlineHandlerTypes.has(type);
|
|
273
|
+
const has = value !== null;
|
|
274
|
+
|
|
275
|
+
if (has && !had) {
|
|
276
|
+
this._inlineHandlerTypes.add(type);
|
|
277
|
+
this.dispatchEvent(new CustomEvent(`${type}:connect`, { bubbles: true }));
|
|
278
|
+
} else if (!has && had) {
|
|
279
|
+
this._inlineHandlerTypes.delete(type);
|
|
280
|
+
this.dispatchEvent(new CustomEvent(`${type}:disconnect`, { bubbles: true }));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
287
284
|
static get observedAttributes() {
|
|
288
285
|
return [
|
|
289
286
|
'enabled',
|
|
@@ -303,19 +300,19 @@ class EntityElement extends AsyncElement {
|
|
|
303
300
|
attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
|
|
304
301
|
switch (name) {
|
|
305
302
|
case 'enabled':
|
|
306
|
-
this.enabled = newValue
|
|
303
|
+
this.enabled = parseBool(newValue, true);
|
|
307
304
|
break;
|
|
308
305
|
case 'name':
|
|
309
306
|
this.name = newValue;
|
|
310
307
|
break;
|
|
311
308
|
case 'position':
|
|
312
|
-
this.position = parseVec3(newValue);
|
|
309
|
+
this.position = parseVec3(newValue, Vec3.ZERO, name);
|
|
313
310
|
break;
|
|
314
311
|
case 'rotation':
|
|
315
|
-
this.rotation = parseVec3(newValue);
|
|
312
|
+
this.rotation = parseVec3(newValue, Vec3.ZERO, name);
|
|
316
313
|
break;
|
|
317
314
|
case 'scale':
|
|
318
|
-
this.scale = parseVec3(newValue);
|
|
315
|
+
this.scale = parseVec3(newValue, Vec3.ONE, name);
|
|
319
316
|
break;
|
|
320
317
|
case 'tags':
|
|
321
318
|
this.tags = newValue.split(',').map(tag => tag.trim());
|
|
@@ -325,20 +322,7 @@ class EntityElement extends AsyncElement {
|
|
|
325
322
|
case 'onpointerdown':
|
|
326
323
|
case 'onpointerup':
|
|
327
324
|
case 'onpointermove':
|
|
328
|
-
|
|
329
|
-
const eventName = name.substring(2);
|
|
330
|
-
// Use Function.prototype.bind to avoid new Function
|
|
331
|
-
const handler = (event: Event) => {
|
|
332
|
-
try {
|
|
333
|
-
const handlerStr = this.getAttribute(eventName) || '';
|
|
334
|
-
/* eslint-disable-next-line no-new-func */
|
|
335
|
-
new Function('event', handlerStr).call(this, event);
|
|
336
|
-
} catch (e) {
|
|
337
|
-
console.error('Error in event handler:', e);
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
this.addEventListener(eventName, handler);
|
|
341
|
-
}
|
|
325
|
+
this._updateInlineHandler(name, newValue);
|
|
342
326
|
break;
|
|
343
327
|
}
|
|
344
328
|
}
|
|
@@ -365,10 +349,16 @@ class EntityElement extends AsyncElement {
|
|
|
365
349
|
}
|
|
366
350
|
|
|
367
351
|
hasListeners(type: string): boolean {
|
|
368
|
-
return Boolean(this._listeners[type]?.length);
|
|
352
|
+
return Boolean(this._listeners[type]?.length) || this._inlineHandlerTypes.has(type);
|
|
369
353
|
}
|
|
370
354
|
}
|
|
371
355
|
|
|
372
356
|
customElements.define('pc-entity', EntityElement);
|
|
373
357
|
|
|
358
|
+
declare global {
|
|
359
|
+
interface HTMLElementTagNameMap {
|
|
360
|
+
'pc-entity': EntityElement;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
374
364
|
export { EntityElement };
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
/* eslint-disable import/order */
|
|
11
11
|
|
|
12
12
|
// Note that order matters here (e.g. pc-entity must be defined before components)
|
|
13
|
-
import { AsyncElement } from './async-element';
|
|
13
|
+
import { AsyncElement, whenReady } from './async-element';
|
|
14
14
|
import { ModuleElement } from './module';
|
|
15
15
|
import { AppElement } from './app';
|
|
16
16
|
import { EntityElement } from './entity';
|
|
@@ -69,5 +69,8 @@ export {
|
|
|
69
69
|
MaterialElement,
|
|
70
70
|
ModelElement,
|
|
71
71
|
SceneElement,
|
|
72
|
-
SkyElement
|
|
72
|
+
SkyElement,
|
|
73
|
+
whenReady
|
|
73
74
|
};
|
|
75
|
+
|
|
76
|
+
export type { AsyncElementTagName } from './async-element';
|
package/src/material.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Color, StandardMaterial, Texture } from 'playcanvas';
|
|
2
2
|
|
|
3
|
+
import { AppElement } from './app';
|
|
3
4
|
import { AssetElement } from './asset';
|
|
4
5
|
import { parseColor } from './utils';
|
|
5
6
|
|
|
@@ -8,6 +9,10 @@ import { parseColor } from './utils';
|
|
|
8
9
|
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-material/ | `<pc-material>`} elements.
|
|
9
10
|
* The MaterialElement interface also inherits the properties and methods of the
|
|
10
11
|
* {@link HTMLElement} interface.
|
|
12
|
+
*
|
|
13
|
+
* A `pc-material` must be a direct child of `pc-app` — elements placed elsewhere log a warning
|
|
14
|
+
* and never create a material. Elements inserted while the application is already running are
|
|
15
|
+
* created on insertion.
|
|
11
16
|
*/
|
|
12
17
|
class MaterialElement extends HTMLElement {
|
|
13
18
|
private _diffuse = new Color(1, 1, 1);
|
|
@@ -22,6 +27,28 @@ class MaterialElement extends HTMLElement {
|
|
|
22
27
|
|
|
23
28
|
material: StandardMaterial | null = null;
|
|
24
29
|
|
|
30
|
+
async connectedCallback() {
|
|
31
|
+
const appElement = this.parentElement?.closest('pc-app') as AppElement | null ?? null;
|
|
32
|
+
|
|
33
|
+
// Materials must be direct children of pc-app (matches the boot query ':scope > pc-material')
|
|
34
|
+
if (!appElement || this.parentElement !== appElement) {
|
|
35
|
+
console.warn(`pc-material '${this.id}' must be a direct child of pc-app - material not created`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
await appElement.ready();
|
|
40
|
+
|
|
41
|
+
// The element may have been removed or re-parented while waiting for the app
|
|
42
|
+
if (!this.isConnected || this.parentElement !== appElement) return;
|
|
43
|
+
|
|
44
|
+
// Materials present at startup are created by AppElement's boot; this branch handles
|
|
45
|
+
// elements inserted (or re-inserted) after the app is already running
|
|
46
|
+
if (!this.material) {
|
|
47
|
+
if (!appElement.app) return; // pc-app is re-connecting; its own boot will create this
|
|
48
|
+
this.createMaterial();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
25
52
|
createMaterial() {
|
|
26
53
|
this.material = new StandardMaterial();
|
|
27
54
|
this.material.glossInvert = false;
|
|
@@ -118,7 +145,7 @@ class MaterialElement extends HTMLElement {
|
|
|
118
145
|
attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
|
|
119
146
|
switch (name) {
|
|
120
147
|
case 'diffuse':
|
|
121
|
-
this.diffuse = parseColor(newValue);
|
|
148
|
+
this.diffuse = parseColor(newValue, Color.WHITE, name);
|
|
122
149
|
break;
|
|
123
150
|
case 'diffuse-map':
|
|
124
151
|
this.diffuseMap = newValue;
|
|
@@ -138,4 +165,10 @@ class MaterialElement extends HTMLElement {
|
|
|
138
165
|
|
|
139
166
|
customElements.define('pc-material', MaterialElement);
|
|
140
167
|
|
|
168
|
+
declare global {
|
|
169
|
+
interface HTMLElementTagNameMap {
|
|
170
|
+
'pc-material': MaterialElement;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
141
174
|
export { MaterialElement };
|
package/src/model.ts
CHANGED
package/src/module.ts
CHANGED
package/src/scene.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Color, Scene, Vec3 } from 'playcanvas';
|
|
|
2
2
|
|
|
3
3
|
import { AppElement } from './app';
|
|
4
4
|
import { AsyncElement } from './async-element';
|
|
5
|
-
import { parseColor, parseVec3 } from './utils';
|
|
5
|
+
import { parseColor, parseEnum, parseNumber, parseVec3 } from './utils';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* The SceneElement interface provides properties and methods for manipulating
|
|
@@ -14,7 +14,7 @@ class SceneElement extends AsyncElement {
|
|
|
14
14
|
/**
|
|
15
15
|
* The fog type of the scene.
|
|
16
16
|
*/
|
|
17
|
-
private _fog
|
|
17
|
+
private _fog: 'none' | 'linear' | 'exp' | 'exp2' = 'none';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* The color of the fog.
|
|
@@ -41,15 +41,21 @@ class SceneElement extends AsyncElement {
|
|
|
41
41
|
*/
|
|
42
42
|
private _gravity = new Vec3(0, -9.81, 0);
|
|
43
43
|
|
|
44
|
+
private _scene: Scene | null = null;
|
|
45
|
+
|
|
44
46
|
/**
|
|
45
|
-
* The PlayCanvas scene instance.
|
|
47
|
+
* The PlayCanvas scene instance. Available once the element is ready — await
|
|
48
|
+
* {@link whenReady} or the element's `ready()` promise before accessing it.
|
|
49
|
+
* @returns The scene instance.
|
|
46
50
|
*/
|
|
47
|
-
scene: Scene
|
|
51
|
+
get scene(): Scene {
|
|
52
|
+
return this._scene!;
|
|
53
|
+
}
|
|
48
54
|
|
|
49
55
|
async connectedCallback() {
|
|
50
56
|
await this.closestApp?.ready();
|
|
51
57
|
|
|
52
|
-
this.
|
|
58
|
+
this._scene = this.closestApp!.app!.scene;
|
|
53
59
|
this.updateSceneSettings();
|
|
54
60
|
|
|
55
61
|
this._onReady();
|
|
@@ -69,7 +75,8 @@ class SceneElement extends AsyncElement {
|
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
/**
|
|
72
|
-
* Sets the fog type of the scene.
|
|
78
|
+
* Sets the fog type of the scene. Can be `none`, `linear`, `exp` or `exp2`. Defaults to
|
|
79
|
+
* `none`.
|
|
73
80
|
* @param value - The fog type.
|
|
74
81
|
*/
|
|
75
82
|
set fog(value) {
|
|
@@ -190,22 +197,22 @@ class SceneElement extends AsyncElement {
|
|
|
190
197
|
attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
|
|
191
198
|
switch (name) {
|
|
192
199
|
case 'fog':
|
|
193
|
-
this.fog = newValue;
|
|
200
|
+
this.fog = parseEnum(newValue, ['none', 'linear', 'exp', 'exp2'], 'none', name);
|
|
194
201
|
break;
|
|
195
202
|
case 'fog-color':
|
|
196
|
-
this.fogColor = parseColor(newValue);
|
|
203
|
+
this.fogColor = parseColor(newValue, Color.WHITE, name);
|
|
197
204
|
break;
|
|
198
205
|
case 'fog-density':
|
|
199
|
-
this.fogDensity =
|
|
206
|
+
this.fogDensity = parseNumber(newValue, 0, name);
|
|
200
207
|
break;
|
|
201
208
|
case 'fog-start':
|
|
202
|
-
this.fogStart =
|
|
209
|
+
this.fogStart = parseNumber(newValue, 0, name);
|
|
203
210
|
break;
|
|
204
211
|
case 'fog-end':
|
|
205
|
-
this.fogEnd =
|
|
212
|
+
this.fogEnd = parseNumber(newValue, 1000, name);
|
|
206
213
|
break;
|
|
207
214
|
case 'gravity':
|
|
208
|
-
this.gravity = parseVec3(newValue);
|
|
215
|
+
this.gravity = parseVec3(newValue, new Vec3(0, -9.81, 0), name);
|
|
209
216
|
break;
|
|
210
217
|
// ... handle other attributes as well
|
|
211
218
|
}
|
|
@@ -214,4 +221,10 @@ class SceneElement extends AsyncElement {
|
|
|
214
221
|
|
|
215
222
|
customElements.define('pc-scene', SceneElement);
|
|
216
223
|
|
|
224
|
+
declare global {
|
|
225
|
+
interface HTMLElementTagNameMap {
|
|
226
|
+
'pc-scene': SceneElement;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
217
230
|
export { SceneElement };
|
package/src/sky.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Asset, EnvLighting, LAYERID_SKYBOX, Quat, Scene, Texture, Vec3 } from 'playcanvas';
|
|
2
2
|
|
|
3
|
+
import { AppElement } from './app';
|
|
3
4
|
import { AssetElement } from './asset';
|
|
4
5
|
import { AsyncElement } from './async-element';
|
|
5
|
-
import { parseVec3 } from './utils';
|
|
6
|
+
import { parseBool, parseEnum, parseNumber, parseVec3 } from './utils';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* The SkyElement interface provides properties and methods for manipulating
|
|
@@ -28,6 +29,8 @@ class SkyElement extends AsyncElement {
|
|
|
28
29
|
|
|
29
30
|
private _scene: Scene | null = null;
|
|
30
31
|
|
|
32
|
+
private _appElement: AppElement | null = null;
|
|
33
|
+
|
|
31
34
|
connectedCallback() {
|
|
32
35
|
this._loadSkybox();
|
|
33
36
|
this._onReady();
|
|
@@ -35,6 +38,7 @@ class SkyElement extends AsyncElement {
|
|
|
35
38
|
|
|
36
39
|
disconnectedCallback() {
|
|
37
40
|
this._unloadSkybox();
|
|
41
|
+
this._appElement = null;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
private _generateSkybox(asset: Asset) {
|
|
@@ -67,10 +71,12 @@ class SkyElement extends AsyncElement {
|
|
|
67
71
|
private async _loadSkybox() {
|
|
68
72
|
const appElement = await this.closestApp?.ready();
|
|
69
73
|
const app = appElement?.app;
|
|
70
|
-
if (!app) {
|
|
74
|
+
if (!appElement || !app) {
|
|
71
75
|
return;
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
this._appElement = appElement;
|
|
79
|
+
|
|
74
80
|
const asset = AssetElement.get(this._asset);
|
|
75
81
|
if (!asset) {
|
|
76
82
|
return;
|
|
@@ -89,16 +95,22 @@ class SkyElement extends AsyncElement {
|
|
|
89
95
|
}
|
|
90
96
|
|
|
91
97
|
private _unloadSkybox() {
|
|
92
|
-
|
|
98
|
+
const scene = this._scene;
|
|
99
|
+
if (!scene) return;
|
|
100
|
+
|
|
101
|
+
this._scene = null;
|
|
102
|
+
|
|
103
|
+
// If the owning application has already been destroyed (removing a <pc-app>
|
|
104
|
+
// disconnects it before its children), the scene, graphics device and skybox
|
|
105
|
+
// textures have all been destroyed along with it — nothing left to clean up.
|
|
106
|
+
if (!this._appElement?.app) return;
|
|
93
107
|
|
|
94
|
-
|
|
108
|
+
scene.skybox?.destroy();
|
|
95
109
|
// @ts-ignore
|
|
96
|
-
|
|
97
|
-
|
|
110
|
+
scene.skybox = null;
|
|
111
|
+
scene.envAtlas?.destroy();
|
|
98
112
|
// @ts-ignore
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
this._scene = null;
|
|
113
|
+
scene.envAtlas = null;
|
|
102
114
|
}
|
|
103
115
|
|
|
104
116
|
/**
|
|
@@ -264,25 +276,25 @@ class SkyElement extends AsyncElement {
|
|
|
264
276
|
this.asset = newValue;
|
|
265
277
|
break;
|
|
266
278
|
case 'center':
|
|
267
|
-
this.center = parseVec3(newValue);
|
|
279
|
+
this.center = parseVec3(newValue, new Vec3(0, 0.01, 0), name);
|
|
268
280
|
break;
|
|
269
281
|
case 'intensity':
|
|
270
|
-
this.intensity =
|
|
282
|
+
this.intensity = parseNumber(newValue, 1, name);
|
|
271
283
|
break;
|
|
272
284
|
case 'level':
|
|
273
|
-
this.level =
|
|
285
|
+
this.level = parseNumber(newValue, 0, name);
|
|
274
286
|
break;
|
|
275
287
|
case 'lighting':
|
|
276
|
-
this.lighting =
|
|
288
|
+
this.lighting = parseBool(newValue, false);
|
|
277
289
|
break;
|
|
278
290
|
case 'rotation':
|
|
279
|
-
this.rotation = parseVec3(newValue);
|
|
291
|
+
this.rotation = parseVec3(newValue, Vec3.ZERO, name);
|
|
280
292
|
break;
|
|
281
293
|
case 'scale':
|
|
282
|
-
this.scale = parseVec3(newValue);
|
|
294
|
+
this.scale = parseVec3(newValue, new Vec3(100, 100, 100), name);
|
|
283
295
|
break;
|
|
284
296
|
case 'type':
|
|
285
|
-
this.type = newValue
|
|
297
|
+
this.type = parseEnum(newValue, ['box', 'dome', 'infinite', 'none'], 'infinite', name);
|
|
286
298
|
break;
|
|
287
299
|
}
|
|
288
300
|
}
|
|
@@ -290,4 +302,10 @@ class SkyElement extends AsyncElement {
|
|
|
290
302
|
|
|
291
303
|
customElements.define('pc-sky', SkyElement);
|
|
292
304
|
|
|
305
|
+
declare global {
|
|
306
|
+
interface HTMLElementTagNameMap {
|
|
307
|
+
'pc-sky': SkyElement;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
293
311
|
export { SkyElement };
|