@playcanvas/web-components 0.11.1 → 0.13.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/README.md +1 -1
- package/dist/app.d.cts +246 -0
- package/dist/app.d.ts +38 -13
- package/dist/asset.d.cts +218 -0
- package/dist/asset.d.ts +145 -6
- package/dist/async-element.d.cts +103 -0
- package/dist/async-element.d.ts +11 -8
- package/dist/colors.d.cts +1 -0
- package/dist/components/button-component.d.cts +186 -0
- package/dist/components/button-component.d.ts +1 -1
- package/dist/components/camera-component.d.cts +253 -0
- package/dist/components/camera-component.d.ts +1 -1
- package/dist/components/collision-component.d.cts +73 -0
- package/dist/components/collision-component.d.ts +17 -1
- package/dist/components/component.d.cts +82 -0
- package/dist/components/component.d.ts +20 -1
- package/dist/components/element-component.d.cts +316 -0
- package/dist/components/element-component.d.ts +1 -1
- package/dist/components/gsplat-component.d.cts +108 -0
- package/dist/components/gsplat-component.d.ts +1 -1
- package/dist/components/layoutchild-component.d.cts +110 -0
- package/dist/components/layoutchild-component.d.ts +1 -1
- package/dist/components/layoutgroup-component.d.cts +136 -0
- package/dist/components/layoutgroup-component.d.ts +1 -1
- package/dist/components/light-component.d.cts +264 -0
- package/dist/components/light-component.d.ts +1 -1
- package/dist/components/listener-component.d.cts +20 -0
- package/dist/components/listener-component.d.ts +1 -1
- package/dist/components/particlesystem-component.d.cts +52 -0
- package/dist/components/particlesystem-component.d.ts +1 -1
- package/dist/components/render-component.d.cts +76 -0
- package/dist/components/render-component.d.ts +1 -1
- package/dist/components/rigidbody-component.d.cts +88 -0
- package/dist/components/rigidbody-component.d.ts +1 -1
- package/dist/components/screen-component.d.cts +70 -0
- package/dist/components/screen-component.d.ts +1 -1
- package/dist/components/script-component.d.cts +163 -0
- package/dist/components/script-component.d.ts +1 -1
- package/dist/components/script.d.cts +94 -0
- package/dist/components/script.d.ts +1 -1
- package/dist/components/scrollbar-component.d.cts +69 -0
- package/dist/components/scrollbar-component.d.ts +1 -1
- package/dist/components/scrollview-component.d.cts +178 -0
- package/dist/components/scrollview-component.d.ts +1 -1
- package/dist/components/sound-component.d.cts +108 -0
- package/dist/components/sound-component.d.ts +1 -1
- package/dist/components/sound-slot.d.cts +134 -0
- package/dist/components/sound-slot.d.ts +2 -2
- package/dist/custom-elements.json +1127 -179
- package/dist/entity-base.d.cts +67 -0
- package/dist/entity-base.d.ts +67 -0
- package/dist/entity.d.cts +131 -0
- package/dist/entity.d.ts +3 -38
- package/dist/index.d.cts +79 -0
- package/dist/index.d.ts +35 -32
- package/dist/loading-bar.d.cts +35 -0
- package/dist/material.d.cts +1011 -0
- package/dist/material.d.ts +2 -1
- package/dist/model.d.cts +72 -0
- package/dist/model.d.ts +27 -5
- package/dist/module.d.cts +29 -0
- package/dist/module.d.ts +16 -10
- package/dist/node.d.cts +253 -0
- package/dist/node.d.ts +253 -0
- package/dist/parse.d.cts +147 -0
- package/dist/pwc.cjs +1496 -200
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +1497 -201
- 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 +1496 -202
- package/dist/pwc.mjs.map +1 -1
- package/dist/scene.d.cts +117 -0
- package/dist/scene.d.ts +1 -1
- package/dist/sky.d.cts +121 -0
- package/dist/sky.d.ts +1 -1
- package/dist/vscode.html-custom-data.json +127 -5
- package/dist/web-types.json +399 -59
- package/package.json +16 -7
- package/src/app.ts +137 -45
- package/src/asset.ts +439 -9
- package/src/async-element.ts +11 -8
- package/src/components/collision-component.ts +35 -0
- package/src/components/component.ts +93 -3
- package/src/entity-base.ts +136 -0
- package/src/entity.ts +23 -117
- package/src/index.ts +5 -0
- package/src/loading-bar.ts +2 -2
- package/src/material.ts +2 -2
- package/src/model.ts +79 -11
- package/src/module.ts +39 -20
- package/src/node.ts +715 -0
- package/src/sky.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcanvas/web-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"author": "PlayCanvas <support@playcanvas.com>",
|
|
5
5
|
"homepage": "https://playcanvas.com",
|
|
6
6
|
"description": "Web Components for the PlayCanvas Engine",
|
|
@@ -32,14 +32,23 @@
|
|
|
32
32
|
"web-types": "dist/web-types.json",
|
|
33
33
|
"exports": {
|
|
34
34
|
".": {
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
"import": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"default": "./dist/pwc.mjs"
|
|
38
|
+
},
|
|
39
|
+
"require": {
|
|
40
|
+
"types": "./dist/index.d.cts",
|
|
41
|
+
"default": "./dist/pwc.cjs"
|
|
42
|
+
}
|
|
38
43
|
},
|
|
39
44
|
"./dist/*": "./dist/*",
|
|
40
45
|
"./package.json": "./package.json"
|
|
41
46
|
},
|
|
42
47
|
"type": "module",
|
|
48
|
+
"sideEffects": true,
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18.3.0"
|
|
51
|
+
},
|
|
43
52
|
"files": [
|
|
44
53
|
"dist",
|
|
45
54
|
"src"
|
|
@@ -47,7 +56,7 @@
|
|
|
47
56
|
"scripts": {
|
|
48
57
|
"prebuild": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
|
|
49
58
|
"build": "rollup -c",
|
|
50
|
-
"postbuild": "npm run cem",
|
|
59
|
+
"postbuild": "node utils/fix-declarations.mjs && npm run cem",
|
|
51
60
|
"cem": "cem analyze && node utils/cem/validate.mjs",
|
|
52
61
|
"dev": "concurrently \"npm run watch\" \"npm run serve\"",
|
|
53
62
|
"docs": "typedoc",
|
|
@@ -89,9 +98,9 @@
|
|
|
89
98
|
"eslint": "9.39.5",
|
|
90
99
|
"globals": "17.9.0",
|
|
91
100
|
"jsdom": "30.0.1",
|
|
92
|
-
"mediabunny": "1.
|
|
101
|
+
"mediabunny": "1.53.0",
|
|
93
102
|
"opentype.js": "2.0.0",
|
|
94
|
-
"playcanvas": "2.
|
|
103
|
+
"playcanvas": "2.22.0-beta.12",
|
|
95
104
|
"prettier": "3.9.6",
|
|
96
105
|
"publint": "0.3.23",
|
|
97
106
|
"rollup": "4.62.4",
|
package/src/app.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { CameraComponent, GraphNode, GSplatComponent, Entity } from 'playcanvas';
|
|
1
|
+
import type { CameraComponent, GraphicsDevice, GraphNode, GSplatComponent, Entity } from 'playcanvas';
|
|
2
2
|
import {
|
|
3
3
|
AppBase,
|
|
4
4
|
AppOptions,
|
|
5
5
|
createGraphicsDevice,
|
|
6
6
|
ElementInput,
|
|
7
|
-
|
|
7
|
+
FILLMODE_NONE,
|
|
8
8
|
Keyboard,
|
|
9
9
|
Mouse,
|
|
10
10
|
Picker,
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
import type { AssetElement } from './asset';
|
|
68
68
|
import { AsyncElement } from './async-element';
|
|
69
69
|
import type { EntityElement } from './entity';
|
|
70
|
+
import type { EntityBaseElement } from './entity-base';
|
|
70
71
|
import { LoadingBar } from './loading-bar';
|
|
71
72
|
import type { MaterialElement } from './material';
|
|
72
73
|
import type { ModuleElement } from './module';
|
|
@@ -75,16 +76,45 @@ import { parseBool, parseEnum, parseNumber } from './parse';
|
|
|
75
76
|
/** The pointer event types the application synthesizes on `<pc-entity>` elements via picking. */
|
|
76
77
|
const pointerEventTypes = ['pointermove', 'pointerdown', 'pointerup', 'pointerenter', 'pointerleave'] as const;
|
|
77
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Gives `pc-app` the sizing contract of a replaced element (`<video>`, `<img>`): a block-level
|
|
81
|
+
* box that the page's CSS sizes, defaulting to the canvas's own 300x150 intrinsic size, with the
|
|
82
|
+
* canvas and loading bar anchored to it. `:where()` keeps every declaration at zero specificity,
|
|
83
|
+
* so any page rule - however plain - overrides these defaults.
|
|
84
|
+
*/
|
|
85
|
+
const ensureBaseStyles = () => {
|
|
86
|
+
const id = 'pc-app-styles';
|
|
87
|
+
if (document.getElementById(id)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const style = document.createElement('style');
|
|
91
|
+
style.id = id;
|
|
92
|
+
style.textContent = ':where(pc-app) { display: block; position: relative; width: 300px; height: 150px; }';
|
|
93
|
+
document.head.appendChild(style);
|
|
94
|
+
};
|
|
95
|
+
|
|
78
96
|
/**
|
|
79
97
|
* The AppElement interface provides properties and methods for manipulating
|
|
80
98
|
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-app/ | `<pc-app>`} elements.
|
|
81
99
|
* The AppElement interface also inherits the properties and methods of the
|
|
82
100
|
* {@link HTMLElement} interface.
|
|
83
101
|
*
|
|
102
|
+
* The element is sized like a replaced element such as `<video>`: a block-level box that the
|
|
103
|
+
* page's CSS controls, 300x150 by default. The application's canvas always fills the element,
|
|
104
|
+
* and the drawing buffer resolution follows the element's size (capped by `max-pixel-ratio`),
|
|
105
|
+
* tracked live via a ResizeObserver — so the element can be embedded at any size, resized by
|
|
106
|
+
* its container, or made fullscreen with ordinary CSS such as `width: 100vw; height: 100dvh`.
|
|
107
|
+
*
|
|
84
108
|
* @fires {ProgressEvent} progress - Fired while the application preloads its assets. `loaded` and
|
|
85
109
|
* `total` are asset counts, not bytes, and an asset that fails to load still counts as loaded.
|
|
86
110
|
* Fired at least once per boot, and the final event always has `loaded` equal to `total`. Does
|
|
87
111
|
* not bubble.
|
|
112
|
+
*
|
|
113
|
+
* @fires {ErrorEvent} error - Fired when the application cannot boot because no graphics device
|
|
114
|
+
* could be created (for example, a browser with WebGL disabled). `message` names the requested
|
|
115
|
+
* backends and `error` holds the underlying failure. The element never becomes ready
|
|
116
|
+
* and `app` stays `null` — listen for this event to show a fallback UI. Removing the element and
|
|
117
|
+
* re-inserting it retries the boot with its current attributes. Does not bubble.
|
|
88
118
|
*/
|
|
89
119
|
class AppElement extends AsyncElement {
|
|
90
120
|
/**
|
|
@@ -133,10 +163,11 @@ class AppElement extends AsyncElement {
|
|
|
133
163
|
|
|
134
164
|
/**
|
|
135
165
|
* The elements backing this application's entities, keyed by the entity itself. Registered
|
|
136
|
-
* by EntityElement at creation and removed when an entity is
|
|
137
|
-
* scene nodes back to their owning elements by
|
|
166
|
+
* by EntityElement at creation (and NodeElement at binding) and removed when an entity is
|
|
167
|
+
* destroyed or unbound, this joins engine scene nodes back to their owning elements by
|
|
168
|
+
* identity - never by name.
|
|
138
169
|
*/
|
|
139
|
-
private _entityElements = new Map<GraphNode,
|
|
170
|
+
private _entityElements = new Map<GraphNode, EntityBaseElement>();
|
|
140
171
|
|
|
141
172
|
private _picker: Picker | null = null;
|
|
142
173
|
|
|
@@ -148,7 +179,7 @@ class AppElement extends AsyncElement {
|
|
|
148
179
|
pointermove: false
|
|
149
180
|
};
|
|
150
181
|
|
|
151
|
-
private _hoveredEntity:
|
|
182
|
+
private _hoveredEntity: EntityBaseElement | null = null;
|
|
152
183
|
|
|
153
184
|
// Identifies the newest in-flight hover pick, so out-of-order results can be discarded
|
|
154
185
|
private _pickToken = 0;
|
|
@@ -163,6 +194,13 @@ class AppElement extends AsyncElement {
|
|
|
163
194
|
|
|
164
195
|
private _loadProgress = 0;
|
|
165
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Tracks the element's box so the drawing buffer and picker follow it. Created per boot once
|
|
199
|
+
* the application exists, and disconnected on teardown. `null` where ResizeObserver is
|
|
200
|
+
* unavailable (jsdom), where the boot-time resolution set is the only sizing that happens.
|
|
201
|
+
*/
|
|
202
|
+
private _resizeObserver: ResizeObserver | null = null;
|
|
203
|
+
|
|
166
204
|
/**
|
|
167
205
|
* The PlayCanvas application instance. `null` until the element is ready, and again once it
|
|
168
206
|
* has been removed from the document — await {@link whenReady} or the element's `ready()`
|
|
@@ -192,9 +230,6 @@ class AppElement extends AsyncElement {
|
|
|
192
230
|
constructor() {
|
|
193
231
|
super();
|
|
194
232
|
|
|
195
|
-
// Bind methods to maintain 'this' context
|
|
196
|
-
this._onWindowResize = this._onWindowResize.bind(this);
|
|
197
|
-
|
|
198
233
|
// Track pointer listeners being added to and removed from descendant entities.
|
|
199
234
|
// Registered once here rather than on every boot - the handlers no-op while there is no
|
|
200
235
|
// canvas, and a re-booted element must not stack a second set.
|
|
@@ -207,6 +242,10 @@ class AppElement extends AsyncElement {
|
|
|
207
242
|
async connectedCallback() {
|
|
208
243
|
const generation = ++this._bootGeneration;
|
|
209
244
|
|
|
245
|
+
// Installed before the loading bar is created: the bar anchors to this element, which
|
|
246
|
+
// these styles make a positioned block box
|
|
247
|
+
ensureBaseStyles();
|
|
248
|
+
|
|
210
249
|
// Created before the first await, so the bar is visible while modules and the graphics
|
|
211
250
|
// device are created, and exists before any disconnect could need to clean it up
|
|
212
251
|
if (this._loadingBar && !this._bar) {
|
|
@@ -225,8 +264,11 @@ class AppElement extends AsyncElement {
|
|
|
225
264
|
return;
|
|
226
265
|
}
|
|
227
266
|
|
|
228
|
-
// Create and append the canvas
|
|
267
|
+
// Create and append the canvas, filling the element's content box - the page sizes the
|
|
268
|
+
// element, and everything else follows. touch-action: none keeps touch drags driving the
|
|
269
|
+
// engine's input handlers instead of scrolling the page.
|
|
229
270
|
this._canvas = document.createElement('canvas');
|
|
271
|
+
this._canvas.style.cssText = 'display: block; width: 100%; height: 100%; touch-action: none;';
|
|
230
272
|
this.appendChild(this._canvas);
|
|
231
273
|
|
|
232
274
|
// Configure device types based on backend selection
|
|
@@ -239,14 +281,46 @@ class AppElement extends AsyncElement {
|
|
|
239
281
|
|
|
240
282
|
this._optionsLocked = true;
|
|
241
283
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
284
|
+
// createGraphicsDevice appends its final null-device fallback to the array in place, so
|
|
285
|
+
// the requested list is captured now for the failure message.
|
|
286
|
+
const requested = deviceTypes.join(', ');
|
|
287
|
+
|
|
288
|
+
let device: GraphicsDevice;
|
|
289
|
+
try {
|
|
290
|
+
device = await createGraphicsDevice(this._canvas, {
|
|
291
|
+
// @ts-ignore - alpha needs to be documented
|
|
292
|
+
alpha: this._alpha,
|
|
293
|
+
antialias: this._antialias,
|
|
294
|
+
depth: this._depthBuffer,
|
|
295
|
+
deviceTypes: deviceTypes,
|
|
296
|
+
stencil: this._stencilBuffer
|
|
297
|
+
});
|
|
298
|
+
} catch (error) {
|
|
299
|
+
// The element may have been removed while device creation was failing. The teardown
|
|
300
|
+
// has already cleaned up, and the failure belongs to a boot that no longer owns the
|
|
301
|
+
// element.
|
|
302
|
+
if (generation !== this._bootGeneration) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Return the element to its pre-boot state - no dead canvas, no loading bar stuck at
|
|
307
|
+
// zero - before announcing the failure. Readiness deliberately stays pending: nothing
|
|
308
|
+
// it would announce (the app, the entity hierarchy) exists, so a device-less element
|
|
309
|
+
// joins the documented never-ready cases and the failure surfaces through the error
|
|
310
|
+
// event instead.
|
|
311
|
+
if (this._canvas && this.contains(this._canvas)) {
|
|
312
|
+
this.removeChild(this._canvas);
|
|
313
|
+
}
|
|
314
|
+
this._canvas = null;
|
|
315
|
+
this._bar?.destroy();
|
|
316
|
+
this._bar = null;
|
|
317
|
+
|
|
318
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
319
|
+
const message = `pc-app failed to create a graphics device (${requested}) - ${reason}`;
|
|
320
|
+
console.error(message, error);
|
|
321
|
+
this.dispatchEvent(new ErrorEvent('error', { message, error }));
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
250
324
|
|
|
251
325
|
// The element may have been removed while the device was created. disconnectedCallback
|
|
252
326
|
// has already cleaned up the canvas; the device was created inside the await, so it is
|
|
@@ -330,11 +404,22 @@ class AppElement extends AsyncElement {
|
|
|
330
404
|
this._app = app;
|
|
331
405
|
app.init(createOptions);
|
|
332
406
|
|
|
333
|
-
|
|
407
|
+
// FILLMODE_NONE leaves the canvas's CSS sizing alone (the engine's other fill modes
|
|
408
|
+
// stamp window-derived pixel sizes onto it); RESOLUTION_AUTO sizes the drawing buffer
|
|
409
|
+
// from the canvas's client size
|
|
410
|
+
app.setCanvasFillMode(FILLMODE_NONE);
|
|
334
411
|
app.setCanvasResolution(RESOLUTION_AUTO);
|
|
335
412
|
|
|
336
413
|
this._pickerCreate();
|
|
337
414
|
|
|
415
|
+
// Track the element's box rather than the window: containers resize without any window
|
|
416
|
+
// event (splitter drags, flex reflow, animations). Guarded because jsdom has no
|
|
417
|
+
// ResizeObserver - there, the resolution set above is the only sizing that happens.
|
|
418
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
419
|
+
this._resizeObserver = new ResizeObserver(() => this._syncCanvasSize());
|
|
420
|
+
this._resizeObserver.observe(this);
|
|
421
|
+
}
|
|
422
|
+
|
|
338
423
|
// Get all pc-asset elements that are direct children of the pc-app element
|
|
339
424
|
const assetElements = this.querySelectorAll<AssetElement>(':scope > pc-asset');
|
|
340
425
|
for (const assetElement of Array.from(assetElements)) {
|
|
@@ -424,9 +509,6 @@ class AppElement extends AsyncElement {
|
|
|
424
509
|
// first rAF tick
|
|
425
510
|
app.once('frameend', () => this._bar?.complete());
|
|
426
511
|
|
|
427
|
-
// Handle window resize to keep the canvas responsive
|
|
428
|
-
window.addEventListener('resize', this._onWindowResize);
|
|
429
|
-
|
|
430
512
|
this._onReady();
|
|
431
513
|
});
|
|
432
514
|
}
|
|
@@ -456,8 +538,9 @@ class AppElement extends AsyncElement {
|
|
|
456
538
|
this._hierarchyReady = false;
|
|
457
539
|
this._resetReady();
|
|
458
540
|
|
|
459
|
-
//
|
|
460
|
-
|
|
541
|
+
// Stop tracking the element's size
|
|
542
|
+
this._resizeObserver?.disconnect();
|
|
543
|
+
this._resizeObserver = null;
|
|
461
544
|
|
|
462
545
|
// Remove the canvas
|
|
463
546
|
if (this._canvas && this.contains(this._canvas)) {
|
|
@@ -466,10 +549,18 @@ class AppElement extends AsyncElement {
|
|
|
466
549
|
}
|
|
467
550
|
}
|
|
468
551
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
552
|
+
/**
|
|
553
|
+
* Syncs the drawing buffer and the picker to the canvas's current CSS size. The picker must
|
|
554
|
+
* track the buffer, or picks would land at stale coordinates after a resize. Skipped while
|
|
555
|
+
* an XR session presents - the session owns the buffer size.
|
|
556
|
+
*/
|
|
557
|
+
private _syncCanvasSize() {
|
|
558
|
+
if (!this.app || this.app.xr?.active) {
|
|
559
|
+
return;
|
|
472
560
|
}
|
|
561
|
+
this.app.updateCanvasSize();
|
|
562
|
+
const { width, height } = this.app.graphicsDevice;
|
|
563
|
+
this._picker?.resize(width, height);
|
|
473
564
|
}
|
|
474
565
|
|
|
475
566
|
private _pickerCreate() {
|
|
@@ -493,8 +584,8 @@ class AppElement extends AsyncElement {
|
|
|
493
584
|
// created from onpointer* attributes when their elements were first upgraded, or
|
|
494
585
|
// listeners carried over from before a re-boot)
|
|
495
586
|
pointerEventTypes.forEach((type) => {
|
|
496
|
-
const anyListeners = Array.from(this.querySelectorAll<
|
|
497
|
-
entity._hasListeners(type)
|
|
587
|
+
const anyListeners = Array.from(this.querySelectorAll<EntityBaseElement>('pc-entity, pc-node')).some(
|
|
588
|
+
(entity) => entity._hasListeners(type)
|
|
498
589
|
);
|
|
499
590
|
if (anyListeners) {
|
|
500
591
|
this._onPointerListenerAdded(type);
|
|
@@ -528,14 +619,14 @@ class AppElement extends AsyncElement {
|
|
|
528
619
|
}
|
|
529
620
|
|
|
530
621
|
/**
|
|
531
|
-
* Registers the element that
|
|
532
|
-
* entity.
|
|
622
|
+
* Registers the element that fronts an entity. Called by EntityElement when it creates its
|
|
623
|
+
* entity, and by NodeElement when it binds one.
|
|
533
624
|
*
|
|
534
625
|
* @param entity - The entity.
|
|
535
|
-
* @param element - The element that
|
|
626
|
+
* @param element - The element that fronts it.
|
|
536
627
|
* @internal
|
|
537
628
|
*/
|
|
538
|
-
_registerEntityElement(entity: Entity, element:
|
|
629
|
+
_registerEntityElement(entity: Entity, element: EntityBaseElement) {
|
|
539
630
|
this._entityElements.set(entity, element);
|
|
540
631
|
}
|
|
541
632
|
|
|
@@ -550,27 +641,28 @@ class AppElement extends AsyncElement {
|
|
|
550
641
|
}
|
|
551
642
|
|
|
552
643
|
/**
|
|
553
|
-
* Returns the `<pc-entity>` element whose backing entity is `entity`, or
|
|
554
|
-
* entity
|
|
555
|
-
* model's instantiated hierarchy, or an entity created through the
|
|
644
|
+
* Returns the `<pc-entity>` or `<pc-node>` element whose backing entity is `entity`, or
|
|
645
|
+
* `null` if the entity is not fronted by an element of this application - for example, an
|
|
646
|
+
* unbound node inside a model's instantiated hierarchy, or an entity created through the
|
|
647
|
+
* engine API.
|
|
556
648
|
*
|
|
557
649
|
* @param entity - The entity to look up.
|
|
558
|
-
* @returns The element
|
|
650
|
+
* @returns The element fronting the entity, or `null`.
|
|
559
651
|
*/
|
|
560
|
-
elementFromEntity(entity: Entity):
|
|
652
|
+
elementFromEntity(entity: Entity): EntityBaseElement | null {
|
|
561
653
|
return this._entityElements.get(entity) ?? null;
|
|
562
654
|
}
|
|
563
655
|
|
|
564
656
|
/**
|
|
565
657
|
* Resolves the element that owns a picked node: the nearest node up the parent chain -
|
|
566
|
-
* starting with the node itself - that
|
|
567
|
-
* A hit inside a model's instantiated hierarchy therefore resolves to the
|
|
568
|
-
* the model.
|
|
658
|
+
* starting with the node itself - that is fronted by a `<pc-entity>` or `<pc-node>` of this
|
|
659
|
+
* application. A hit inside a model's instantiated hierarchy therefore resolves to the
|
|
660
|
+
* nearest bound `<pc-node>`, or failing that the element hosting the model.
|
|
569
661
|
*
|
|
570
662
|
* @param node - The picked node, or `null`.
|
|
571
663
|
* @returns The owning element, or `null`.
|
|
572
664
|
*/
|
|
573
|
-
private _elementFromNode(node: GraphNode | null):
|
|
665
|
+
private _elementFromNode(node: GraphNode | null): EntityBaseElement | null {
|
|
574
666
|
while (node !== null) {
|
|
575
667
|
const element = this._entityElements.get(node);
|
|
576
668
|
if (element) {
|
|
@@ -589,7 +681,7 @@ class AppElement extends AsyncElement {
|
|
|
589
681
|
* @param type - The pointer event type a listener is required for.
|
|
590
682
|
* @returns The nearest listening element, or `null`.
|
|
591
683
|
*/
|
|
592
|
-
private _elementWithListener(node: GraphNode | null, type: string):
|
|
684
|
+
private _elementWithListener(node: GraphNode | null, type: string): EntityBaseElement | null {
|
|
593
685
|
while (node !== null) {
|
|
594
686
|
const element = this._entityElements.get(node);
|
|
595
687
|
if (element?._hasListeners(type)) {
|
|
@@ -715,7 +807,7 @@ class AppElement extends AsyncElement {
|
|
|
715
807
|
}
|
|
716
808
|
|
|
717
809
|
private _onPointerListenerRemoved(type: string) {
|
|
718
|
-
const hasListeners = Array.from(this.querySelectorAll<
|
|
810
|
+
const hasListeners = Array.from(this.querySelectorAll<EntityBaseElement>('pc-entity, pc-node')).some((entity) =>
|
|
719
811
|
entity._hasListeners(type)
|
|
720
812
|
);
|
|
721
813
|
|
|
@@ -859,7 +951,7 @@ class AppElement extends AsyncElement {
|
|
|
859
951
|
this._maxPixelRatio = value;
|
|
860
952
|
if (this.app) {
|
|
861
953
|
this.app.graphicsDevice.maxPixelRatio = value;
|
|
862
|
-
this.
|
|
954
|
+
this._syncCanvasSize();
|
|
863
955
|
}
|
|
864
956
|
}
|
|
865
957
|
|