@threlte/xr 0.0.2

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.
Files changed (57) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +13 -0
  3. package/dist/components/ARButton.svelte +25 -0
  4. package/dist/components/ARButton.svelte.d.ts +250 -0
  5. package/dist/components/Controller.svelte +124 -0
  6. package/dist/components/Controller.svelte.d.ts +30 -0
  7. package/dist/components/Hand.svelte +119 -0
  8. package/dist/components/Hand.svelte.d.ts +24 -0
  9. package/dist/components/Hands.svelte +35 -0
  10. package/dist/components/Hands.svelte.d.ts +24 -0
  11. package/dist/components/Ray.svelte +23 -0
  12. package/dist/components/Ray.svelte.d.ts +18 -0
  13. package/dist/components/ShortRay.svelte +28 -0
  14. package/dist/components/ShortRay.svelte.d.ts +16 -0
  15. package/dist/components/TeleportControls.svelte +136 -0
  16. package/dist/components/TeleportControls.svelte.d.ts +54 -0
  17. package/dist/components/VRButton.svelte +24 -0
  18. package/dist/components/VRButton.svelte.d.ts +250 -0
  19. package/dist/components/XR.svelte +114 -0
  20. package/dist/components/XR.svelte.d.ts +59 -0
  21. package/dist/components/XRButton.svelte +79 -0
  22. package/dist/components/XRButton.svelte.d.ts +265 -0
  23. package/dist/hooks/index.d.ts +7 -0
  24. package/dist/hooks/index.js +7 -0
  25. package/dist/hooks/useController.d.ts +14 -0
  26. package/dist/hooks/useController.js +32 -0
  27. package/dist/hooks/useEvent.d.ts +14 -0
  28. package/dist/hooks/useEvent.js +34 -0
  29. package/dist/hooks/useHand.d.ts +8 -0
  30. package/dist/hooks/useHand.js +14 -0
  31. package/dist/hooks/useHandJoint.d.ts +6 -0
  32. package/dist/hooks/useHandJoint.js +19 -0
  33. package/dist/hooks/useHitTest.d.ts +5 -0
  34. package/dist/hooks/useHitTest.js +44 -0
  35. package/dist/hooks/useTeleport.d.ts +13 -0
  36. package/dist/hooks/useTeleport.js +54 -0
  37. package/dist/hooks/useXR.d.ts +14 -0
  38. package/dist/hooks/useXR.js +15 -0
  39. package/dist/index.d.ts +12 -0
  40. package/dist/index.js +11 -0
  41. package/dist/internal/events.d.ts +5 -0
  42. package/dist/internal/events.js +26 -0
  43. package/dist/internal/stores.d.ts +10 -0
  44. package/dist/internal/stores.js +10 -0
  45. package/dist/lib/getXRSessionOptions.d.ts +2 -0
  46. package/dist/lib/getXRSessionOptions.js +15 -0
  47. package/dist/lib/getXRSupportState.d.ts +7 -0
  48. package/dist/lib/getXRSupportState.js +20 -0
  49. package/dist/lib/handJoints.d.ts +2 -0
  50. package/dist/lib/handJoints.js +27 -0
  51. package/dist/lib/toggleXRSession.d.ts +14 -0
  52. package/dist/lib/toggleXRSession.js +33 -0
  53. package/dist/plugins/teleportPlugin.d.ts +1 -0
  54. package/dist/plugins/teleportPlugin.js +41 -0
  55. package/dist/types.d.ts +31 -0
  56. package/dist/types.js +1 -0
  57. package/package.json +50 -0
