@playcanvas/web-components 0.12.0 → 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 +26 -3
- package/dist/asset.d.cts +218 -0
- package/dist/asset.d.ts +1 -1
- package/dist/async-element.d.cts +103 -0
- package/dist/async-element.d.ts +6 -4
- 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 +1 -1
- package/dist/components/component.d.cts +82 -0
- package/dist/components/component.d.ts +1 -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 +79 -21
- package/dist/entity-base.d.cts +67 -0
- package/dist/entity-base.d.ts +2 -2
- package/dist/entity.d.cts +131 -0
- package/dist/entity.d.ts +1 -1
- package/dist/index.d.cts +79 -0
- package/dist/index.d.ts +33 -33
- package/dist/loading-bar.d.cts +35 -0
- package/dist/material.d.cts +1011 -0
- package/dist/model.d.cts +72 -0
- package/dist/model.d.ts +1 -1
- 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 +1 -1
- package/dist/parse.d.cts +147 -0
- package/dist/pwc.cjs +141 -41
- package/dist/pwc.cjs.map +1 -1
- package/dist/pwc.js +142 -42
- 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 +142 -42
- 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 +2 -2
- package/dist/web-types.json +41 -5
- package/package.json +16 -7
- package/src/app.ts +119 -30
- package/src/async-element.ts +4 -2
- package/src/loading-bar.ts +2 -2
- package/src/module.ts +39 -20
package/dist/pwc.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { basisInitialize, WasmModule, Vec3, Color, Vec4, Quat, Vec2, createGraphicsDevice, AppOptions, Keyboard, Mouse, ElementInput, AnimComponentSystem, AnimationComponentSystem, AudioListenerComponentSystem, ButtonComponentSystem, CameraComponentSystem, CollisionComponentSystem, ElementComponentSystem, GSplatComponentSystem, JointComponentSystem, LayoutChildComponentSystem, LayoutGroupComponentSystem, LightComponentSystem, ModelComponentSystem, ParticleSystemComponentSystem, RenderComponentSystem, RigidBodyComponentSystem, ScreenComponentSystem, ScriptComponentSystem, ScrollbarComponentSystem, ScrollViewComponentSystem, SoundComponentSystem, SpriteComponentSystem, ZoneComponentSystem, AnimClipHandler, AnimationHandler, AnimStateGraphHandler, AudioHandler, BinaryHandler, CssHandler, ContainerHandler, CubemapHandler, FolderHandler, FontHandler, GSplatHandler, HierarchyHandler, HtmlHandler, JsonHandler, MaterialHandler, ModelHandler, RenderHandler, ScriptHandler, SceneHandler, ShaderHandler, SpriteHandler, TemplateHandler, TextHandler, TextureAtlasHandler, TextureHandler, SoundManager, Lightmapper, BatchManager, XrManager, AppBase,
|
|
1
|
+
import { basisInitialize, WasmModule, Vec3, Color, Vec4, Quat, Vec2, createGraphicsDevice, AppOptions, Keyboard, Mouse, ElementInput, AnimComponentSystem, AnimationComponentSystem, AudioListenerComponentSystem, ButtonComponentSystem, CameraComponentSystem, CollisionComponentSystem, ElementComponentSystem, GSplatComponentSystem, JointComponentSystem, LayoutChildComponentSystem, LayoutGroupComponentSystem, LightComponentSystem, ModelComponentSystem, ParticleSystemComponentSystem, RenderComponentSystem, RigidBodyComponentSystem, ScreenComponentSystem, ScriptComponentSystem, ScrollbarComponentSystem, ScrollViewComponentSystem, SoundComponentSystem, SpriteComponentSystem, ZoneComponentSystem, AnimClipHandler, AnimationHandler, AnimStateGraphHandler, AudioHandler, BinaryHandler, CssHandler, ContainerHandler, CubemapHandler, FolderHandler, FontHandler, GSplatHandler, HierarchyHandler, HtmlHandler, JsonHandler, MaterialHandler, ModelHandler, RenderHandler, ScriptHandler, SceneHandler, ShaderHandler, SpriteHandler, TemplateHandler, TextHandler, TextureAtlasHandler, TextureHandler, SoundManager, Lightmapper, BatchManager, XrManager, AppBase, FILLMODE_NONE, RESOLUTION_AUTO, Picker, MeshInstance, Entity, Asset, SPRITE_RENDERMODE_SIMPLE, FILTER_LINEAR_MIPMAP_LINEAR, FILTER_LINEAR, ADDRESS_REPEAT, SPRITE_RENDERMODE_SLICED, SPRITE_RENDERMODE_TILED, ADDRESS_CLAMP_TO_EDGE, ADDRESS_MIRRORED_REPEAT, FILTER_NEAREST, FILTER_NEAREST_MIPMAP_NEAREST, FILTER_LINEAR_MIPMAP_NEAREST, FILTER_NEAREST_MIPMAP_LINEAR, BUTTON_TRANSITION_MODE_TINT, BUTTON_TRANSITION_MODE_SPRITE_CHANGE, TONEMAP_NONE, PROJECTION_PERSPECTIVE, GAMMA_SRGB, GAMMA_NONE, XRTYPE_VR, TONEMAP_LINEAR, TONEMAP_FILMIC, TONEMAP_HEJL, TONEMAP_ACES, TONEMAP_ACES2, TONEMAP_NEUTRAL, PROJECTION_ORTHOGRAPHIC, ORIENTATION_HORIZONTAL, FITTING_NONE, FITTING_STRETCH, FITTING_SHRINK, FITTING_BOTH, ORIENTATION_VERTICAL, SHADOW_PCF3_32F, SHADOW_PCF1_16F, SHADOW_PCF1_32F, SHADOW_PCF3_16F, SHADOW_PCF5_16F, SHADOW_PCF5_32F, SHADOW_VSM_16F, SHADOW_VSM_32F, SHADOW_PCSS_32F, StandardMaterial, BLEND_NONE, CULLFACE_BACK, FRESNEL_SCHLICK, SPECOCC_AO, BLEND_NORMAL, BLEND_ADDITIVE, BLEND_ADDITIVEALPHA, BLEND_PREMULTIPLIED, BLEND_MULTIPLICATIVE, BLEND_MULTIPLICATIVE2X, BLEND_SCREEN, BLEND_MIN, BLEND_MAX, BLEND_SUBTRACTIVE, CULLFACE_NONE, CULLFACE_FRONT, CULLFACE_FRONTANDBACK, FRESNEL_NONE, SPECOCC_NONE, SPECOCC_GLOSSDEPENDENT, SCALEMODE_NONE, SCALEMODE_BLEND, SCROLL_MODE_BOUNCE, SCROLLBAR_VISIBILITY_SHOW_WHEN_REQUIRED, SCROLLBAR_VISIBILITY_SHOW_ALWAYS, SCROLL_MODE_CLAMP, SCROLL_MODE_INFINITE, EnvLighting, LAYERID_SKYBOX } from 'playcanvas';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Base class for all PlayCanvas Web Components that initialize asynchronously.
|
|
@@ -108,12 +108,18 @@ async function whenReady(target) {
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* The ModuleElement interface provides properties and methods for manipulating
|
|
111
|
-
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-module/ | `<pc-module>`}
|
|
112
|
-
* The ModuleElement interface also inherits the properties and methods of the
|
|
113
|
-
* {@link
|
|
111
|
+
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-module/ | `<pc-module>`}
|
|
112
|
+
* elements. The ModuleElement interface also inherits the properties and methods of the
|
|
113
|
+
* {@link AsyncElement} interface.
|
|
114
|
+
*
|
|
115
|
+
* The attributes are read once, when the module starts loading - on the element's first
|
|
116
|
+
* connection, or earlier if a containing `<pc-app>` boots first and collects it - so changing
|
|
117
|
+
* them later has no effect. The element becomes ready once the module has loaded. WebAssembly
|
|
118
|
+
* modules configure engine-global state that never unloads, so readiness is not re-armed by
|
|
119
|
+
* removing the element, and a re-inserted element does not load again.
|
|
114
120
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
121
|
+
* A `<pc-module>` without a `name` warns and never becomes ready; a containing `<pc-app>` still
|
|
122
|
+
* boots.
|
|
117
123
|
*
|
|
118
124
|
* @attribute {string} name - The name of the WebAssembly module to configure, e.g. `Basis` or
|
|
119
125
|
* `Ammo`.
|
|
@@ -122,19 +128,22 @@ async function whenReady(target) {
|
|
|
122
128
|
* @attribute {string} fallback - The URL of the module's asm.js fallback script, used when
|
|
123
129
|
* WebAssembly is unavailable.
|
|
124
130
|
*/
|
|
125
|
-
class ModuleElement extends
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
super();
|
|
130
|
-
this.loadPromise = this.loadModule();
|
|
131
|
+
class ModuleElement extends AsyncElement {
|
|
132
|
+
_loadPromise = null;
|
|
133
|
+
connectedCallback() {
|
|
134
|
+
this._getLoadPromise();
|
|
131
135
|
}
|
|
132
|
-
async
|
|
136
|
+
async _loadModule() {
|
|
133
137
|
const name = this.getAttribute('name');
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
+
if (!name) {
|
|
139
|
+
console.warn("pc-module requires a 'name' attribute - no module was configured");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const config = {
|
|
143
|
+
glueUrl: this.getAttribute('glue') ?? undefined,
|
|
144
|
+
wasmUrl: this.getAttribute('wasm') ?? undefined,
|
|
145
|
+
fallbackUrl: this.getAttribute('fallback') ?? undefined
|
|
146
|
+
};
|
|
138
147
|
if (name === 'Basis') {
|
|
139
148
|
basisInitialize(config);
|
|
140
149
|
}
|
|
@@ -144,16 +153,22 @@ class ModuleElement extends HTMLElement {
|
|
|
144
153
|
WasmModule.getInstance(name, () => resolve());
|
|
145
154
|
});
|
|
146
155
|
}
|
|
156
|
+
this._onReady();
|
|
147
157
|
}
|
|
148
158
|
/**
|
|
149
|
-
* Returns the promise that settles when the module has loaded
|
|
150
|
-
* `<pc-app>`
|
|
159
|
+
* Returns the promise that settles when the module has loaded, starting the load if it has
|
|
160
|
+
* not already started - a containing `<pc-app>` boots in document order, so it may collect
|
|
161
|
+
* this element before the element's own connectedCallback has run. A missing `name` resolves
|
|
162
|
+
* the promise without configuring anything, so a misconfigured module never blocks the app.
|
|
151
163
|
*
|
|
152
164
|
* @returns The load promise.
|
|
153
165
|
* @internal
|
|
154
166
|
*/
|
|
155
167
|
_getLoadPromise() {
|
|
156
|
-
|
|
168
|
+
if (!this._loadPromise) {
|
|
169
|
+
this._loadPromise = this._loadModule();
|
|
170
|
+
}
|
|
171
|
+
return this._loadPromise;
|
|
157
172
|
}
|
|
158
173
|
}
|
|
159
174
|
customElements.define('pc-module', ModuleElement);
|
|
@@ -183,9 +198,9 @@ class LoadingBar {
|
|
|
183
198
|
this._track.setAttribute('aria-label', 'Loading');
|
|
184
199
|
this._track.setAttribute('aria-valuemin', '0');
|
|
185
200
|
this._track.setAttribute('aria-valuemax', '100');
|
|
186
|
-
//
|
|
201
|
+
// Anchored to the pc-app element, which the library's base styles make a positioned box
|
|
187
202
|
this._track.style.cssText = [
|
|
188
|
-
'position:
|
|
203
|
+
'position: absolute',
|
|
189
204
|
'top: 0',
|
|
190
205
|
'left: 0',
|
|
191
206
|
'width: 100%',
|
|
@@ -697,16 +712,44 @@ const getEntity = (ref) => {
|
|
|
697
712
|
|
|
698
713
|
/** The pointer event types the application synthesizes on `<pc-entity>` elements via picking. */
|
|
699
714
|
const pointerEventTypes = ['pointermove', 'pointerdown', 'pointerup', 'pointerenter', 'pointerleave'];
|
|
715
|
+
/**
|
|
716
|
+
* Gives `pc-app` the sizing contract of a replaced element (`<video>`, `<img>`): a block-level
|
|
717
|
+
* box that the page's CSS sizes, defaulting to the canvas's own 300x150 intrinsic size, with the
|
|
718
|
+
* canvas and loading bar anchored to it. `:where()` keeps every declaration at zero specificity,
|
|
719
|
+
* so any page rule - however plain - overrides these defaults.
|
|
720
|
+
*/
|
|
721
|
+
const ensureBaseStyles = () => {
|
|
722
|
+
const id = 'pc-app-styles';
|
|
723
|
+
if (document.getElementById(id)) {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
const style = document.createElement('style');
|
|
727
|
+
style.id = id;
|
|
728
|
+
style.textContent = ':where(pc-app) { display: block; position: relative; width: 300px; height: 150px; }';
|
|
729
|
+
document.head.appendChild(style);
|
|
730
|
+
};
|
|
700
731
|
/**
|
|
701
732
|
* The AppElement interface provides properties and methods for manipulating
|
|
702
733
|
* {@link https://developer.playcanvas.com/user-manual/web-components/tags/pc-app/ | `<pc-app>`} elements.
|
|
703
734
|
* The AppElement interface also inherits the properties and methods of the
|
|
704
735
|
* {@link HTMLElement} interface.
|
|
705
736
|
*
|
|
737
|
+
* The element is sized like a replaced element such as `<video>`: a block-level box that the
|
|
738
|
+
* page's CSS controls, 300x150 by default. The application's canvas always fills the element,
|
|
739
|
+
* and the drawing buffer resolution follows the element's size (capped by `max-pixel-ratio`),
|
|
740
|
+
* tracked live via a ResizeObserver — so the element can be embedded at any size, resized by
|
|
741
|
+
* its container, or made fullscreen with ordinary CSS such as `width: 100vw; height: 100dvh`.
|
|
742
|
+
*
|
|
706
743
|
* @fires {ProgressEvent} progress - Fired while the application preloads its assets. `loaded` and
|
|
707
744
|
* `total` are asset counts, not bytes, and an asset that fails to load still counts as loaded.
|
|
708
745
|
* Fired at least once per boot, and the final event always has `loaded` equal to `total`. Does
|
|
709
746
|
* not bubble.
|
|
747
|
+
*
|
|
748
|
+
* @fires {ErrorEvent} error - Fired when the application cannot boot because no graphics device
|
|
749
|
+
* could be created (for example, a browser with WebGL disabled). `message` names the requested
|
|
750
|
+
* backends and `error` holds the underlying failure. The element never becomes ready
|
|
751
|
+
* and `app` stays `null` — listen for this event to show a fallback UI. Removing the element and
|
|
752
|
+
* re-inserting it retries the boot with its current attributes. Does not bubble.
|
|
710
753
|
*/
|
|
711
754
|
class AppElement extends AsyncElement {
|
|
712
755
|
/**
|
|
@@ -766,6 +809,12 @@ class AppElement extends AsyncElement {
|
|
|
766
809
|
};
|
|
767
810
|
_app = null;
|
|
768
811
|
_loadProgress = 0;
|
|
812
|
+
/**
|
|
813
|
+
* Tracks the element's box so the drawing buffer and picker follow it. Created per boot once
|
|
814
|
+
* the application exists, and disconnected on teardown. `null` where ResizeObserver is
|
|
815
|
+
* unavailable (jsdom), where the boot-time resolution set is the only sizing that happens.
|
|
816
|
+
*/
|
|
817
|
+
_resizeObserver = null;
|
|
769
818
|
/**
|
|
770
819
|
* The PlayCanvas application instance. `null` until the element is ready, and again once it
|
|
771
820
|
* has been removed from the document — await {@link whenReady} or the element's `ready()`
|
|
@@ -792,8 +841,6 @@ class AppElement extends AsyncElement {
|
|
|
792
841
|
*/
|
|
793
842
|
constructor() {
|
|
794
843
|
super();
|
|
795
|
-
// Bind methods to maintain 'this' context
|
|
796
|
-
this._onWindowResize = this._onWindowResize.bind(this);
|
|
797
844
|
// Track pointer listeners being added to and removed from descendant entities.
|
|
798
845
|
// Registered once here rather than on every boot - the handlers no-op while there is no
|
|
799
846
|
// canvas, and a re-booted element must not stack a second set.
|
|
@@ -804,6 +851,9 @@ class AppElement extends AsyncElement {
|
|
|
804
851
|
}
|
|
805
852
|
async connectedCallback() {
|
|
806
853
|
const generation = ++this._bootGeneration;
|
|
854
|
+
// Installed before the loading bar is created: the bar anchors to this element, which
|
|
855
|
+
// these styles make a positioned block box
|
|
856
|
+
ensureBaseStyles();
|
|
807
857
|
// Created before the first await, so the bar is visible while modules and the graphics
|
|
808
858
|
// device are created, and exists before any disconnect could need to clean it up
|
|
809
859
|
if (this._loadingBar && !this._bar) {
|
|
@@ -818,8 +868,11 @@ class AppElement extends AsyncElement {
|
|
|
818
868
|
if (generation !== this._bootGeneration) {
|
|
819
869
|
return;
|
|
820
870
|
}
|
|
821
|
-
// Create and append the canvas
|
|
871
|
+
// Create and append the canvas, filling the element's content box - the page sizes the
|
|
872
|
+
// element, and everything else follows. touch-action: none keeps touch drags driving the
|
|
873
|
+
// engine's input handlers instead of scrolling the page.
|
|
822
874
|
this._canvas = document.createElement('canvas');
|
|
875
|
+
this._canvas.style.cssText = 'display: block; width: 100%; height: 100%; touch-action: none;';
|
|
823
876
|
this.appendChild(this._canvas);
|
|
824
877
|
// Configure device types based on backend selection
|
|
825
878
|
const backendToDeviceTypes = {
|
|
@@ -829,14 +882,44 @@ class AppElement extends AsyncElement {
|
|
|
829
882
|
};
|
|
830
883
|
const deviceTypes = backendToDeviceTypes[this._backend] || [];
|
|
831
884
|
this._optionsLocked = true;
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
885
|
+
// createGraphicsDevice appends its final null-device fallback to the array in place, so
|
|
886
|
+
// the requested list is captured now for the failure message.
|
|
887
|
+
const requested = deviceTypes.join(', ');
|
|
888
|
+
let device;
|
|
889
|
+
try {
|
|
890
|
+
device = await createGraphicsDevice(this._canvas, {
|
|
891
|
+
// @ts-ignore - alpha needs to be documented
|
|
892
|
+
alpha: this._alpha,
|
|
893
|
+
antialias: this._antialias,
|
|
894
|
+
depth: this._depthBuffer,
|
|
895
|
+
deviceTypes: deviceTypes,
|
|
896
|
+
stencil: this._stencilBuffer
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
catch (error) {
|
|
900
|
+
// The element may have been removed while device creation was failing. The teardown
|
|
901
|
+
// has already cleaned up, and the failure belongs to a boot that no longer owns the
|
|
902
|
+
// element.
|
|
903
|
+
if (generation !== this._bootGeneration) {
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
// Return the element to its pre-boot state - no dead canvas, no loading bar stuck at
|
|
907
|
+
// zero - before announcing the failure. Readiness deliberately stays pending: nothing
|
|
908
|
+
// it would announce (the app, the entity hierarchy) exists, so a device-less element
|
|
909
|
+
// joins the documented never-ready cases and the failure surfaces through the error
|
|
910
|
+
// event instead.
|
|
911
|
+
if (this._canvas && this.contains(this._canvas)) {
|
|
912
|
+
this.removeChild(this._canvas);
|
|
913
|
+
}
|
|
914
|
+
this._canvas = null;
|
|
915
|
+
this._bar?.destroy();
|
|
916
|
+
this._bar = null;
|
|
917
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
918
|
+
const message = `pc-app failed to create a graphics device (${requested}) - ${reason}`;
|
|
919
|
+
console.error(message, error);
|
|
920
|
+
this.dispatchEvent(new ErrorEvent('error', { message, error }));
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
840
923
|
// The element may have been removed while the device was created. disconnectedCallback
|
|
841
924
|
// has already cleaned up the canvas; the device was created inside the await, so it is
|
|
842
925
|
// this boot's to release.
|
|
@@ -915,9 +998,19 @@ class AppElement extends AsyncElement {
|
|
|
915
998
|
const app = new AppBase(this._canvas);
|
|
916
999
|
this._app = app;
|
|
917
1000
|
app.init(createOptions);
|
|
918
|
-
|
|
1001
|
+
// FILLMODE_NONE leaves the canvas's CSS sizing alone (the engine's other fill modes
|
|
1002
|
+
// stamp window-derived pixel sizes onto it); RESOLUTION_AUTO sizes the drawing buffer
|
|
1003
|
+
// from the canvas's client size
|
|
1004
|
+
app.setCanvasFillMode(FILLMODE_NONE);
|
|
919
1005
|
app.setCanvasResolution(RESOLUTION_AUTO);
|
|
920
1006
|
this._pickerCreate();
|
|
1007
|
+
// Track the element's box rather than the window: containers resize without any window
|
|
1008
|
+
// event (splitter drags, flex reflow, animations). Guarded because jsdom has no
|
|
1009
|
+
// ResizeObserver - there, the resolution set above is the only sizing that happens.
|
|
1010
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
1011
|
+
this._resizeObserver = new ResizeObserver(() => this._syncCanvasSize());
|
|
1012
|
+
this._resizeObserver.observe(this);
|
|
1013
|
+
}
|
|
921
1014
|
// Get all pc-asset elements that are direct children of the pc-app element
|
|
922
1015
|
const assetElements = this.querySelectorAll(':scope > pc-asset');
|
|
923
1016
|
for (const assetElement of Array.from(assetElements)) {
|
|
@@ -993,8 +1086,6 @@ class AppElement extends AsyncElement {
|
|
|
993
1086
|
// Dismiss the bar only once a frame has actually rendered; ready fires before the
|
|
994
1087
|
// first rAF tick
|
|
995
1088
|
app.once('frameend', () => this._bar?.complete());
|
|
996
|
-
// Handle window resize to keep the canvas responsive
|
|
997
|
-
window.addEventListener('resize', this._onWindowResize);
|
|
998
1089
|
this._onReady();
|
|
999
1090
|
});
|
|
1000
1091
|
}
|
|
@@ -1019,18 +1110,27 @@ class AppElement extends AsyncElement {
|
|
|
1019
1110
|
// no longer holds.
|
|
1020
1111
|
this._hierarchyReady = false;
|
|
1021
1112
|
this._resetReady();
|
|
1022
|
-
//
|
|
1023
|
-
|
|
1113
|
+
// Stop tracking the element's size
|
|
1114
|
+
this._resizeObserver?.disconnect();
|
|
1115
|
+
this._resizeObserver = null;
|
|
1024
1116
|
// Remove the canvas
|
|
1025
1117
|
if (this._canvas && this.contains(this._canvas)) {
|
|
1026
1118
|
this.removeChild(this._canvas);
|
|
1027
1119
|
this._canvas = null;
|
|
1028
1120
|
}
|
|
1029
1121
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1122
|
+
/**
|
|
1123
|
+
* Syncs the drawing buffer and the picker to the canvas's current CSS size. The picker must
|
|
1124
|
+
* track the buffer, or picks would land at stale coordinates after a resize. Skipped while
|
|
1125
|
+
* an XR session presents - the session owns the buffer size.
|
|
1126
|
+
*/
|
|
1127
|
+
_syncCanvasSize() {
|
|
1128
|
+
if (!this.app || this.app.xr?.active) {
|
|
1129
|
+
return;
|
|
1033
1130
|
}
|
|
1131
|
+
this.app.updateCanvasSize();
|
|
1132
|
+
const { width, height } = this.app.graphicsDevice;
|
|
1133
|
+
this._picker?.resize(width, height);
|
|
1034
1134
|
}
|
|
1035
1135
|
_pickerCreate() {
|
|
1036
1136
|
const { width, height } = this.app.graphicsDevice;
|
|
@@ -1368,7 +1468,7 @@ class AppElement extends AsyncElement {
|
|
|
1368
1468
|
this._maxPixelRatio = value;
|
|
1369
1469
|
if (this.app) {
|
|
1370
1470
|
this.app.graphicsDevice.maxPixelRatio = value;
|
|
1371
|
-
this.
|
|
1471
|
+
this._syncCanvasSize();
|
|
1372
1472
|
}
|
|
1373
1473
|
}
|
|
1374
1474
|
/**
|