@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
105 lines • 4.2 kB
JavaScript
import { isDevEnvironment } from "./debug/index.js";
export var ApplicationEvents;
(function (ApplicationEvents) {
ApplicationEvents["Visible"] = "application-visible";
ApplicationEvents["Hidden"] = "application-hidden";
ApplicationEvents["MuteChanged"] = "application-mutechanged";
})(ApplicationEvents || (ApplicationEvents = {}));
let userInteractionRegistered = false;
const userInteractionCallbacks = [];
/**
* Invoked when the user interacts with the page (click, touch, keypress, etc) allowing to play media / audio / start XR
* @internal
*/
export function internalOnUserInputRegistered() {
if (userInteractionRegistered)
return;
if (isDevEnvironment())
console.debug("User interaction registered: audio can now be played");
userInteractionRegistered = true;
const copy = [...userInteractionCallbacks];
userInteractionCallbacks.length = 0;
copy.forEach(cb => cb());
}
document.addEventListener('mousedown', internalOnUserInputRegistered);
document.addEventListener('pointerup', internalOnUserInputRegistered);
document.addEventListener('click', internalOnUserInputRegistered);
document.addEventListener('dragstart', internalOnUserInputRegistered);
document.addEventListener('touchend', internalOnUserInputRegistered);
document.addEventListener('keydown', internalOnUserInputRegistered);
/**
* The Application class can be used to mute audio globally, and to check if the application (canvas) is currently visible (it's tab is active and not minimized).
*/
export class Application extends EventTarget {
static get userInteractionRegistered() {
return userInteractionRegistered;
}
/** @deprecated use Application.registerWaitForInteraction instead */
static registerWaitForAllowAudio = Application.registerWaitForInteraction;
/**
* Register a callback that will be called when the user interacts with the page (click, touch, keypress, etc).
* If the user has already interacted with the page, the callback will be called immediately.
* This can be used to wait for user interaction before playing audio, for example.
*/
static registerWaitForInteraction(cb) {
if (cb !== null) {
if (userInteractionRegistered) {
cb();
return;
}
if (userInteractionCallbacks.indexOf(cb) === -1)
userInteractionCallbacks.push(cb);
}
}
/**
* Unregister a callback that was previously registered with registerWaitForInteraction.
*/
static unregisterWaitForInteraction(cb) {
const index = userInteractionCallbacks.indexOf(cb);
if (index !== -1) {
userInteractionCallbacks.splice(index, 1);
}
}
_mute = false;
/** audio muted? */
get muted() { return this._mute; }
/** set global audio mute */
set muted(value) {
if (value === this._mute)
return;
this._mute = value;
this.dispatchEvent(new Event(ApplicationEvents.MuteChanged));
}
context;
/** @returns true if the document is focused */
get hasFocus() {
return document.hasFocus();
}
/**
* @returns true if the application is currently visible (it's tab is active and not minimized)
*/
get isVisible() {
return this._isVisible;
}
_isVisible = true;
/** @internal */
constructor(context) {
super();
this.context = context;
window.addEventListener("visibilitychange", this.onVisiblityChanged.bind(this), false);
}
onVisiblityChanged(evt) {
// console.log(evt.target.visibilityState)
switch (evt.target.visibilityState) {
case "hidden":
this._isVisible = false;
this.dispatchEvent(new Event(ApplicationEvents.Hidden));
break;
case "visible":
this._isVisible = true;
this.dispatchEvent(new Event(ApplicationEvents.Visible));
break;
}
}
}
//# sourceMappingURL=engine_application.js.map