@@ -0,0 +1,114 @@
1
+ <!--
2
+
3
+ @component
4
+ `<XR />` is a WebXR manager that configures your scene for XR rendering and interaction.
5
+
6
+ This should be placed within a Threlte `<Canvas />`.
7
+
8
+ ```svelte
9
+ <XR
10
+ foveation={1}
11
+ frameRate={90}
12
+ referenceSpace='local-floor'
13
+ on:sessionstart={(event: XREvent<XRManagerEvent>) => {}}
14
+ on:sessionend={(event: XREvent<XRManagerEvent>) => {}}
15
+ on:visibilitychange={(event: XREvent<XRSessionEvent>) => {}}
16
+ on:inputsourceschange={(event: XREvent<XRSessionEvent>) => {}}
17
+ />
18
+ ```
19
+
20
+ -->
21
+
22
+ <script>import { onDestroy } from "svelte";
23
+ import { useThrelte, createRawEventDispatcher } from "@threlte/core";
24
+ import { session, referenceSpaceType, isPresenting, isHandTracking, initialized, xr as xrStore } from "../internal/stores";
25
+ export let foveation = 1;
26
+ export let frameRate = void 0;
27
+ export let referenceSpace = "local-floor";
28
+ const dispatch = createRawEventDispatcher();
29
+ const { renderer, frameloop } = useThrelte();
30
+ const { xr } = renderer;
31
+ const handleSessionStart = (event) => {
32
+ $isPresenting = true;
33
+ dispatch("sessionstart", { ...event, target: $session });
34
+ };
35
+ const handleSessionEnd = (event) => {
36
+ dispatch("sessionend", { ...event, target: $session });
37
+ $isPresenting = false;
38
+ $session = void 0;
39
+ };
40
+ const handleVisibilityChange = (event) => {
41
+ dispatch("visibilitychange", { ...event, target: $session });
42
+ };
43
+ const handleInputSourcesChange = (event) => {
44
+ $isHandTracking = Object.values($session.inputSources).some((source) => source.hand);
45
+ dispatch("inputsourceschange", { ...event, target: $session });
46
+ };
47
+ const handleFramerateChange = (event) => {
48
+ dispatch("visibilitychange", { ...event, target: $session });
49
+ };
50
+ const updateTargetFrameRate = (frameRate2) => {
51
+ if (frameRate2 === void 0)
52
+ return;
53
+ try {
54
+ $session?.updateTargetFrameRate(frameRate2);
55
+ } catch {
56
+ }
57
+ };
58
+ const cleanupSession = (currentSession) => {
59
+ if (currentSession === void 0)
60
+ return;
61
+ currentSession.removeEventListener("visibilitychange", handleVisibilityChange);
62
+ currentSession.removeEventListener("inputsourceschange", handleInputSourcesChange);
63
+ currentSession.removeEventListener("frameratechange", handleFramerateChange);
64
+ };
65
+ const updateSession = async (currentSession) => {
66
+ if (currentSession === void 0)
67
+ return;
68
+ currentSession.addEventListener("visibilitychange", handleVisibilityChange);
69
+ currentSession.addEventListener("inputsourceschange", handleInputSourcesChange);
70
+ currentSession.addEventListener("frameratechange", handleFramerateChange);
71
+ xr.setFoveation(foveation);
72
+ updateTargetFrameRate(frameRate);
73
+ };
74
+ let lastSession;
75
+ $initialized = true;
76
+ $xrStore = xr;
77
+ xr.enabled = true;
78
+ xr.addEventListener("sessionstart", handleSessionStart);
79
+ xr.addEventListener("sessionend", handleSessionEnd);
80
+ onDestroy(() => {
81
+ $initialized = false;
82
+ $xrStore = void 0;
83
+ xr.enabled = false;
84
+ xr.removeEventListener("sessionstart", handleSessionStart);
85
+ xr.removeEventListener("sessionend", handleSessionEnd);
86
+ });
87
+ $: {
88
+ xr.setReferenceSpaceType(referenceSpace);
89
+ $referenceSpaceType = referenceSpace;
90
+ }
91
+ $:
92
+ if (lastSession !== $session) {
93
+ cleanupSession(lastSession);
94
+ updateSession($session);
95
+ lastSession = $session;
96
+ }
97
+ let originalFrameloop = $frameloop;
98
+ $frameloop = "always";
99
+ $:
100
+ if ($isPresenting) {
101
+ originalFrameloop = $frameloop;
102
+ $frameloop = "always";
103
+ } else {
104
+ $frameloop = originalFrameloop;
105
+ }
106
+ $:
107
+ updateTargetFrameRate(frameRate);
108
+ $:
109
+ xr.setFoveation(foveation);
110
+ </script>
111
+
112
+ {#if $isPresenting}
113
+ <slot />
114
+ {/if}
@@ -0,0 +1,59 @@
1
+ /// <reference types="webxr" />
2
+ import { SvelteComponent } from "svelte";
3
+ import type { XRSessionEvent } from '../types';
4
+ declare const __propDef: {
5
+ props: {
6
+ /**
7
+ * Enables foveated rendering. Default is `1`, the three.js default.
8
+ *
9
+ * 0 = no foveation, full resolution
10
+ *
11
+ * 1 = maximum foveation, the edges render at lower resolution
12
+ */ foveation?: number;
13
+ /**
14
+ * The target framerate for the XRSystem. Smaller rates give more CPU headroom at the cost of responsiveness.
15
+ * Recommended range is `72`-`120`. Default is unset and left to the device.
16
+ * @note If your experience cannot effectively reach the target framerate, it will be subject to frame reprojection
17
+ * which will halve the effective framerate. Choose a conservative estimate that balances responsiveness and
18
+ * headroom based on your experience.
19
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API/Rendering#refresh_rate_and_frame_rate
20
+ */ frameRate?: number | undefined;
21
+ /** Type of WebXR reference space to use. Default is `local-floor` */ referenceSpace?: XRReferenceSpaceType;
22
+ };
23
+ slots: {
24
+ default: {};
25
+ };
26
+ events: {
27
+ /** Called as an XRSession is requested */
28
+ sessionstart: XRSessionEvent<'sessionstart'>;
29
+ /** Called after an XRSession is terminated */
30
+ sessionend: XRSessionEvent<'sessionend'>;
31
+ /** Called when an XRSession is hidden or unfocused. */
32
+ visibilitychange: globalThis.XRSessionEvent;
33
+ /** Called when available inputsources change */
34
+ inputsourceschange: globalThis.XRSessionEvent;
35
+ };
36
+ };
37
+ export type XrProps = typeof __propDef.props;
38
+ export type XrEvents = typeof __propDef.events;
39
+ export type XrSlots = typeof __propDef.slots;
40
+ /**
41
+ * `<XR />` is a WebXR manager that configures your scene for XR rendering and interaction.
42
+ *
43
+ * This should be placed within a Threlte `<Canvas />`.
44
+ *
45
+ * ```svelte
46
+ * <XR
47
+ * foveation={1}
48
+ * frameRate={90}
49
+ * referenceSpace='local-floor'
50
+ * on:sessionstart={(event: XREvent<XRManagerEvent>) => {}}
51
+ * on:sessionend={(event: XREvent<XRManagerEvent>) => {}}
52
+ * on:visibilitychange={(event: XREvent<XRSessionEvent>) => {}}
53
+ * on:inputsourceschange={(event: XREvent<XRSessionEvent>) => {}}
54
+ * />
55
+ * ```
56
+ */
57
+ export default class Xr extends SvelteComponent<XrProps, XrEvents, XrSlots> {
58
+ }
59
+ export {};
@@ -0,0 +1,79 @@
1
+ <!--
2
+ @component
3
+ `<XRButton />` is an HTML `<button />` that can be used to init and
4
+ display info about your WebXR session. This is aliased by `ARButton` and
5
+ `VRButton` with sensible session defaults.
6
+
7
+ ```svelte
8
+ <XRButton
9
+ mode={'immersive-ar' | 'immersive-vr' | 'inline'}
10
+ sessionInit={{
11
+ optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers']
12
+ }}
13
+ force={'enter' | 'exit' | undefined}
14
+ styled={'true' | 'false'}
15
+ on:error={(event) => {}}
16
+ on:click={(event) => {}}
17
+ />
18
+ ```
19
+ -->
20
+
21
+ <script>import { createEventDispatcher } from "svelte";
22
+ import { getXRSupportState } from "../lib/getXRSupportState";
23
+ import { toggleXRSession } from "../lib/toggleXRSession";
24
+ import { session, initialized } from "../internal/stores";
25
+ export let mode;
26
+ export let sessionInit = void 0;
27
+ export let force = void 0;
28
+ export let styled = true;
29
+ const dispatch = createEventDispatcher();
30
+ const handleButtonClick = async (state) => {
31
+ if (!$initialized) {
32
+ throw new Error("The <XR> component was not created. This is required to start an XR session.");
33
+ }
34
+ dispatch("click", { state });
35
+ if (state !== "supported")
36
+ return;
37
+ try {
38
+ await toggleXRSession(mode, sessionInit, force);
39
+ } catch (error) {
40
+ dispatch("error", error);
41
+ }
42
+ };
43
+ $:
44
+ modeText = {
45
+ "immersive-vr": "VR",
46
+ "immersive-ar": "AR",
47
+ inline: "inline"
48
+ }[mode];
49
+ $:
50
+ if (styled) {
51
+ $$restProps.style = `
52
+ position: absolute;
53
+ bottom: 24px;
54
+ left: 50%;
55
+ transform: translateX(-50%);
56
+ padding: 10px 20px;
57
+ border: 1px solid white;
58
+ background: rgba(0, 0, 0, 0.1);
59
+ color: white;
60
+ outline: none;
61
+ z-index: 10;
62
+ ${$$restProps.style ?? ""}
63
+ `;
64
+ }
65
+ </script>
66
+
67
+ {#await getXRSupportState(mode) then state}
68
+ <button {...$$restProps} on:click={() => handleButtonClick(state)}>
69
+ {#if state === 'unsupported'}
70
+ {modeText} unsupported
71
+ {:else if state === 'insecure'}
72
+ HTTPS needed
73
+ {:else if state === 'blocked'}
74
+ {modeText} blocked
75
+ {:else if state === 'supported'}
76
+ {$session ? 'Exit' : 'Enter'} {modeText}
77
+ {/if}
78
+ </button>
79
+ {/await}
@@ -0,0 +1,265 @@
1
+ /// <reference types="webxr" />
2
+ import { SvelteComponent } from "svelte";
3
+ declare const __propDef: {
4
+ props: {
5
+ disabled?: boolean | null | undefined;
6
+ form?: string | null | undefined;
7
+ formaction?: string | null | undefined;
8
+ formenctype?: string | null | undefined;
9
+ formmethod?: string | null | undefined;
10
+ formnovalidate?: boolean | null | undefined;
11
+ formtarget?: string | null | undefined;
12
+ name?: string | null | undefined;
13
+ type?: "submit" | "reset" | "button" | null | undefined;
14
+ value?: string | number | string[] | null | undefined;
15
+ accesskey?: string | null | undefined;
16
+ autofocus?: boolean | null | undefined;
17
+ class?: string | null | undefined;
18
+ contenteditable?: import("svelte/elements").Booleanish | "inherit" | null | undefined;
19
+ contextmenu?: string | null | undefined;
20
+ dir?: string | null | undefined;
21
+ draggable?: import("svelte/elements").Booleanish | null | undefined;
22
+ enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | null | undefined;
23
+ hidden?: boolean | null | undefined;
24
+ id?: string | null | undefined;
25
+ lang?: string | null | undefined;
26
+ part?: string | null | undefined;
27
+ placeholder?: string | null | undefined;
28
+ slot?: string | null | undefined;
29
+ spellcheck?: import("svelte/elements").Booleanish | null | undefined;
30
+ style?: string | null | undefined;
31
+ tabindex?: number | null | undefined;
32
+ title?: string | null | undefined;
33
+ translate?: "" | "yes" | "no" | null | undefined;
34
+ inert?: boolean | null | undefined;
35
+ radiogroup?: string | null | undefined;
36
+ role?: import("svelte/elements").AriaRole | null | undefined;
37
+ about?: string | null | undefined;
38
+ datatype?: string | null | undefined;
39
+ inlist?: any;
40
+ prefix?: string | null | undefined;
41
+ property?: string | null | undefined;
42
+ resource?: string | null | undefined;
43
+ typeof?: string | null | undefined;
44
+ vocab?: string | null | undefined;
45
+ autocapitalize?: string | null | undefined;
46
+ autocorrect?: string | null | undefined;
47
+ autosave?: string | null | undefined;
48
+ color?: string | null | undefined;
49
+ itemprop?: string | null | undefined;
50
+ itemscope?: boolean | null | undefined;
51
+ itemtype?: string | null | undefined;
52
+ itemid?: string | null | undefined;
53
+ itemref?: string | null | undefined;
54
+ results?: number | null | undefined;
55
+ security?: string | null | undefined;
56
+ unselectable?: "on" | "off" | null | undefined;
57
+ inputmode?: "search" | "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | null | undefined;
58
+ is?: string | null | undefined;
59
+ 'bind:innerHTML'?: string | null | undefined;
60
+ 'bind:textContent'?: string | null | undefined;
61
+ 'bind:innerText'?: string | null | undefined;
62
+ 'bind:contentRect'?: DOMRectReadOnly | null | undefined;
63
+ 'bind:contentBoxSize'?: ResizeObserverSize[] | null | undefined;
64
+ 'bind:borderBoxSize'?: ResizeObserverSize[] | null | undefined;
65
+ 'bind:devicePixelContentBoxSize'?: ResizeObserverSize[] | null | undefined;
66
+ 'data-sveltekit-keepfocus'?: true | "" | "off" | null | undefined;
67
+ 'data-sveltekit-noscroll'?: true | "" | "off" | null | undefined;
68
+ 'data-sveltekit-preload-code'?: true | "" | "off" | "eager" | "viewport" | "hover" | "tap" | null | undefined;
69
+ 'data-sveltekit-preload-data'?: true | "" | "off" | "hover" | "tap" | null | undefined;
70
+ 'data-sveltekit-reload'?: true | "" | "off" | null | undefined;
71
+ 'data-sveltekit-replacestate'?: true | "" | "off" | null | undefined;
72
+ 'aria-activedescendant'?: string | null | undefined;
73
+ 'aria-atomic'?: import("svelte/elements").Booleanish | null | undefined;
74
+ 'aria-autocomplete'?: "inline" | "list" | "none" | "both" | null | undefined;
75
+ 'aria-busy'?: import("svelte/elements").Booleanish | null | undefined;
76
+ 'aria-checked'?: boolean | "true" | "false" | "mixed" | null | undefined;
77
+ 'aria-colcount'?: number | null | undefined;
78
+ 'aria-colindex'?: number | null | undefined;
79
+ 'aria-colspan'?: number | null | undefined;
80
+ 'aria-controls'?: string | null | undefined;
81
+ 'aria-current'?: import("svelte/elements").Booleanish | "page" | "step" | "location" | "date" | "time" | null | undefined;
82
+ 'aria-describedby'?: string | null | undefined;
83
+ 'aria-details'?: string | null | undefined;
84
+ 'aria-disabled'?: import("svelte/elements").Booleanish | null | undefined;
85
+ 'aria-dropeffect'?: "link" | "none" | "copy" | "execute" | "move" | "popup" | null | undefined;
86
+ 'aria-errormessage'?: string | null | undefined;
87
+ 'aria-expanded'?: import("svelte/elements").Booleanish | null | undefined;
88
+ 'aria-flowto'?: string | null | undefined;
89
+ 'aria-grabbed'?: import("svelte/elements").Booleanish | null | undefined;
90
+ 'aria-haspopup'?: import("svelte/elements").Booleanish | "dialog" | "grid" | "listbox" | "menu" | "tree" | null | undefined;
91
+ 'aria-hidden'?: import("svelte/elements").Booleanish | null | undefined;
92
+ 'aria-invalid'?: import("svelte/elements").Booleanish | "grammar" | "spelling" | null | undefined;
93
+ 'aria-keyshortcuts'?: string | null | undefined;
94
+ 'aria-label'?: string | null | undefined;
95
+ 'aria-labelledby'?: string | null | undefined;
96
+ 'aria-level'?: number | null | undefined;
97
+ 'aria-live'?: "off" | "assertive" | "polite" | null | undefined;
98
+ 'aria-modal'?: import("svelte/elements").Booleanish | null | undefined;
99
+ 'aria-multiline'?: import("svelte/elements").Booleanish | null | undefined;
100
+ 'aria-multiselectable'?: import("svelte/elements").Booleanish | null | undefined;
101
+ 'aria-orientation'?: "horizontal" | "vertical" | null | undefined;
102
+ 'aria-owns'?: string | null | undefined;
103
+ 'aria-placeholder'?: string | null | undefined;
104
+ 'aria-posinset'?: number | null | undefined;
105
+ 'aria-pressed'?: boolean | "true" | "false" | "mixed" | null | undefined;
106
+ 'aria-readonly'?: import("svelte/elements").Booleanish | null | undefined;
107
+ 'aria-relevant'?: "text" | "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | null | undefined;
108
+ 'aria-required'?: import("svelte/elements").Booleanish | null | undefined;
109
+ 'aria-roledescription'?: string | null | undefined;
110
+ 'aria-rowcount'?: number | null | undefined;
111
+ 'aria-rowindex'?: number | null | undefined;
112
+ 'aria-rowspan'?: number | null | undefined;
113
+ 'aria-selected'?: import("svelte/elements").Booleanish | null | undefined;
114
+ 'aria-setsize'?: number | null | undefined;
115
+ 'aria-sort'?: "none" | "ascending" | "descending" | "other" | null | undefined;
116
+ 'aria-valuemax'?: number | null | undefined;
117
+ 'aria-valuemin'?: number | null | undefined;
118
+ 'aria-valuenow'?: number | null | undefined;
119
+ 'aria-valuetext'?: string | null | undefined;
120
+ 'on:copy'?: import("svelte/elements").ClipboardEventHandler<HTMLButtonElement> | null | undefined;
121
+ 'on:cut'?: import("svelte/elements").ClipboardEventHandler<HTMLButtonElement> | null | undefined;
122
+ 'on:paste'?: import("svelte/elements").ClipboardEventHandler<HTMLButtonElement> | null | undefined;
123
+ 'on:compositionend'?: import("svelte/elements").CompositionEventHandler<HTMLButtonElement> | null | undefined;
124
+ 'on:compositionstart'?: import("svelte/elements").CompositionEventHandler<HTMLButtonElement> | null | undefined;
125
+ 'on:compositionupdate'?: import("svelte/elements").CompositionEventHandler<HTMLButtonElement> | null | undefined;
126
+ 'on:focus'?: import("svelte/elements").FocusEventHandler<HTMLButtonElement> | null | undefined;
127
+ 'on:focusin'?: import("svelte/elements").FocusEventHandler<HTMLButtonElement> | null | undefined;
128
+ 'on:focusout'?: import("svelte/elements").FocusEventHandler<HTMLButtonElement> | null | undefined;
129
+ 'on:blur'?: import("svelte/elements").FocusEventHandler<HTMLButtonElement> | null | undefined;
130
+ 'on:change'?: import("svelte/elements").FormEventHandler<HTMLButtonElement> | null | undefined;
131
+ 'on:beforeinput'?: import("svelte/elements").EventHandler<InputEvent, HTMLButtonElement> | null | undefined;
132
+ 'on:input'?: import("svelte/elements").FormEventHandler<HTMLButtonElement> | null | undefined;
133
+ 'on:reset'?: import("svelte/elements").FormEventHandler<HTMLButtonElement> | null | undefined;
134
+ 'on:submit'?: import("svelte/elements").EventHandler<SubmitEvent, HTMLButtonElement> | null | undefined;
135
+ 'on:invalid'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
136
+ 'on:formdata'?: import("svelte/elements").EventHandler<FormDataEvent, HTMLButtonElement> | null | undefined;
137
+ 'on:load'?: import("svelte/elements").EventHandler<Event, Element> | null | undefined;
138
+ 'on:error'?: import("svelte/elements").EventHandler<Event, Element> | null | undefined;
139
+ 'on:toggle'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
140
+ 'on:keydown'?: import("svelte/elements").KeyboardEventHandler<HTMLButtonElement> | null | undefined;
141
+ 'on:keypress'?: import("svelte/elements").KeyboardEventHandler<HTMLButtonElement> | null | undefined;
142
+ 'on:keyup'?: import("svelte/elements").KeyboardEventHandler<HTMLButtonElement> | null | undefined;
143
+ 'on:abort'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
144
+ 'on:canplay'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
145
+ 'on:canplaythrough'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
146
+ 'on:cuechange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
147
+ 'on:durationchange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
148
+ 'on:emptied'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
149
+ 'on:encrypted'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
150
+ 'on:ended'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
151
+ 'on:loadeddata'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
152
+ 'on:loadedmetadata'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
153
+ 'on:loadstart'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
154
+ 'on:pause'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
155
+ 'on:play'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
156
+ 'on:playing'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
157
+ 'on:progress'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
158
+ 'on:ratechange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
159
+ 'on:seeked'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
160
+ 'on:seeking'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
161
+ 'on:stalled'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
162
+ 'on:suspend'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
163
+ 'on:timeupdate'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
164
+ 'on:volumechange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
165
+ 'on:waiting'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
166
+ 'on:auxclick'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
167
+ 'on:click'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
168
+ 'on:contextmenu'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
169
+ 'on:dblclick'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
170
+ 'on:drag'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
171
+ 'on:dragend'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
172
+ 'on:dragenter'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
173
+ 'on:dragexit'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
174
+ 'on:dragleave'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
175
+ 'on:dragover'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
176
+ 'on:dragstart'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
177
+ 'on:drop'?: import("svelte/elements").DragEventHandler<HTMLButtonElement> | null | undefined;
178
+ 'on:mousedown'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
179
+ 'on:mouseenter'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
180
+ 'on:mouseleave'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
181
+ 'on:mousemove'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
182
+ 'on:mouseout'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
183
+ 'on:mouseover'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
184
+ 'on:mouseup'?: import("svelte/elements").MouseEventHandler<HTMLButtonElement> | null | undefined;
185
+ 'on:select'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
186
+ 'on:selectionchange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
187
+ 'on:selectstart'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
188
+ 'on:touchcancel'?: import("svelte/elements").TouchEventHandler<HTMLButtonElement> | null | undefined;
189
+ 'on:touchend'?: import("svelte/elements").TouchEventHandler<HTMLButtonElement> | null | undefined;
190
+ 'on:touchmove'?: import("svelte/elements").TouchEventHandler<HTMLButtonElement> | null | undefined;
191
+ 'on:touchstart'?: import("svelte/elements").TouchEventHandler<HTMLButtonElement> | null | undefined;
192
+ 'on:gotpointercapture'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
193
+ 'on:pointercancel'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
194
+ 'on:pointerdown'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
195
+ 'on:pointerenter'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
196
+ 'on:pointerleave'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
197
+ 'on:pointermove'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
198
+ 'on:pointerout'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
199
+ 'on:pointerover'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
200
+ 'on:pointerup'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
201
+ 'on:lostpointercapture'?: import("svelte/elements").PointerEventHandler<HTMLButtonElement> | null | undefined;
202
+ 'on:scroll'?: import("svelte/elements").UIEventHandler<HTMLButtonElement> | null | undefined;
203
+ 'on:resize'?: import("svelte/elements").UIEventHandler<HTMLButtonElement> | null | undefined;
204
+ 'on:wheel'?: import("svelte/elements").WheelEventHandler<HTMLButtonElement> | null | undefined;
205
+ 'on:animationstart'?: import("svelte/elements").AnimationEventHandler<HTMLButtonElement> | null | undefined;
206
+ 'on:animationend'?: import("svelte/elements").AnimationEventHandler<HTMLButtonElement> | null | undefined;
207
+ 'on:animationiteration'?: import("svelte/elements").AnimationEventHandler<HTMLButtonElement> | null | undefined;
208
+ 'on:transitionstart'?: import("svelte/elements").TransitionEventHandler<HTMLButtonElement> | null | undefined;
209
+ 'on:transitionrun'?: import("svelte/elements").TransitionEventHandler<HTMLButtonElement> | null | undefined;
210
+ 'on:transitionend'?: import("svelte/elements").TransitionEventHandler<HTMLButtonElement> | null | undefined;
211
+ 'on:transitioncancel'?: import("svelte/elements").TransitionEventHandler<HTMLButtonElement> | null | undefined;
212
+ 'on:outrostart'?: import("svelte/elements").EventHandler<CustomEvent<null>, HTMLButtonElement> | null | undefined;
213
+ 'on:outroend'?: import("svelte/elements").EventHandler<CustomEvent<null>, HTMLButtonElement> | null | undefined;
214
+ 'on:introstart'?: import("svelte/elements").EventHandler<CustomEvent<null>, HTMLButtonElement> | null | undefined;
215
+ 'on:introend'?: import("svelte/elements").EventHandler<CustomEvent<null>, HTMLButtonElement> | null | undefined;
216
+ 'on:message'?: import("svelte/elements").MessageEventHandler<HTMLButtonElement> | null | undefined;
217
+ 'on:messageerror'?: import("svelte/elements").MessageEventHandler<HTMLButtonElement> | null | undefined;
218
+ 'on:visibilitychange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
219
+ 'on:cancel'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
220
+ 'on:close'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
221
+ 'on:fullscreenchange'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
222
+ 'on:fullscreenerror'?: import("svelte/elements").EventHandler<Event, HTMLButtonElement> | null | undefined;
223
+ mode: XRSessionMode;
224
+ sessionInit?: XRSessionInit & {
225
+ domOverlay?: {
226
+ root: HTMLElement;
227
+ } | undefined;
228
+ };
229
+ force?: 'enter' | 'exit';
230
+ styled?: boolean;
231
+ };
232
+ events: {
233
+ click: CustomEvent<{
234
+ state: 'unsupported' | 'insecure' | 'blocked' | 'supported';
235
+ }>;
236
+ error: CustomEvent<Error>;
237
+ } & {
238
+ [evt: string]: CustomEvent<any>;
239
+ };
240
+ slots: {};
241
+ };
242
+ export type XrButtonProps = typeof __propDef.props;
243
+ export type XrButtonEvents = typeof __propDef.events;
244
+ export type XrButtonSlots = typeof __propDef.slots;
245
+ /**
246
+ * `<XRButton />` is an HTML `<button />` that can be used to init and
247
+ * display info about your WebXR session. This is aliased by `ARButton` and
248
+ * `VRButton` with sensible session defaults.
249
+ *
250
+ * ```svelte
251
+ * <XRButton
252
+ * mode={'immersive-ar' | 'immersive-vr' | 'inline'}
253
+ * sessionInit={{
254
+ * optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers']
255
+ * }}
256
+ * force={'enter' | 'exit' | undefined}
257
+ * styled={'true' | 'false'}
258
+ * on:error={(event) => {}}
259
+ * on:click={(event) => {}}
260
+ * />
261
+ * ```
262
+ */
263
+ export default class XrButton extends SvelteComponent<XrButtonProps, XrButtonEvents, XrButtonSlots> {
264
+ }
265
+ export {};
@@ -0,0 +1,7 @@
1
+ export { useController, useGamepad } from './useController';
2
+ export { useControllerEvent, useHandEvent } from './useEvent';
3
+ export { useHand } from './useHand';
4
+ export { useHandJoint } from './useHandJoint';
5
+ export { useHitTest } from './useHitTest';
6
+ export { useTeleport } from './useTeleport';
7
+ export { useXR } from './useXR';
@@ -0,0 +1,7 @@
1
+ export { useController, useGamepad } from './useController';
2
+ export { useControllerEvent, useHandEvent } from './useEvent';
3
+ export { useHand } from './useHand';
4
+ export { useHandJoint } from './useHandJoint';
5
+ export { useHitTest } from './useHitTest';
6
+ export { useTeleport } from './useTeleport';
7
+ export { useXR } from './useXR';
@@ -0,0 +1,14 @@
1
+ /// <reference types="webxr" />
2
+ import { type CurrentWritable } from '@threlte/core';
3
+ import type { XRController } from '../types';
4
+ export declare const left: CurrentWritable<XRController | undefined>;
5
+ export declare const right: CurrentWritable<XRController | undefined>;
6
+ export declare const gaze: CurrentWritable<XRController | undefined>;
7
+ /**
8
+ * Provides a reference to a current XRController, filtered by handedness.
9
+ */
10
+ export declare const useController: (handedness: XRHandedness) => CurrentWritable<XRController | undefined>;
11
+ /**
12
+ * Provides a reference to the gamepad attached to a current XRController.
13
+ */
14
+ export declare const useGamepad: (handedness: 'left' | 'right') => CurrentWritable<Gamepad | undefined>;
@@ -0,0 +1,32 @@
1
+ import { currentWritable } from '@threlte/core';
2
+ export const left = currentWritable(undefined);
3
+ export const right = currentWritable(undefined);
4
+ export const gaze = currentWritable(undefined);
5
+ const gamepadLeft = currentWritable(undefined);
6
+ const gamepadRight = currentWritable(undefined);
7
+ left.subscribe((value) => gamepadLeft.set(value?.inputSource.gamepad));
8
+ right.subscribe((value) => gamepadRight.set(value?.inputSource.gamepad));
9
+ /**
10
+ * Provides a reference to a current XRController, filtered by handedness.
11
+ */
12
+ export const useController = (handedness) => {
13
+ switch (handedness) {
14
+ case 'left':
15
+ return left;
16
+ case 'right':
17
+ return right;
18
+ case 'none':
19
+ return gaze;
20
+ }
21
+ };
22
+ /**
23
+ * Provides a reference to the gamepad attached to a current XRController.
24
+ */
25
+ export const useGamepad = (handedness) => {
26
+ switch (handedness) {
27
+ case 'left':
28
+ return gamepadLeft;
29
+ case 'right':
30
+ return gamepadRight;
31
+ }
32
+ };
@@ -0,0 +1,14 @@
1
+ /// <reference types="webxr" />
2
+ import type { XRControllerEventType, XRHandEventType, XRControllerEvent, XRHandEvent } from '../types';
3
+ /**
4
+ * Adds listeners for controller events.
5
+ */
6
+ export declare const useControllerEvent: (event: XRControllerEventType, handler: (event: XRControllerEvent) => void, { handedness }?: {
7
+ handedness?: XRHandedness;
8
+ }) => void;
9
+ /**
10
+ * Adds listeners for hand events.
11
+ */
12
+ export declare const useHandEvent: (event: XRHandEventType, handler: (event: XRHandEvent<XRHandEventType, null | THREE.XRHandSpace>) => void, { handedness }?: {
13
+ handedness?: 'left' | 'right';
14
+ }) => void;
@@ -0,0 +1,34 @@
1
+ import { onDestroy } from 'svelte';
2
+ import { isHandTracking } from '../internal/stores';
3
+ import { on, off } from '../internal/events';
4
+ /**
5
+ * Adds listeners for controller events.
6
+ */
7
+ export const useControllerEvent = (event, handler, { handedness } = {}) => {
8
+ const listener = (event, metadata) => {
9
+ if (metadata?.input === 'hand')
10
+ return;
11
+ if (handedness !== undefined && event.data?.handedness !== handedness) {
12
+ return;
13
+ }
14
+ handler(event);
15
+ };
16
+ on(event, listener);
17
+ onDestroy(() => off(event, listener));
18
+ };
19
+ /**
20
+ * Adds listeners for hand events.
21
+ */
22
+ export const useHandEvent = (event, handler, { handedness } = {}) => {
23
+ const listener = (event, metadata) => {
24
+ if (metadata?.input === 'controller')
25
+ return;
26
+ const eventHandedness = event.handedness ?? event.data?.handedness;
27
+ if (handedness !== undefined && eventHandedness !== handedness) {
28
+ return;
29
+ }
30
+ handler(event);
31
+ };
32
+ on(event, listener);
33
+ onDestroy(() => off(event, listener));
34
+ };
@@ -0,0 +1,8 @@
1
+ import { type CurrentWritable } from '@threlte/core';
2
+ import type { XRHand } from '../types';
3
+ export declare const left: CurrentWritable<XRHand | undefined>;
4
+ export declare const right: CurrentWritable<XRHand | undefined>;
5
+ /**
6
+ * Provides a reference to a current XRHand, filtered by handedness.
7
+ */
8
+ export declare const useHand: (handedness: 'left' | 'right') => CurrentWritable<undefined | XRHand>;