@playcanvas/web-components 0.11.0 → 0.11.1
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/README.md +1 -1
- package/dist/app.d.ts +18 -38
- package/dist/asset.d.ts +8 -7
- package/dist/async-element.d.ts +21 -5
- package/dist/components/button-component.d.ts +3 -7
- package/dist/components/camera-component.d.ts +3 -7
- package/dist/components/collision-component.d.ts +3 -7
- package/dist/components/component.d.ts +22 -4
- package/dist/components/element-component.d.ts +4 -8
- package/dist/components/gsplat-component.d.ts +2 -7
- package/dist/components/layoutchild-component.d.ts +2 -7
- package/dist/components/layoutgroup-component.d.ts +3 -7
- package/dist/components/light-component.d.ts +3 -7
- package/dist/components/listener-component.d.ts +1 -6
- package/dist/components/particlesystem-component.d.ts +2 -7
- package/dist/components/render-component.d.ts +2 -7
- package/dist/components/rigidbody-component.d.ts +3 -7
- package/dist/components/screen-component.d.ts +3 -7
- package/dist/components/script-component.d.ts +8 -20
- package/dist/components/script.d.ts +2 -22
- package/dist/components/scrollbar-component.d.ts +2 -7
- package/dist/components/scrollview-component.d.ts +3 -7
- package/dist/components/sound-component.d.ts +2 -7
- package/dist/components/sound-slot.d.ts +8 -6
- package/dist/custom-elements.json +5049 -10696
- package/dist/entity.d.ts +5 -11
- package/dist/index.d.ts +37 -0
- package/dist/material.d.ts +12 -12
- package/dist/model.d.ts +21 -5
- package/dist/module.d.ts +0 -6
- package/dist/parse.d.ts +2 -1
- package/dist/pwc.cjs +496 -136
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +496 -136
- 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.min.mjs +1 -1
- package/dist/pwc.min.mjs.map +1 -1
- package/dist/pwc.mjs +496 -136
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.ts +4 -7
- package/dist/sky.d.ts +13 -5
- package/dist/vscode.html-custom-data.json +26 -26
- package/dist/web-types.json +545 -536
- package/package.json +8 -7
- package/src/app.ts +142 -70
- package/src/asset.ts +34 -28
- package/src/async-element.ts +34 -8
- package/src/components/button-component.ts +5 -9
- package/src/components/camera-component.ts +24 -10
- package/src/components/collision-component.ts +26 -15
- package/src/components/component.ts +58 -8
- package/src/components/element-component.ts +26 -30
- package/src/components/gsplat-component.ts +4 -9
- package/src/components/layoutchild-component.ts +4 -9
- package/src/components/layoutgroup-component.ts +14 -9
- package/src/components/light-component.ts +42 -12
- package/src/components/listener-component.ts +1 -7
- package/src/components/particlesystem-component.ts +7 -15
- package/src/components/render-component.ts +5 -10
- package/src/components/rigidbody-component.ts +23 -16
- package/src/components/screen-component.ts +5 -9
- package/src/components/script-component.ts +108 -46
- package/src/components/script.ts +38 -33
- package/src/components/scrollbar-component.ts +6 -16
- package/src/components/scrollview-component.ts +16 -11
- package/src/components/sound-component.ts +10 -15
- package/src/components/sound-slot.ts +30 -20
- package/src/entity.ts +42 -19
- package/src/index.ts +45 -1
- package/src/loading-bar.ts +8 -8
- package/src/material.ts +63 -37
- package/src/model.ts +69 -14
- package/src/module.ts +8 -7
- package/src/parse.ts +62 -17
- package/src/scene.ts +12 -9
- package/src/sky.ts +50 -9
package/src/components/script.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Script } from 'playcanvas';
|
|
1
|
+
import type { Script } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
import { AsyncElement } from '../async-element';
|
|
4
4
|
import { parseBool } from '../parse';
|
|
@@ -39,18 +39,11 @@ import { parseBool } from '../parse';
|
|
|
39
39
|
class ScriptElement extends AsyncElement {
|
|
40
40
|
private _attributes: Record<string, any> = {};
|
|
41
41
|
|
|
42
|
-
private _enabled
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Whether readiness has been signalled. Creation can happen more than once over an
|
|
46
|
-
* element's life (a runtime `name` change recreates the instance), but `ready` is a
|
|
47
|
-
* one-shot signal, so only the first successful creation fires it.
|
|
48
|
-
*/
|
|
49
|
-
private _readySignalled: boolean = false;
|
|
42
|
+
private _enabled = true;
|
|
50
43
|
|
|
51
44
|
/**
|
|
52
45
|
* The Script instance created for this element by its parent `<pc-scripts>` element.
|
|
53
|
-
* @
|
|
46
|
+
* @internal
|
|
54
47
|
*/
|
|
55
48
|
_script: Script | null = null;
|
|
56
49
|
|
|
@@ -64,10 +57,12 @@ class ScriptElement extends AsyncElement {
|
|
|
64
57
|
*/
|
|
65
58
|
set scriptAttributes(value: Record<string, any>) {
|
|
66
59
|
this._attributes = value ?? {};
|
|
67
|
-
this.dispatchEvent(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
this.dispatchEvent(
|
|
61
|
+
new CustomEvent('scriptattributeschange', {
|
|
62
|
+
detail: { attributes: this._attributes },
|
|
63
|
+
bubbles: true
|
|
64
|
+
})
|
|
65
|
+
);
|
|
71
66
|
}
|
|
72
67
|
|
|
73
68
|
/**
|
|
@@ -84,10 +79,12 @@ class ScriptElement extends AsyncElement {
|
|
|
84
79
|
*/
|
|
85
80
|
set enabled(value: boolean) {
|
|
86
81
|
this._enabled = value;
|
|
87
|
-
this.dispatchEvent(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
this.dispatchEvent(
|
|
83
|
+
new CustomEvent('scriptenablechange', {
|
|
84
|
+
detail: { enabled: value },
|
|
85
|
+
bubbles: true
|
|
86
|
+
})
|
|
87
|
+
);
|
|
91
88
|
}
|
|
92
89
|
|
|
93
90
|
/**
|
|
@@ -137,17 +134,27 @@ class ScriptElement extends AsyncElement {
|
|
|
137
134
|
// Script instances are created by the parent pc-scripts element, so an element placed
|
|
138
135
|
// anywhere else is inert and never becomes ready - warn rather than hang silently
|
|
139
136
|
if (this.parentElement?.tagName !== 'PC-SCRIPTS') {
|
|
140
|
-
console.warn(
|
|
137
|
+
console.warn(
|
|
138
|
+
`pc-script '${this.getAttribute('name')}' must be a direct child of pc-scripts - script not created`
|
|
139
|
+
);
|
|
141
140
|
}
|
|
142
141
|
}
|
|
143
142
|
|
|
143
|
+
disconnectedCallback() {
|
|
144
|
+
// Re-arm readiness so a re-inserted element announces the instance created for it then.
|
|
145
|
+
// `_script` is deliberately NOT cleared here: the parent's mutation observer processes
|
|
146
|
+
// this removal afterwards and reads it to establish which engine script this element
|
|
147
|
+
// owned - the parent is what clears it.
|
|
148
|
+
this._resetReady();
|
|
149
|
+
}
|
|
150
|
+
|
|
144
151
|
/**
|
|
145
152
|
* Called by the parent `<pc-scripts>` element when the script instance has been created.
|
|
146
|
-
*
|
|
153
|
+
* Creation can happen more than once per connection (a runtime `name` change recreates the
|
|
154
|
+
* instance), but `_onReady` signals readiness at most once per cycle.
|
|
155
|
+
* @internal
|
|
147
156
|
*/
|
|
148
157
|
_onScriptCreated() {
|
|
149
|
-
if (this._readySignalled) return;
|
|
150
|
-
this._readySignalled = true;
|
|
151
158
|
this._onReady();
|
|
152
159
|
}
|
|
153
160
|
|
|
@@ -165,7 +172,9 @@ class ScriptElement extends AsyncElement {
|
|
|
165
172
|
try {
|
|
166
173
|
this.scriptAttributes = JSON.parse(newValue);
|
|
167
174
|
} catch (error) {
|
|
168
|
-
console.warn(
|
|
175
|
+
console.warn(
|
|
176
|
+
`Invalid 'attributes' JSON on pc-script '${this.getAttribute('name')}': ${(error as Error).message}`
|
|
177
|
+
);
|
|
169
178
|
}
|
|
170
179
|
break;
|
|
171
180
|
case 'enabled':
|
|
@@ -176,10 +185,12 @@ class ScriptElement extends AsyncElement {
|
|
|
176
185
|
// the added-node mutation), so only a genuine rename is signalled here. Note
|
|
177
186
|
// that setAttribute fires this callback even when the value is unchanged.
|
|
178
187
|
if (oldValue !== null && oldValue !== newValue) {
|
|
179
|
-
this.dispatchEvent(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
188
|
+
this.dispatchEvent(
|
|
189
|
+
new CustomEvent('scriptnamechange', {
|
|
190
|
+
detail: { oldName: oldValue, newName: newValue },
|
|
191
|
+
bubbles: true
|
|
192
|
+
})
|
|
193
|
+
);
|
|
183
194
|
}
|
|
184
195
|
break;
|
|
185
196
|
}
|
|
@@ -188,10 +199,4 @@ class ScriptElement extends AsyncElement {
|
|
|
188
199
|
|
|
189
200
|
customElements.define('pc-script', ScriptElement);
|
|
190
201
|
|
|
191
|
-
declare global {
|
|
192
|
-
interface HTMLElementTagNameMap {
|
|
193
|
-
'pc-script': ScriptElement;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
202
|
export { ScriptElement };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ScrollbarComponent } from 'playcanvas';
|
|
2
|
+
import { ORIENTATION_HORIZONTAL, ORIENTATION_VERTICAL } from 'playcanvas';
|
|
2
3
|
|
|
3
|
-
import { ComponentElement } from './component';
|
|
4
4
|
import { getEntity, parseEnum, parseNumber } from '../parse';
|
|
5
5
|
|
|
6
|
+
import { ComponentElement } from './component';
|
|
7
|
+
|
|
6
8
|
const orientations = new Map<'horizontal' | 'vertical', number>([
|
|
7
9
|
['horizontal', ORIENTATION_HORIZONTAL],
|
|
8
10
|
['vertical', ORIENTATION_VERTICAL]
|
|
@@ -30,7 +32,7 @@ class ScrollbarComponentElement extends ComponentElement {
|
|
|
30
32
|
super('scrollbar');
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
getInitialComponentData() {
|
|
35
|
+
protected getInitialComponentData() {
|
|
34
36
|
const data: Record<string, any> = {
|
|
35
37
|
orientation: orientations.get(this._orientation),
|
|
36
38
|
value: this._value,
|
|
@@ -133,13 +135,7 @@ class ScrollbarComponentElement extends ComponentElement {
|
|
|
133
135
|
}
|
|
134
136
|
|
|
135
137
|
static get observedAttributes() {
|
|
136
|
-
return [
|
|
137
|
-
...super.observedAttributes,
|
|
138
|
-
'orientation',
|
|
139
|
-
'value',
|
|
140
|
-
'handle-size',
|
|
141
|
-
'handle'
|
|
142
|
-
];
|
|
138
|
+
return [...super.observedAttributes, 'orientation', 'value', 'handle-size', 'handle'];
|
|
143
139
|
}
|
|
144
140
|
|
|
145
141
|
attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null) {
|
|
@@ -164,10 +160,4 @@ class ScrollbarComponentElement extends ComponentElement {
|
|
|
164
160
|
|
|
165
161
|
customElements.define('pc-scrollbar', ScrollbarComponentElement);
|
|
166
162
|
|
|
167
|
-
declare global {
|
|
168
|
-
interface HTMLElementTagNameMap {
|
|
169
|
-
'pc-scrollbar': ScrollbarComponentElement;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
163
|
export { ScrollbarComponentElement };
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ScrollViewComponent } from 'playcanvas';
|
|
2
|
+
import {
|
|
3
|
+
SCROLL_MODE_BOUNCE,
|
|
4
|
+
SCROLL_MODE_CLAMP,
|
|
5
|
+
SCROLL_MODE_INFINITE,
|
|
6
|
+
SCROLLBAR_VISIBILITY_SHOW_ALWAYS,
|
|
7
|
+
SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED,
|
|
8
|
+
Vec2
|
|
9
|
+
} from 'playcanvas';
|
|
2
10
|
|
|
3
|
-
import { ComponentElement } from './component';
|
|
4
11
|
import { getEntity, parseBool, parseEnum, parseNumber, parseVec2 } from '../parse';
|
|
5
12
|
|
|
13
|
+
import { ComponentElement } from './component';
|
|
14
|
+
|
|
6
15
|
const scrollModes = new Map<'clamp' | 'bounce' | 'infinite', number>([
|
|
7
16
|
['clamp', SCROLL_MODE_CLAMP],
|
|
8
17
|
['bounce', SCROLL_MODE_BOUNCE],
|
|
@@ -54,7 +63,7 @@ class ScrollViewComponentElement extends ComponentElement {
|
|
|
54
63
|
super('scrollview');
|
|
55
64
|
}
|
|
56
65
|
|
|
57
|
-
getInitialComponentData() {
|
|
66
|
+
protected getInitialComponentData() {
|
|
58
67
|
const data: Record<string, any> = {
|
|
59
68
|
horizontal: this._horizontal,
|
|
60
69
|
vertical: this._vertical,
|
|
@@ -244,7 +253,8 @@ class ScrollViewComponentElement extends ComponentElement {
|
|
|
244
253
|
set horizontalScrollbarVisibility(value: 'always' | 'when-required') {
|
|
245
254
|
this._horizontalScrollbarVisibility = value;
|
|
246
255
|
if (this.component) {
|
|
247
|
-
this.component.horizontalScrollbarVisibility =
|
|
256
|
+
this.component.horizontalScrollbarVisibility =
|
|
257
|
+
visibilities.get(value) ?? SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED;
|
|
248
258
|
}
|
|
249
259
|
}
|
|
250
260
|
|
|
@@ -264,7 +274,8 @@ class ScrollViewComponentElement extends ComponentElement {
|
|
|
264
274
|
set verticalScrollbarVisibility(value: 'always' | 'when-required') {
|
|
265
275
|
this._verticalScrollbarVisibility = value;
|
|
266
276
|
if (this.component) {
|
|
267
|
-
this.component.verticalScrollbarVisibility =
|
|
277
|
+
this.component.verticalScrollbarVisibility =
|
|
278
|
+
visibilities.get(value) ?? SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED;
|
|
268
279
|
}
|
|
269
280
|
}
|
|
270
281
|
|
|
@@ -428,10 +439,4 @@ class ScrollViewComponentElement extends ComponentElement {
|
|
|
428
439
|
|
|
429
440
|
customElements.define('pc-scrollview', ScrollViewComponentElement);
|
|
430
441
|
|
|
431
|
-
declare global {
|
|
432
|
-
interface HTMLElementTagNameMap {
|
|
433
|
-
'pc-scrollview': ScrollViewComponentElement;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
442
|
export { ScrollViewComponentElement };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { SoundComponent } from 'playcanvas';
|
|
1
|
+
import type { SoundComponent } from 'playcanvas';
|
|
2
2
|
|
|
3
|
-
import { ComponentElement } from './component';
|
|
4
3
|
import { parseBool, parseEnum, parseNumber } from '../parse';
|
|
5
4
|
|
|
5
|
+
import { ComponentElement } from './component';
|
|
6
|
+
|
|
6
7
|
/**
|
|
7
8
|
* The SoundComponentElement interface provides properties and methods for manipulating
|
|
8
9
|
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-sounds/ | `<pc-sounds>`} elements.
|
|
@@ -14,24 +15,24 @@ import { parseBool, parseEnum, parseNumber } from '../parse';
|
|
|
14
15
|
class SoundComponentElement extends ComponentElement {
|
|
15
16
|
private _distanceModel: 'exponential' | 'inverse' | 'linear' = 'linear';
|
|
16
17
|
|
|
17
|
-
private _maxDistance
|
|
18
|
+
private _maxDistance = 10000;
|
|
18
19
|
|
|
19
|
-
private _pitch
|
|
20
|
+
private _pitch = 1;
|
|
20
21
|
|
|
21
|
-
private _positional
|
|
22
|
+
private _positional = false;
|
|
22
23
|
|
|
23
|
-
private _refDistance
|
|
24
|
+
private _refDistance = 1;
|
|
24
25
|
|
|
25
|
-
private _rollOffFactor
|
|
26
|
+
private _rollOffFactor = 1;
|
|
26
27
|
|
|
27
|
-
private _volume
|
|
28
|
+
private _volume = 1;
|
|
28
29
|
|
|
29
30
|
/** @ignore */
|
|
30
31
|
constructor() {
|
|
31
32
|
super('sound');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
getInitialComponentData() {
|
|
35
|
+
protected getInitialComponentData() {
|
|
35
36
|
return {
|
|
36
37
|
distanceModel: this._distanceModel,
|
|
37
38
|
maxDistance: this._maxDistance,
|
|
@@ -228,10 +229,4 @@ class SoundComponentElement extends ComponentElement {
|
|
|
228
229
|
|
|
229
230
|
customElements.define('pc-sounds', SoundComponentElement);
|
|
230
231
|
|
|
231
|
-
declare global {
|
|
232
|
-
interface HTMLElementTagNameMap {
|
|
233
|
-
'pc-sounds': SoundComponentElement;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
232
|
export { SoundComponentElement };
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import { SoundSlot } from 'playcanvas';
|
|
1
|
+
import type { SoundSlot } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
import { AssetElement } from '../asset';
|
|
4
4
|
import { AsyncElement } from '../async-element';
|
|
5
|
-
import { SoundComponentElement } from './sound-component';
|
|
6
5
|
import { parseBool, parseNumber } from '../parse';
|
|
7
6
|
|
|
7
|
+
import { SoundComponentElement } from './sound-component';
|
|
8
|
+
|
|
8
9
|
/**
|
|
9
10
|
* The SoundSlotElement interface provides properties and methods for manipulating
|
|
10
11
|
* `<pc-sound>` elements. The SoundSlotElement interface also inherits the properties and
|
|
11
12
|
* methods of the {@link AsyncElement} interface.
|
|
12
13
|
*/
|
|
13
14
|
class SoundSlotElement extends AsyncElement {
|
|
14
|
-
private _asset
|
|
15
|
+
private _asset = '';
|
|
15
16
|
|
|
16
|
-
private _autoPlay
|
|
17
|
+
private _autoPlay = false;
|
|
17
18
|
|
|
18
19
|
private _duration: number | null = null;
|
|
19
20
|
|
|
20
|
-
private _loop
|
|
21
|
+
private _loop = false;
|
|
21
22
|
|
|
22
|
-
private _name
|
|
23
|
+
private _name = '';
|
|
23
24
|
|
|
24
|
-
private _overlap
|
|
25
|
+
private _overlap = false;
|
|
25
26
|
|
|
26
|
-
private _pitch
|
|
27
|
+
private _pitch = 1;
|
|
27
28
|
|
|
28
|
-
private _startTime
|
|
29
|
+
private _startTime = 0;
|
|
29
30
|
|
|
30
|
-
private _volume
|
|
31
|
+
private _volume = 1;
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* The `<pc-sounds>` this slot was added to, captured at connect time.
|
|
@@ -38,20 +39,31 @@ class SoundSlotElement extends AsyncElement {
|
|
|
38
39
|
*/
|
|
39
40
|
private _soundElement: SoundComponentElement | null = null;
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Incremented on every connect and disconnect, and captured by connectedCallback on entry —
|
|
44
|
+
* a resume from an await abandons itself if the value has moved on, so a stale callback can
|
|
45
|
+
* neither act on a torn-down tree nor add its slot alongside a re-inserted element's own
|
|
46
|
+
* callback.
|
|
47
|
+
*/
|
|
48
|
+
private _connectionGeneration = 0;
|
|
49
|
+
|
|
41
50
|
/**
|
|
42
51
|
* The sound slot.
|
|
43
52
|
*/
|
|
44
53
|
soundSlot: SoundSlot | null = null;
|
|
45
54
|
|
|
46
55
|
async connectedCallback() {
|
|
56
|
+
const generation = ++this._connectionGeneration;
|
|
57
|
+
|
|
47
58
|
const soundElement = this.soundElement;
|
|
48
59
|
await soundElement?.ready();
|
|
49
60
|
|
|
50
|
-
// The element may have been removed
|
|
51
|
-
//
|
|
52
|
-
// already be gone - see the
|
|
61
|
+
// The element may have been removed (perhaps re-inserted, which runs a callback of its
|
|
62
|
+
// own), or its parent torn down, while we were waiting. A <pc-app> disconnects before
|
|
63
|
+
// its children, so by the time we resume the component can already be gone - see the
|
|
64
|
+
// matching guard in disconnectedCallback below.
|
|
53
65
|
const component = soundElement?.component;
|
|
54
|
-
if (
|
|
66
|
+
if (generation !== this._connectionGeneration || !component) {
|
|
55
67
|
return;
|
|
56
68
|
}
|
|
57
69
|
|
|
@@ -78,12 +90,16 @@ class SoundSlotElement extends AsyncElement {
|
|
|
78
90
|
}
|
|
79
91
|
|
|
80
92
|
disconnectedCallback() {
|
|
93
|
+
// Invalidate any connectedCallback still suspended on an await
|
|
94
|
+
this._connectionGeneration++;
|
|
95
|
+
|
|
81
96
|
// Uses the cached parent rather than a fresh lookup, since parentElement is already null
|
|
82
97
|
// by now. The component itself is null if the parent <pc-sound> (or the whole <pc-app>) is
|
|
83
98
|
// being torn down — parents disconnect first and have already removed the component.
|
|
84
99
|
this._soundElement?.component?.removeSlot(this._name);
|
|
85
100
|
this._soundElement = null;
|
|
86
101
|
this.soundSlot = null;
|
|
102
|
+
this._resetReady();
|
|
87
103
|
}
|
|
88
104
|
|
|
89
105
|
protected get soundElement(): SoundComponentElement | null {
|
|
@@ -310,10 +326,4 @@ class SoundSlotElement extends AsyncElement {
|
|
|
310
326
|
|
|
311
327
|
customElements.define('pc-sound', SoundSlotElement);
|
|
312
328
|
|
|
313
|
-
declare global {
|
|
314
|
-
interface HTMLElementTagNameMap {
|
|
315
|
-
'pc-sound': SoundSlotElement;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
329
|
export { SoundSlotElement };
|
package/src/entity.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AppBase
|
|
1
|
+
import type { AppBase } from 'playcanvas';
|
|
2
|
+
import { Entity, Vec3 } from 'playcanvas';
|
|
2
3
|
|
|
3
4
|
import type { AppElement } from './app';
|
|
4
5
|
import { AsyncElement } from './async-element';
|
|
@@ -62,7 +63,7 @@ class EntityElement extends AsyncElement {
|
|
|
62
63
|
/**
|
|
63
64
|
* The pointer event listeners for the entity.
|
|
64
65
|
*/
|
|
65
|
-
private _listeners:
|
|
66
|
+
private _listeners: Record<string, EventListener[]> = {};
|
|
66
67
|
|
|
67
68
|
/**
|
|
68
69
|
* The event types for which an inline `onpointer*` attribute is currently present.
|
|
@@ -92,7 +93,14 @@ class EntityElement extends AsyncElement {
|
|
|
92
93
|
return this._entity;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Creates the backing entity. Called by the containing `<pc-app>` element during its boot
|
|
98
|
+
* sweep, and on connection for elements inserted while the application is already running.
|
|
99
|
+
*
|
|
100
|
+
* @param app - The application to create the entity in.
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
_createEntity(app: AppBase) {
|
|
96
104
|
// Guard against double creation. When a subtree is inserted at runtime (e.g. cloning a
|
|
97
105
|
// `<template>`), an ancestor's connectedCallback eagerly creates descendant entities; the
|
|
98
106
|
// descendants' own connectedCallbacks would otherwise create them a second time.
|
|
@@ -128,8 +136,10 @@ class EntityElement extends AsyncElement {
|
|
|
128
136
|
|
|
129
137
|
/**
|
|
130
138
|
* Handles the destruction of the backing entity. Resets the element so a later re-insertion
|
|
131
|
-
* starts clean: `_built` must be cleared alongside `_entity`, or
|
|
132
|
-
* and a re-created entity would never be parented.
|
|
139
|
+
* starts clean: `_built` must be cleared alongside `_entity`, or _buildHierarchy would bail
|
|
140
|
+
* and a re-created entity would never be parented. Readiness is re-armed for the same
|
|
141
|
+
* reason — with the entity gone, a resolved ready promise would resume its awaiters against
|
|
142
|
+
* a null `entity`.
|
|
133
143
|
*
|
|
134
144
|
* @param entity - The entity that was destroyed.
|
|
135
145
|
*/
|
|
@@ -138,9 +148,19 @@ class EntityElement extends AsyncElement {
|
|
|
138
148
|
this._appElement = null;
|
|
139
149
|
this._entity = null;
|
|
140
150
|
this._built = false;
|
|
151
|
+
this._resetReady();
|
|
141
152
|
}
|
|
142
153
|
|
|
143
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Parents the backing entity: under the entity of the nearest ancestor `<pc-entity>` when
|
|
156
|
+
* there is one, and under the application root otherwise. Called by the containing `<pc-app>`
|
|
157
|
+
* element once a sweep has created every entity, so a parent's existence never depends on
|
|
158
|
+
* document order.
|
|
159
|
+
*
|
|
160
|
+
* @param app - The application whose root adopts parentless entities.
|
|
161
|
+
* @internal
|
|
162
|
+
*/
|
|
163
|
+
_buildHierarchy(app: AppBase) {
|
|
144
164
|
if (!this.entity || this._built) return;
|
|
145
165
|
this._built = true;
|
|
146
166
|
|
|
@@ -168,19 +188,19 @@ class EntityElement extends AsyncElement {
|
|
|
168
188
|
}
|
|
169
189
|
|
|
170
190
|
// If app is already running, create entity immediately
|
|
171
|
-
if (closestApp.
|
|
191
|
+
if (closestApp._hierarchyReady) {
|
|
172
192
|
const app = closestApp.app!;
|
|
173
193
|
|
|
174
|
-
this.
|
|
175
|
-
this.
|
|
194
|
+
this._createEntity(app);
|
|
195
|
+
this._buildHierarchy(app);
|
|
176
196
|
|
|
177
197
|
// Handle any child entities that might exist
|
|
178
198
|
const childEntities = this.querySelectorAll<EntityElement>('pc-entity');
|
|
179
199
|
childEntities.forEach((child) => {
|
|
180
|
-
child.
|
|
200
|
+
child._createEntity(app);
|
|
181
201
|
});
|
|
182
202
|
childEntities.forEach((child) => {
|
|
183
|
-
child.
|
|
203
|
+
child._buildHierarchy(app);
|
|
184
204
|
});
|
|
185
205
|
}
|
|
186
206
|
}
|
|
@@ -392,7 +412,7 @@ class EntityElement extends AsyncElement {
|
|
|
392
412
|
|
|
393
413
|
removeEventListener(type: string, listener: EventListener, options?: boolean | EventListenerOptions) {
|
|
394
414
|
if (this._listeners[type]) {
|
|
395
|
-
this._listeners[type] = this._listeners[type].filter(l => l !== listener);
|
|
415
|
+
this._listeners[type] = this._listeners[type].filter((l) => l !== listener);
|
|
396
416
|
}
|
|
397
417
|
super.removeEventListener(type, listener, options);
|
|
398
418
|
if (type.startsWith('pointer')) {
|
|
@@ -400,17 +420,20 @@ class EntityElement extends AsyncElement {
|
|
|
400
420
|
}
|
|
401
421
|
}
|
|
402
422
|
|
|
403
|
-
|
|
423
|
+
/**
|
|
424
|
+
* Whether the element has a listener for an event type, registered either with
|
|
425
|
+
* {@link addEventListener} or with the matching inline `onpointer*` attribute. Read by the
|
|
426
|
+
* containing `<pc-app>` element to gate pointer event synthesis.
|
|
427
|
+
*
|
|
428
|
+
* @param type - The event type.
|
|
429
|
+
* @returns Whether a listener is registered.
|
|
430
|
+
* @internal
|
|
431
|
+
*/
|
|
432
|
+
_hasListeners(type: string): boolean {
|
|
404
433
|
return Boolean(this._listeners[type]?.length) || this._inlineHandlerTypes.has(type);
|
|
405
434
|
}
|
|
406
435
|
}
|
|
407
436
|
|
|
408
437
|
customElements.define('pc-entity', EntityElement);
|
|
409
438
|
|
|
410
|
-
declare global {
|
|
411
|
-
interface HTMLElementTagNameMap {
|
|
412
|
-
'pc-entity': EntityElement;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
439
|
export { EntityElement };
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module EngineWebComponents
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
/* eslint-disable import/order */
|
|
10
|
+
/* eslint-disable import-x/order */
|
|
11
11
|
|
|
12
12
|
// Note that order matters here (e.g. pc-entity must be defined before components)
|
|
13
13
|
import { AsyncElement, whenReady } from './async-element';
|
|
@@ -40,6 +40,50 @@ import { ModelElement } from './model';
|
|
|
40
40
|
import { SceneElement } from './scene';
|
|
41
41
|
import { SkyElement } from './sky';
|
|
42
42
|
|
|
43
|
+
import type {
|
|
44
|
+
ScriptAttributesChangeEvent,
|
|
45
|
+
ScriptEnableChangeEvent,
|
|
46
|
+
ScriptNameChangeEvent
|
|
47
|
+
} from './components/script-component';
|
|
48
|
+
|
|
49
|
+
declare global {
|
|
50
|
+
interface HTMLElementEventMap {
|
|
51
|
+
scriptattributeschange: ScriptAttributesChangeEvent;
|
|
52
|
+
scriptenablechange: ScriptEnableChangeEvent;
|
|
53
|
+
scriptnamechange: ScriptNameChangeEvent;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface HTMLElementTagNameMap {
|
|
57
|
+
'pc-app': AppElement;
|
|
58
|
+
'pc-asset': AssetElement;
|
|
59
|
+
'pc-button': ButtonComponentElement;
|
|
60
|
+
'pc-camera': CameraComponentElement;
|
|
61
|
+
'pc-collision': CollisionComponentElement;
|
|
62
|
+
'pc-element': ElementComponentElement;
|
|
63
|
+
'pc-entity': EntityElement;
|
|
64
|
+
'pc-gsplat': GSplatComponentElement;
|
|
65
|
+
'pc-layoutchild': LayoutChildComponentElement;
|
|
66
|
+
'pc-layoutgroup': LayoutGroupComponentElement;
|
|
67
|
+
'pc-light': LightComponentElement;
|
|
68
|
+
'pc-listener': ListenerComponentElement;
|
|
69
|
+
'pc-material': MaterialElement;
|
|
70
|
+
'pc-model': ModelElement;
|
|
71
|
+
'pc-module': ModuleElement;
|
|
72
|
+
'pc-particles': ParticleSystemComponentElement;
|
|
73
|
+
'pc-render': RenderComponentElement;
|
|
74
|
+
'pc-rigidbody': RigidBodyComponentElement;
|
|
75
|
+
'pc-scene': SceneElement;
|
|
76
|
+
'pc-screen': ScreenComponentElement;
|
|
77
|
+
'pc-script': ScriptElement;
|
|
78
|
+
'pc-scripts': ScriptComponentElement;
|
|
79
|
+
'pc-scrollbar': ScrollbarComponentElement;
|
|
80
|
+
'pc-scrollview': ScrollViewComponentElement;
|
|
81
|
+
'pc-sky': SkyElement;
|
|
82
|
+
'pc-sound': SoundSlotElement;
|
|
83
|
+
'pc-sounds': SoundComponentElement;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
43
87
|
export {
|
|
44
88
|
AsyncElement,
|
|
45
89
|
ModuleElement,
|
package/src/loading-bar.ts
CHANGED
|
@@ -59,14 +59,14 @@ class LoadingBar {
|
|
|
59
59
|
// aria-valuenow is set, which is what marks a progressbar indeterminate. jsdom has no Web
|
|
60
60
|
// Animations API, so the guard degrades to a static bar there rather than crashing boot.
|
|
61
61
|
if (typeof this._fill.animate === 'function') {
|
|
62
|
-
this._sweep = this._fill.animate(
|
|
63
|
-
{ transform: 'scaleX(0.25) translateX(-100%)' },
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
this._sweep = this._fill.animate(
|
|
63
|
+
[{ transform: 'scaleX(0.25) translateX(-100%)' }, { transform: 'scaleX(0.25) translateX(500%)' }],
|
|
64
|
+
{
|
|
65
|
+
duration: 1000,
|
|
66
|
+
iterations: Infinity,
|
|
67
|
+
easing: 'ease-in-out'
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|