@needle-tools/engine 4.4.6 → 4.5.0-alpha.1
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/CHANGELOG.md +6 -0
- package/dist/{needle-engine.bundle-0359367a.js → needle-engine.bundle-3d05185b.js} +4960 -4918
- package/dist/{needle-engine.bundle-381aaeb9.light.min.js → needle-engine.bundle-b2e17f0e.light.min.js} +162 -162
- package/dist/{needle-engine.bundle-545dcd43.light.js → needle-engine.bundle-c44e02c7.light.js} +4959 -4917
- package/dist/{needle-engine.bundle-7919deac.light.umd.cjs → needle-engine.bundle-d7d53476.light.umd.cjs} +144 -144
- package/dist/{needle-engine.bundle-bd6721d2.min.js → needle-engine.bundle-e4ae93a2.min.js} +162 -162
- package/dist/{needle-engine.bundle-cb4d28f2.umd.cjs → needle-engine.bundle-f496c70e.umd.cjs} +143 -143
- package/dist/needle-engine.js +438 -438
- package/dist/needle-engine.light.js +438 -438
- package/dist/needle-engine.light.min.js +1 -1
- package/dist/needle-engine.light.umd.cjs +1 -1
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +4 -4
- package/lib/engine/api.js +4 -4
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_application.d.ts +5 -0
- package/lib/engine/engine_application.js +11 -11
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_context.js +14 -3
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_hot_reload.d.ts +1 -0
- package/lib/engine/engine_hot_reload.js +16 -3
- package/lib/engine/engine_hot_reload.js.map +1 -1
- package/lib/engine/engine_lifecycle_api.d.ts +2 -1
- package/lib/engine/engine_lifecycle_api.js +2 -1
- package/lib/engine/engine_lifecycle_api.js.map +1 -1
- package/lib/engine/webcomponents/buttons.d.ts +15 -3
- package/lib/engine/webcomponents/buttons.js +32 -6
- package/lib/engine/webcomponents/buttons.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.ar-overlay.d.ts +21 -0
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js +167 -0
- package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.attributes.d.ts +72 -0
- package/lib/engine/webcomponents/needle-engine.attributes.js +2 -0
- package/lib/engine/webcomponents/needle-engine.attributes.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.d.ts +113 -0
- package/lib/engine/webcomponents/needle-engine.extras.d.ts +6 -0
- package/lib/engine/webcomponents/needle-engine.extras.js +14 -0
- package/lib/engine/webcomponents/needle-engine.extras.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.js +832 -0
- package/lib/engine/webcomponents/needle-engine.js.map +1 -0
- package/lib/engine/webcomponents/needle-engine.loading.d.ts +44 -0
- package/lib/engine/webcomponents/needle-engine.loading.js +350 -0
- package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -0
- package/lib/engine/xr/NeedleXRSession.js +21 -0
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine-components/CameraUtils.js.map +1 -1
- package/lib/engine-components/Component.js +5 -0
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.js +1 -1
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/Skybox.js +1 -1
- package/lib/engine-components/Skybox.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.js +1 -0
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/needle-engine.d.ts +1 -1
- package/lib/needle-engine.js +1 -1
- package/lib/needle-engine.js.map +1 -1
- package/package.json +1 -1
- package/plugins/vite/reload.js +8 -20
- package/src/engine/api.ts +4 -4
- package/src/engine/engine_application.ts +11 -11
- package/src/engine/engine_context.ts +16 -3
- package/src/engine/engine_hot_reload.ts +16 -4
- package/src/engine/engine_lifecycle_api.ts +2 -1
- package/src/engine/webcomponents/buttons.ts +37 -8
- package/src/engine/{engine_element_overlay.ts → webcomponents/needle-engine.ar-overlay.ts} +2 -2
- package/src/engine/{engine_element_extras.ts → webcomponents/needle-engine.extras.ts} +1 -1
- package/src/engine/{engine_element_loading.ts → webcomponents/needle-engine.loading.ts} +6 -6
- package/src/engine/{engine_element.ts → webcomponents/needle-engine.ts} +15 -16
- package/src/engine/xr/NeedleXRSession.ts +26 -2
- package/src/engine-components/CameraUtils.ts +1 -1
- package/src/engine-components/Component.ts +51 -48
- package/src/engine-components/SceneSwitcher.ts +1 -1
- package/src/engine-components/Skybox.ts +1 -1
- package/src/engine-components/ui/EventSystem.ts +1 -0
- package/src/needle-engine.ts +1 -1
- /package/src/engine/{engine_element_attributes.ts → webcomponents/needle-engine.attributes.ts} +0 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { DeviceUtilities, getParam } from "../engine_utils.js";
|
|
2
|
+
const debug = getParam("debugoverlay");
|
|
3
|
+
export const arContainerClassName = "ar";
|
|
4
|
+
export const quitARClassName = "quit-ar";
|
|
5
|
+
// https://developers.google.com/web/fundamentals/web-components/customelements
|
|
6
|
+
/** @internal */
|
|
7
|
+
export class AROverlayHandler {
|
|
8
|
+
get ARContainer() { return this.arContainer; }
|
|
9
|
+
arContainer = null;
|
|
10
|
+
currentSession = null;
|
|
11
|
+
_createdAROnlyElements = [];
|
|
12
|
+
_reparentedObjects = [];
|
|
13
|
+
contentElement = null;
|
|
14
|
+
originalDomOverlayParent = null;
|
|
15
|
+
requestEndAR = () => {
|
|
16
|
+
this.onRequestedEndAR();
|
|
17
|
+
};
|
|
18
|
+
onBegin(context, overlayContainer, session) {
|
|
19
|
+
this.currentSession = session;
|
|
20
|
+
this.arContainer = overlayContainer;
|
|
21
|
+
if (DeviceUtilities.isMozillaXR()) {
|
|
22
|
+
const arElements = context.domElement.children;
|
|
23
|
+
for (let i = 0; i < arElements?.length; i++) {
|
|
24
|
+
const el = arElements[i];
|
|
25
|
+
if (!el)
|
|
26
|
+
return;
|
|
27
|
+
if (el === this.arContainer)
|
|
28
|
+
return;
|
|
29
|
+
this._reparentedObjects.push({ el: el, previousParent: el.parentElement });
|
|
30
|
+
this.arContainer?.appendChild(el);
|
|
31
|
+
}
|
|
32
|
+
if (overlayContainer) {
|
|
33
|
+
this.originalDomOverlayParent = overlayContainer.parentNode;
|
|
34
|
+
if (this.originalDomOverlayParent) {
|
|
35
|
+
console.log("Reparent DOM Overlay to body", overlayContainer, overlayContainer.style.display);
|
|
36
|
+
// mozilla webxr does hide elements on session start
|
|
37
|
+
// this is only necessary if we generated the overlay element
|
|
38
|
+
overlayContainer.style.display = "";
|
|
39
|
+
overlayContainer.style.visibility = "";
|
|
40
|
+
document.body.appendChild(overlayContainer);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.warn("WebXRViewer: No DOM Overlay found");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
this.ensureQuitARButton(this.arContainer);
|
|
48
|
+
}
|
|
49
|
+
onEnd(_context) {
|
|
50
|
+
// if (this.arContainer)
|
|
51
|
+
// this.arContainer.classList.remove("ar-session-active");
|
|
52
|
+
for (const created of this._createdAROnlyElements) {
|
|
53
|
+
if (created.remove) {
|
|
54
|
+
created.remove();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const prev of this._reparentedObjects) {
|
|
58
|
+
const el = prev.el;
|
|
59
|
+
prev.previousParent?.appendChild(el);
|
|
60
|
+
}
|
|
61
|
+
this._reparentedObjects.length = 0;
|
|
62
|
+
// mozilla XR exit AR fixes
|
|
63
|
+
if (DeviceUtilities.isMozillaXR()) {
|
|
64
|
+
// without the timeout we get errors in mozillas code and can not enter XR again
|
|
65
|
+
// not sure why we have to wait
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
// Canvas is not in DOM anymore after AR using Mozilla XR
|
|
68
|
+
const canvas = _context.renderer.domElement;
|
|
69
|
+
if (canvas) {
|
|
70
|
+
_context.domElement.shadowRoot?.prepend(canvas);
|
|
71
|
+
}
|
|
72
|
+
// Fix visibility
|
|
73
|
+
const elements = document.querySelectorAll("*");
|
|
74
|
+
for (var i = 0; i < elements.length; i++) {
|
|
75
|
+
const child = elements[i];
|
|
76
|
+
if (child && child._displayChanged !== undefined && child._displayWas !== undefined) {
|
|
77
|
+
child.style.display = child._displayWas;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}, 10);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
createOverlayContainer(needleEngineElement) {
|
|
84
|
+
if (this.contentElement)
|
|
85
|
+
return this.contentElement;
|
|
86
|
+
if (debug)
|
|
87
|
+
console.log("Setup overlay container");
|
|
88
|
+
const contentElement = needleEngineElement.shadowRoot.querySelector(".content");
|
|
89
|
+
this.contentElement = contentElement;
|
|
90
|
+
const overlaySlot = needleEngineElement.shadowRoot.querySelector(".overlay-content");
|
|
91
|
+
if (overlaySlot)
|
|
92
|
+
contentElement.appendChild(overlaySlot);
|
|
93
|
+
if (debug && !DeviceUtilities.isMobileDevice())
|
|
94
|
+
this.ensureQuitARButton(contentElement);
|
|
95
|
+
return contentElement;
|
|
96
|
+
}
|
|
97
|
+
onRequestedEndAR() {
|
|
98
|
+
if (!this.currentSession)
|
|
99
|
+
return;
|
|
100
|
+
this.currentSession.end();
|
|
101
|
+
this.currentSession = null;
|
|
102
|
+
}
|
|
103
|
+
ensureQuitARButton(element) {
|
|
104
|
+
const quitARSlot = document.createElement("slot");
|
|
105
|
+
quitARSlot.setAttribute("name", "quit-ar");
|
|
106
|
+
this.appendElement(quitARSlot, element);
|
|
107
|
+
this._createdAROnlyElements.push(quitARSlot);
|
|
108
|
+
// for mozilla XR reparenting we have to make sure the close button is clickable so we set it on the element directly
|
|
109
|
+
// it's in general perhaps more safe to set it on the element to ensure it's clickable
|
|
110
|
+
quitARSlot.style.pointerEvents = "auto";
|
|
111
|
+
// We want to search the document if there's a quit-ar button
|
|
112
|
+
// In which case we don't want to populate the default button (slot) with any content
|
|
113
|
+
const quitARElement = document.querySelector(`.${quitARClassName}`);
|
|
114
|
+
if (quitARElement) {
|
|
115
|
+
quitARElement.addEventListener('click', this.requestEndAR);
|
|
116
|
+
if (debug)
|
|
117
|
+
quitARElement.addEventListener('click', () => console.log("Clicked quit-ar button"));
|
|
118
|
+
// We found a explicit quit-ar element
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
quitARSlot.addEventListener('click', this.requestEndAR);
|
|
122
|
+
if (debug)
|
|
123
|
+
quitARSlot.addEventListener('click', () => console.log("Clicked fallback close button"));
|
|
124
|
+
// we need another container to make sure the button is always on top
|
|
125
|
+
const fixedButtonContainer = document.createElement("div");
|
|
126
|
+
fixedButtonContainer.style.cssText = `
|
|
127
|
+
position: fixed;
|
|
128
|
+
top: 0;
|
|
129
|
+
right: 0;
|
|
130
|
+
z-index: 600;
|
|
131
|
+
pointer-events: all;
|
|
132
|
+
`;
|
|
133
|
+
this.appendElement(fixedButtonContainer, quitARSlot);
|
|
134
|
+
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
135
|
+
svg.classList.add("quit-ar-button");
|
|
136
|
+
svg.setAttribute('width', "40px");
|
|
137
|
+
svg.setAttribute('height', "40px");
|
|
138
|
+
svg.style.cssText = `
|
|
139
|
+
background: rgba(255, 255, 255, .4);
|
|
140
|
+
-webkit-backdrop-filter: blur(8px);
|
|
141
|
+
backdrop-filter: blur(8px);
|
|
142
|
+
border-radius: 50%;
|
|
143
|
+
box-shadow: 0 0 5px rgba(0,0,0,.3);
|
|
144
|
+
outline: 1px solid rgba(255, 255, 255, .6);
|
|
145
|
+
display: flex;
|
|
146
|
+
justify-content: center;
|
|
147
|
+
align-items: center;
|
|
148
|
+
`;
|
|
149
|
+
fixedButtonContainer.appendChild(svg);
|
|
150
|
+
var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
151
|
+
path.setAttribute('d', 'M 12,12 L 28,28 M 28,12 12,28');
|
|
152
|
+
path.setAttribute('stroke', '#000000');
|
|
153
|
+
path.setAttribute('stroke-width', "2px");
|
|
154
|
+
path.style.cssText = `
|
|
155
|
+
/**filter: drop-shadow(0 0px 1.2px rgba(0,0,0,.7));**/
|
|
156
|
+
`;
|
|
157
|
+
svg.appendChild(path);
|
|
158
|
+
if (debug)
|
|
159
|
+
console.log("Created fallback close button", svg, element);
|
|
160
|
+
}
|
|
161
|
+
appendElement(element, parent) {
|
|
162
|
+
if (parent.shadowRoot)
|
|
163
|
+
return parent.shadowRoot.appendChild(element);
|
|
164
|
+
return parent.appendChild(element);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=needle-engine.ar-overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"needle-engine.ar-overlay.js","sourceRoot":"","sources":["../../../src/engine/webcomponents/needle-engine.ar-overlay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
type MainAttributes = {
|
|
2
|
+
children?: HTMLElement[];
|
|
3
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
4
|
+
/** src to one or multiple glb files to be loaded initially. Can be either "path/to/scene.glb" or "[./path/scene1.glb, myOtherScene.gltf]" */
|
|
5
|
+
src?: string | string[];
|
|
6
|
+
/** optional */
|
|
7
|
+
hash?: string;
|
|
8
|
+
/** set to automatically add OrbitControls to the loaded scene */
|
|
9
|
+
"camera-controls"?: boolean | "none";
|
|
10
|
+
/** event function name called when loading starts, use preventDefault to prevent the default loading overlay to show */
|
|
11
|
+
"loadstart"?: string;
|
|
12
|
+
/** event function name called when loading updates */
|
|
13
|
+
"progress"?: string;
|
|
14
|
+
/** event function name called when loading has finished */
|
|
15
|
+
"loadfinished"?: string;
|
|
16
|
+
/** override the default draco decoder path location */
|
|
17
|
+
"dracoDecoderPath"?: string;
|
|
18
|
+
/** override the default draco type */
|
|
19
|
+
"dracoDecoderType"?: string;
|
|
20
|
+
/** override the default ktx2 decoder path */
|
|
21
|
+
"ktx2DecoderPath"?: string;
|
|
22
|
+
/** Add to prevent Needle Engine context from being disposed when the element is removed from the DOM */
|
|
23
|
+
"keep-alive"?: boolean;
|
|
24
|
+
addEventListener?(event: "ready", callback: (event: CustomEvent) => void): void;
|
|
25
|
+
addEventListener?(event: "error", callback: (event: CustomEvent) => void): void;
|
|
26
|
+
};
|
|
27
|
+
type LoadingAttributes = {
|
|
28
|
+
"loading-style"?: "light" | "dark";
|
|
29
|
+
/** Pro feature */
|
|
30
|
+
"hide-loading-overlay"?: boolean;
|
|
31
|
+
/** Pro feature */
|
|
32
|
+
"loading-background-color"?: string;
|
|
33
|
+
/** Pro feature */
|
|
34
|
+
"loading-logo-src"?: string;
|
|
35
|
+
/** Pro feature */
|
|
36
|
+
"primary-color"?: string;
|
|
37
|
+
/** Pro feature */
|
|
38
|
+
"secondary-color"?: string;
|
|
39
|
+
/** Pro feature */
|
|
40
|
+
"loading-text-color"?: string;
|
|
41
|
+
};
|
|
42
|
+
type SkyboxAttributes = {
|
|
43
|
+
/** use background-image instead - URL to .exr, .hdr, .png, .jpg to be used as skybox */
|
|
44
|
+
"skybox-image"?: string;
|
|
45
|
+
/** URL to .exr, .hdr, .png, .jpg to be used as skybox */
|
|
46
|
+
"background-image"?: string;
|
|
47
|
+
/** Blurs the background image (if any) - value between 0 and 1
|
|
48
|
+
* 0: no blur
|
|
49
|
+
* 1: full blur
|
|
50
|
+
*/
|
|
51
|
+
"background-blurriness"?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Background color to be used if no skybox or background image is provided.
|
|
54
|
+
* For example: "skybox-color='#ff0000'" will set the background color to red.
|
|
55
|
+
*/
|
|
56
|
+
"background-color"?: string;
|
|
57
|
+
/** URL to .exr, .hdr, .png, .jpg to be used for lighting */
|
|
58
|
+
"environment-image"?: string;
|
|
59
|
+
};
|
|
60
|
+
export type TonemappingAttributeOptions = "none" | "linear" | "neutral" | "agx";
|
|
61
|
+
type RenderingAttributes = {
|
|
62
|
+
"transparent"?: boolean;
|
|
63
|
+
"contactshadows"?: boolean;
|
|
64
|
+
"tone-mapping"?: TonemappingAttributeOptions;
|
|
65
|
+
"tone-mapping-exposure"?: number;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Available attributes for the `<needle-engine>` web component
|
|
69
|
+
* @inheritdoc
|
|
70
|
+
*/
|
|
71
|
+
export type NeedleEngineAttributes = MainAttributes & Partial<Omit<HTMLElement, "style">> & LoadingAttributes & SkyboxAttributes & RenderingAttributes;
|
|
72
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"needle-engine.attributes.js","sourceRoot":"","sources":["../../../src/engine/webcomponents/needle-engine.attributes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/// <reference types="webxr" />
|
|
2
|
+
import { Context } from "../engine_setup.js";
|
|
3
|
+
import { type INeedleEngineComponent } from "../engine_types.js";
|
|
4
|
+
/**
|
|
5
|
+
* <needle-engine> web component. See {@link NeedleEngineAttributes} attributes for supported attributes
|
|
6
|
+
* The needle engine web component creates and manages a needle engine context which is responsible for rendering a 3D scene using threejs.
|
|
7
|
+
* The needle engine context is created when the src attribute is set and disposed when the needle engine is removed from the document (you can prevent this by setting the keep-alive attribute to true).
|
|
8
|
+
* The needle engine context is accessible via the context property on the needle engine element (e.g. document.querySelector("needle-engine").context).
|
|
9
|
+
* @link https://engine.needle.tools/docs/reference/needle-engine-attributes
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <needle-engine src="https://example.com/scene.glb"></needle-engine>
|
|
13
|
+
* @example
|
|
14
|
+
* <needle-engine src="https://example.com/scene.glb" camera-controls="false"></needle-engine>
|
|
15
|
+
*/
|
|
16
|
+
export declare class NeedleEngineHTMLElement extends HTMLElement implements INeedleEngineComponent {
|
|
17
|
+
static get observedAttributes(): string[];
|
|
18
|
+
get loadingProgress01(): number;
|
|
19
|
+
get loadingFinished(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* If set to false the camera controls are disabled. Default is true.
|
|
22
|
+
* @type {boolean | null}
|
|
23
|
+
* @memberof NeedleEngineAttributes
|
|
24
|
+
* @example
|
|
25
|
+
* <needle-engine camera-controls="false"></needle-engine>
|
|
26
|
+
* @example
|
|
27
|
+
* <needle-engine camera-controls="true"></needle-engine>
|
|
28
|
+
* @example
|
|
29
|
+
* <needle-engine camera-controls></needle-engine>
|
|
30
|
+
* @example
|
|
31
|
+
* <needle-engine></needle-engine>
|
|
32
|
+
* @returns {boolean | null} if the attribute is not set it returns null
|
|
33
|
+
*/
|
|
34
|
+
get cameraControls(): boolean | null;
|
|
35
|
+
/**
|
|
36
|
+
* Get the current context for this web component instance. The context is created when the src attribute is set and the loading has finished.
|
|
37
|
+
* The context is disposed when the needle engine is removed from the document (you can prevent this by setting the keep-alive attribute to true).
|
|
38
|
+
* @returns {Promise<Context>} a promise that resolves to the context when the loading has finished
|
|
39
|
+
*/
|
|
40
|
+
getContext(): Promise<Context>;
|
|
41
|
+
/**
|
|
42
|
+
* Get the context that is created when the src attribute is set and the loading has finished.
|
|
43
|
+
*/
|
|
44
|
+
get context(): Context;
|
|
45
|
+
private _context;
|
|
46
|
+
private _overlay_ar;
|
|
47
|
+
private _loadingProgress01;
|
|
48
|
+
private _loadingView?;
|
|
49
|
+
private _previousSrc;
|
|
50
|
+
/** set to true after <needle-engine> did load completely at least once. Set to false when <needle-engine> is removed from the document */
|
|
51
|
+
private _didFullyLoad;
|
|
52
|
+
constructor();
|
|
53
|
+
/**
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
connectedCallback(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
disconnectedCallback(): void;
|
|
61
|
+
/**
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
65
|
+
private _loadId;
|
|
66
|
+
private _abortController;
|
|
67
|
+
private _lastSourceFiles;
|
|
68
|
+
private _createContextPromise;
|
|
69
|
+
private onLoad;
|
|
70
|
+
private applyAttributes;
|
|
71
|
+
private onXRSessionStarted;
|
|
72
|
+
/** called by the context when the first frame has been rendered */
|
|
73
|
+
private onReady;
|
|
74
|
+
private onError;
|
|
75
|
+
private internalSetLoadingMessage;
|
|
76
|
+
private getSourceFiles;
|
|
77
|
+
private checkIfSourceHasChanged;
|
|
78
|
+
private _previouslyRegisteredMap;
|
|
79
|
+
private ensureLoadStartIsRegistered;
|
|
80
|
+
private registerEventFromAttribute;
|
|
81
|
+
private setPublicKey;
|
|
82
|
+
private setVersion;
|
|
83
|
+
/**
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
getAROverlayContainer(): HTMLElement;
|
|
87
|
+
/**
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
getVROverlayContainer(): HTMLElement | null;
|
|
91
|
+
/**
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
onEnterAR(session: XRSession): void;
|
|
95
|
+
/**
|
|
96
|
+
* @internal
|
|
97
|
+
*/
|
|
98
|
+
onExitAR(session: XRSession): void;
|
|
99
|
+
/**
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
onEnterVR(session: XRSession): void;
|
|
103
|
+
/**
|
|
104
|
+
* @internal
|
|
105
|
+
*/
|
|
106
|
+
onExitVR(session: XRSession): void;
|
|
107
|
+
private onSetupAR;
|
|
108
|
+
private onSetupVR;
|
|
109
|
+
private onSetupDesktop;
|
|
110
|
+
private setupElementsForMode;
|
|
111
|
+
private foreachHtmlElement;
|
|
112
|
+
private onBeforeBeginLoading;
|
|
113
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call with the name of an attribute that you want to receive change events for
|
|
3
|
+
* This is useful for example if you want to add custom attributes to <needle-engine>
|
|
4
|
+
* Use the addAttributeChangeCallback utility methods to register callback events
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerObservableAttribute(name: string): Promise<void>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
DO NOT IMPORT ENGINE_ELEMENT FROM HERE
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Call with the name of an attribute that you want to receive change events for
|
|
6
|
+
* This is useful for example if you want to add custom attributes to <needle-engine>
|
|
7
|
+
* Use the addAttributeChangeCallback utility methods to register callback events
|
|
8
|
+
*/
|
|
9
|
+
export async function registerObservableAttribute(name) {
|
|
10
|
+
const { NeedleEngineHTMLElement } = await import("./needle-engine.js");
|
|
11
|
+
if (!NeedleEngineHTMLElement.observedAttributes.includes(name))
|
|
12
|
+
NeedleEngineHTMLElement.observedAttributes.push(name);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=needle-engine.extras.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"needle-engine.extras.js","sourceRoot":"","sources":["../../../src/engine/webcomponents/needle-engine.extras.ts"],"names":[],"mappings":"AAEA;;EAEE;AAEF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,IAAY;IAC1D,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACvE,IAAI,CAAC,uBAAuB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC1D,uBAAuB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC"}
|