@eyejack/ejx-launcher-button v0.6.15
EJX Launcher Button
This package provides an all-in-one WebXR launcher button that supports all devices, including iOS support for WebXR by running the experience in the EyeJackX App Clip.
Demo: https://demos.eyejack.xyz/index-gallery
Examples
Three.js
import { showThreeLaunchButton } from "@eyejack/ejx-launcher-button";
showThreeLaunchButton({
// Required
renderer,
// (optional) configure and enable VR launcher
vrOptions: {
optionalFeatures: [
"local-floor",
"bounded-floor",
"plane-detection",
"anchors",
],
},
// (optional) configure and enable AR launcher
arOptions: {
optionalFeatures: [
"local-floor",
"bounded-floor",
"plane-detection",
"anchors",
"hit-test",
],
},
// (optional) Reference space for AR, defaults to local.
arReferenceSpace: "local-floor",
// (optional) Reference space for VR, defaults to undefined (does not effect renderer.xr)
vrReferenceSpace: undefined,
// Occurs after session start.
// sessionType: 'immersive-ar' | 'immersive-vr'
onStart: (sessionType) => {
console.log("Started ", sessionType);
},
// Occurs after session end
onEnd: (sessionType) => {
console.log("Ended", sessionType);
},
// (optional) Root element, for the dom overlay
container: document.getElementById("my-launcher-root"),
});
Other frameworks
The launcher button can be extended to use other frameworks by implementing the
XRSession builder functions. Here's the implementation of
showThreeLaunchButton
as an example.
:warning: App related side effects (such as showing / hiding elements in your scene) should not be added to
xrSessionBuilder
orxrSessionEnder
but ratheronStart
andonEnd
import { showLauncherButton } from "@eyejack/ejx-launcher-button";
export const showThreeLaunchButton = ({
renderer,
arReferenceSpace = "local",
vrReferenceSpace,
...opts
}: ShowThreeLaunchButtonOptions) => {
const destroy = showLaunchButton({
...opts,
// Returns a Promise<XRSession>
xrSessionBuilder: (sessionType) => {
// Get options for the session type
const xrOptions = (() => {
if (sessionType === "immersive-ar" && opts.arOptions) {
return opts.arOptions;
} else if (sessionType === "immersive-vr" && opts.vrOptions) {
return opts.vrOptions;
}
throw new Error(
`@eyejack/ejx-launcher-button: Trying to build xr session with session type ${sessionType}. This session type is not supported.`
);
})();
// Add dom overlay to close button
if (!xrOptions.optionalFeatures) {
xrOptions.optionalFeatures = [];
}
if (!xrOptions.optionalFeatures.includes("dom-overlay")) {
xrOptions.optionalFeatures.push("dom-overlay");
}
xrOptions.domOverlay = { root: opts.container ?? document.body };
// Build the XR Session
return new Promise((res) => {
navigator.xr
?.requestSession(sessionType, xrOptions)
.then(async (session) => {
if (sessionType === "immersive-ar" && arReferenceSpace) {
renderer.xr.setReferenceSpaceType(arReferenceSpace);
}
if (sessionType === "immersive-vr" && vrReferenceSpace) {
renderer.xr.setReferenceSpaceType(vrReferenceSpace);
}
await renderer.xr.setSession(session);
res(session);
});
});
},
// Receives the XRSession and ends it.
xrSessionEnder: (session) => {
return session.end();
},
});
return destroy;
};
API
The Launcher button will dispatch events to window object and also to the parent window if within an iframe.
:warning: The API has changed to use
postMessage
instead ofdispatchEvent
so that it can work with cross origin iframes. This has not been updated in the docs yet.Example:
window.addEventListener('message', event => { if (event.data.type === '@eyejack/ejx-launcher-button:ready') { window.postMessage({ type: '@eyejack/ejx-launcher-button:start', sessionType: 'immersive-ar', }, '*'); } });
Exposed functions
window.EJXStartXR
Exposes a global function to start a WebXR session. This is set after
@eyejack/ejx-launcher-button:ready
.
Returns a Promise<void>
window.addEventListener("@eyejack/ejx-launcher-button:ready", (event) => {
window.EJXStartXR("immersive-ar").then(() => {
console.log("Session started.");
});
});
window.EJXStopXR
Exposes a global function to stop a WebXR session. This is set after
@eyejack/ejx-launcher-button:ready
.
Returns a Promise<void>
let EJXStopXR;
// Attempts to stop the XR session after 10s
window.addEventListener("@eyejack/ejx-launcher-button:ready", (event) => {
setTimeout(() => {
if (window.EJXStopXR) {
window.EJXStopXR().then(() => {
console.log("Session started.");
});;
}
}, 10000);
});
Window Action Events
These are events that you can dispatch to interact with the launch button.
:warning: If the WebXR experience is within an iframe you'll need to dispatch These events on
document.getElementById('my-iframe').contentWindow
;Example, configuring the iframe to set the launch URL to the parent window url.
const iframe = document.getElementById("my-iframe"); const customEvent = new CustomEvent( "@eyejack/ejx-launcher-button:configure", { detail: { launchUrl: window.location.href, }, } ); iframe.contentWindow.dispatchEvent(customEvent);
@eyejack/ejx-launcher-button:configure
Configures the launcher button
const customEvent = new CustomEvent('@eyejack/ejx-launcher-button:configure', { detail: {
// Sets the url of the experience to launch
// @type {string}
launchUrl: window.location.href
// Shows or hides the launch button
showButton: true,
}})
window.dispatchEvent(customEvent)
@eyejack/ejx-launcher-button:start
Starts the WebXR session with a given sesionType
const customEvent = new CustomEvent("@eyejack/ejx-launcher-button:start", {
detail: {
// Type of XR Session to start
sessionType: "immersive-ar",
},
});
window.dispatchEvent(customEvent);
@eyejack/ejx-launcher-button:stop
Stops the WebXR Session
const customEvent = new CustomEvent("@eyejack/ejx-launcher-button:stop");
window.dispatchEvent(customEvent);
Window Events
These events are dispatched by the launcher button and can be handled to add interactive behaviour in your project.
:information_source: These events will be dispatch to both
window
andwindow.parent
(if it exists). This means that even if your launcher button is within an iframe, you can still handle these events from thewindow
object of the parent window.
@eyejack/ejx-launcher-button:ready
Triggers when the launcher button has loaded and is ready to start a WebXR session
window.addEventListener("@eyejack/ejx-launcher-button:ready", (event) => {
// Automatically start XR with a specific session
const customEvent = new CustomEvent("@eyejack/ejx-launcher-button:start", {
detail: {
sessionType: "immersive-ar",
},
});
window.dispatchEvent(customEvent);
});
@eyejack/ejx-launcher-button:started
Triggers after the session has started
window.addEventListener("@eyejack/ejx-launcher-button:started", (event) => {
console.log("Started ", event.detail.sessionType);
});
@eyejack/ejx-launcher-button:stopped
Triggers after the session has stopped.
window.addEventListener("@eyejack/ejx-launcher-button:stopped", (event) => {
console.log("Stopped ", event.detail.sessionType);
});
@eyejack/ejx-launcher-button:redirect
:warning: Required to handle redirects if the experience is viewed within an iframe. This is so the parent window can re-direct to https://play.eyejack.xyz/ and launch the experience in the EyeJackX AppClip.
window.addEventListener("@eyejack/ejx-launcher-button:redirect", (event) => {
window.location.href = event.detail.launchUrl;
});
10 months ago
10 months ago
10 months ago
10 months ago
12 months ago
12 months ago
12 months ago
12 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
12 months ago
12 months ago
1 year ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago