diff --git a/package.json b/package.json index 2db5ee36aa8..cae1dac474f 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "TWEEN": "readonly", "twgsl": "readonly", "webkitAudioContext": "readonly", + "WorkerGlobalScope": "readonly", "XRRay": "readonly", "XRRigidTransform": "readonly", "XRWebGLLayer": "readonly" diff --git a/src/core/platform.js b/src/core/platform.js index 9e7d816ee30..20a9beb4dfb 100644 --- a/src/core/platform.js +++ b/src/core/platform.js @@ -17,8 +17,10 @@ const detectPassiveEvents = () => { }; const ua = (typeof navigator !== 'undefined') ? navigator.userAgent : ''; -const environment = typeof window !== 'undefined' ? 'browser' : - typeof global !== 'undefined' ? 'node' : 'worker'; +const environment = + typeof window !== 'undefined' ? 'browser' : + typeof WorkerGlobalScope !== 'undefined' ? 'webworker' : + typeof global !== 'undefined' ? 'node' : 'worker'; // detect platform const platformName = @@ -78,7 +80,8 @@ const platform = { global: (typeof globalThis !== 'undefined' && globalThis) ?? (environment === 'browser' && window) ?? (environment === 'node' && global) ?? - (environment === 'worker' && self), + (environment === 'worker' && self) ?? + (environment === 'webworker' && WorkerGlobalScope), /** * Convenience boolean indicating whether we're running in the browser. @@ -87,6 +90,13 @@ const platform = { */ browser: environment === 'browser', + /** + * True if running in a Web Worker. + * + * @type {boolean} + */ + webworker: environment === 'webworker', + /** * True if running on a desktop or laptop device. * diff --git a/src/framework/app-base.js b/src/framework/app-base.js index 2b6e71817b6..d6d2292d4c5 100644 --- a/src/framework/app-base.js +++ b/src/framework/app-base.js @@ -2023,7 +2023,7 @@ const makeTick = function (_app) { if (application.xr?.session) { application.frameRequestId = application.xr.session.requestAnimationFrame(application.tick); } else { - application.frameRequestId = platform.browser ? window.requestAnimationFrame(application.tick) : null; + application.frameRequestId = platform.browser || platform.webworker ? requestAnimationFrame(application.tick) : null; } if (application.graphicsDevice.contextLost) diff --git a/src/framework/application.js b/src/framework/application.js index 7f9e1201314..66684f86ecd 100644 --- a/src/framework/application.js +++ b/src/framework/application.js @@ -115,7 +115,7 @@ class Application extends AppBase { * - sound ({@link SoundComponentSystem}) * - sprite ({@link SpriteComponentSystem}) * - * @param {HTMLCanvasElement} canvas - The canvas element. + * @param {HTMLCanvasElement | OffscreenCanvas} canvas - The canvas element. * @param {object} [options] - The options object to configure the Application. * @param {ElementInput} [options.elementInput] - Input handler for {@link ElementComponent}s. * @param {Keyboard} [options.keyboard] - Keyboard handler for input. diff --git a/src/platform/graphics/graphics-device.js b/src/platform/graphics/graphics-device.js index b5104a5d61b..b17dfb8b34e 100644 --- a/src/platform/graphics/graphics-device.js +++ b/src/platform/graphics/graphics-device.js @@ -356,6 +356,16 @@ class GraphicsDevice extends EventHandler { flags: CLEARFLAG_COLOR | CLEARFLAG_DEPTH }; + /** + * The current client rect. + * + * @type {{ width: number, height: number }} + */ + clientRect = { + width: 0, + height: 0 + }; + static EVENT_RESIZE = 'resizecanvas'; constructor(canvas, options) { @@ -752,7 +762,16 @@ class GraphicsDevice extends EventHandler { } updateClientRect() { - this.clientRect = this.canvas.getBoundingClientRect(); + if (platform.browser) { + const rect = this.canvas.getBoundingClientRect(); + this.clientRect.width = rect.width; + this.clientRect.height = rect.height; + + } else if (platform.webworker) { + // Web Workers don't do page layout, so getBoundingClientRect is not available + this.clientRect.width = this.canvas.width; + this.clientRect.height = this.canvas.height; + } } /**