@threlte/xr 1.0.8 → 1.1.0

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 (67) hide show
  1. package/dist/components/ARButton.svelte.d.ts +11 -24
  2. package/dist/components/Controller.svelte +31 -27
  3. package/dist/components/Controller.svelte.d.ts +7 -5
  4. package/dist/components/Hand.svelte +24 -28
  5. package/dist/components/Hand.svelte.d.ts +6 -4
  6. package/dist/components/Headset.svelte.d.ts +4 -2
  7. package/dist/components/VRButton.svelte.d.ts +5 -18
  8. package/dist/components/XR.svelte +44 -43
  9. package/dist/components/XR.svelte.d.ts +24 -22
  10. package/dist/components/XRButton.svelte +3 -3
  11. package/dist/components/XRButton.svelte.d.ts +26 -23
  12. package/dist/components/internal/Cursor.svelte.d.ts +4 -2
  13. package/dist/components/internal/PointerCursor.svelte +8 -7
  14. package/dist/components/internal/PointerCursor.svelte.d.ts +5 -3
  15. package/dist/components/internal/ShortRay.svelte +3 -3
  16. package/dist/components/internal/ShortRay.svelte.d.ts +5 -3
  17. package/dist/components/internal/TeleportCursor.svelte +8 -7
  18. package/dist/components/internal/TeleportCursor.svelte.d.ts +5 -3
  19. package/dist/components/internal/TeleportRay.svelte +5 -5
  20. package/dist/components/internal/TeleportRay.svelte.d.ts +5 -3
  21. package/dist/hooks/currentReadable.svelte.d.ts +5 -0
  22. package/dist/hooks/currentReadable.svelte.js +11 -0
  23. package/dist/hooks/useController.svelte.d.ts +13 -0
  24. package/dist/hooks/useController.svelte.js +22 -0
  25. package/dist/hooks/useHand.svelte.d.ts +12 -0
  26. package/dist/hooks/{useHand.js → useHand.svelte.js} +8 -5
  27. package/dist/hooks/{useHandJoint.d.ts → useHandJoint.svelte.d.ts} +1 -1
  28. package/dist/hooks/useHandJoint.svelte.js +21 -0
  29. package/dist/hooks/useHeadset.js +1 -1
  30. package/dist/hooks/useHitTest.svelte.js +67 -0
  31. package/dist/hooks/useTeleport.js +1 -2
  32. package/dist/hooks/useXR.d.ts +6 -7
  33. package/dist/hooks/useXR.js +10 -12
  34. package/dist/index.d.ts +4 -4
  35. package/dist/index.js +4 -4
  36. package/dist/internal/raf.d.ts +1 -0
  37. package/dist/internal/raf.js +2 -0
  38. package/dist/internal/setupControllers.js +13 -14
  39. package/dist/internal/setupHands.js +8 -9
  40. package/dist/internal/{setupHeadset.js → setupHeadset.svelte.js} +6 -6
  41. package/dist/internal/setupRaf.svelte.js +17 -0
  42. package/dist/internal/state.svelte.d.ts +51 -0
  43. package/dist/internal/state.svelte.js +40 -0
  44. package/dist/internal/useHandTrackingState.js +10 -7
  45. package/dist/lib/getXRSessionOptions.d.ts +1 -1
  46. package/dist/lib/toggleXRSession.d.ts +3 -3
  47. package/dist/lib/toggleXRSession.js +3 -3
  48. package/dist/plugins/pointerControls/compute.js +2 -6
  49. package/dist/plugins/pointerControls/index.js +4 -10
  50. package/dist/plugins/pointerControls/{setup.js → setup.svelte.js} +18 -19
  51. package/dist/plugins/teleportControls/compute.js +2 -6
  52. package/dist/plugins/teleportControls/index.js +4 -10
  53. package/dist/plugins/teleportControls/{setup.js → setup.svelte.js} +9 -10
  54. package/package.json +8 -8
  55. package/dist/hooks/useController.d.ts +0 -9
  56. package/dist/hooks/useController.js +0 -19
  57. package/dist/hooks/useHand.d.ts +0 -8
  58. package/dist/hooks/useHandJoint.js +0 -20
  59. package/dist/hooks/useHitTest.js +0 -79
  60. package/dist/internal/setupRaf.js +0 -16
  61. package/dist/internal/stores.d.ts +0 -43
  62. package/dist/internal/stores.js +0 -42
  63. /package/dist/hooks/{useHitTest.d.ts → useHitTest.svelte.d.ts} +0 -0
  64. /package/dist/internal/{setupHeadset.d.ts → setupHeadset.svelte.d.ts} +0 -0
  65. /package/dist/internal/{setupRaf.d.ts → setupRaf.svelte.d.ts} +0 -0
  66. /package/dist/plugins/pointerControls/{setup.d.ts → setup.svelte.d.ts} +0 -0
  67. /package/dist/plugins/teleportControls/{setup.d.ts → setup.svelte.d.ts} +0 -0
@@ -1,3 +1,12 @@
1
+ import type { ComponentProps } from 'svelte';
2
+ import XRButton from './XRButton.svelte';
3
+ type Props = Omit<ComponentProps<typeof XRButton>, 'mode' | 'sessionInit'> & {
4
+ sessionInit?: XRSessionInit & {
5
+ domOverlay?: {
6
+ root: HTMLElement;
7
+ } | undefined;
8
+ };
9
+ };
1
10
  /**
2
11
  * `<ARButton />` is an HTML `<button />` that can be used to init and display info about your immersive AR session.
3
12
  *
@@ -8,28 +17,6 @@
8
17
  * />
9
18
  * ```
10
19
  */
11
- declare const ArButton: import("svelte").Component<Omit<import("svelte/elements").HTMLButtonAttributes & {
12
- mode: XRSessionMode;
13
- sessionInit?: XRSessionInit & {
14
- domOverlay?: {
15
- root: HTMLElement;
16
- } | undefined;
17
- };
18
- force?: "enter" | "exit";
19
- styled?: boolean;
20
- children?: import("svelte").Snippet<[{
21
- state: "unsupported" | "insecure" | "blocked" | "supported";
22
- }]>;
23
- onclick?: (event: {
24
- state: "unsupported" | "insecure" | "blocked" | "supported";
25
- nativeEvent: MouseEvent;
26
- }) => void;
27
- onerror?: (error: Error) => void;
28
- }, "mode" | "sessionInit"> & {
29
- sessionInit?: XRSessionInit & {
30
- domOverlay?: {
31
- root: HTMLElement;
32
- } | undefined;
33
- };
34
- }, {}, "">;
20
+ declare const ArButton: import("svelte").Component<Props, {}, "">;
21
+ type ArButton = ReturnType<typeof ArButton>;
35
22
  export default ArButton;
@@ -1,13 +1,15 @@
1
1
  <!--
2
2
  @component `<Controller />` represents a THREE.XRTargetRaySpace, a THREE.XRGripSpace, and a controller model.
3
3
  -->
4
- <script
5
- lang="ts"
6
- module
7
- >
8
- import { T } from '@threlte/core'
9
- import { left as leftStore, right as rightStore } from '../hooks/useController'
10
- import { isHandTracking, pointerState, teleportState, controllerEvents } from '../internal/stores'
4
+ <script lang="ts">
5
+ import { T, useThrelte } from '@threlte/core'
6
+ import { controllers } from '../hooks/useController.svelte'
7
+ import {
8
+ isHandTracking,
9
+ pointerState,
10
+ teleportState,
11
+ controllerEvents
12
+ } from '../internal/state.svelte'
11
13
  import type { XRControllerEvents } from '../types'
12
14
  import PointerCursor from './internal/PointerCursor.svelte'
13
15
  import ShortRay from './internal/ShortRay.svelte'
@@ -15,13 +17,6 @@
15
17
  import TeleportRay from './internal/TeleportRay.svelte'
16
18
  import type { Snippet } from 'svelte'
17
19
 
18
- const stores = {
19
- left: leftStore,
20
- right: rightStore
21
- } as const
22
- </script>
23
-
24
- <script lang="ts">
25
20
  type Props = {
26
21
  children?: Snippet
27
22
  grip?: Snippet
@@ -75,10 +70,12 @@
75
70
  teleportCursor: teleportCursorSnippet
76
71
  }: Props = $props()
77
72
 
73
+ const { scene } = useThrelte()
74
+
78
75
  const handedness = $derived<'left' | 'right'>(left ? 'left' : right ? 'right' : hand ?? 'left')
79
76
 
80
- $effect.pre(() =>
81
- controllerEvents[handedness].set({
77
+ $effect.pre(() => {
78
+ controllerEvents[handedness] = {
82
79
  onconnected,
83
80
  ondisconnected,
84
81
  onselect,
@@ -87,20 +84,27 @@
87
84
  onsqueeze,
88
85
  onsqueezeend,
89
86
  onsqueezestart
90
- })
91
- )
92
-
93
- const store = $derived(stores[handedness])
94
- const grip = $derived($store?.grip)
95
- const targetRay = $derived($store?.targetRay)
96
- const model = $derived($store?.model)
97
- const hasPointerControls = $derived($pointerState[handedness].enabled)
98
- const hasTeleportControls = $derived($teleportState[handedness].enabled)
87
+ }
88
+
89
+ return () => {
90
+ controllerEvents[handedness] = undefined
91
+ }
92
+ })
93
+
94
+ const xrController = $derived(controllers[handedness])
95
+ const grip = $derived(xrController?.grip)
96
+ const targetRay = $derived(xrController?.targetRay)
97
+ const model = $derived(xrController?.model)
98
+ const hasPointerControls = $derived(pointerState[handedness].enabled)
99
+ const hasTeleportControls = $derived(teleportState[handedness].enabled)
99
100
  </script>
100
101
 
101
- {#if !$isHandTracking}
102
+ {#if !isHandTracking.current}
102
103
  {#if grip}
103
- <T is={grip}>
104
+ <T
105
+ is={grip}
106
+ attach={scene}
107
+ >
104
108
  {#if children}
105
109
  {@render children?.()}
106
110
  {:else}
@@ -1,7 +1,6 @@
1
1
  import type { XRControllerEvents } from '../types';
2
2
  import type { Snippet } from 'svelte';
3
- /** `<Controller />` represents a THREE.XRTargetRaySpace, a THREE.XRGripSpace, and a controller model. */
4
- declare const Controller: import("svelte").Component<{
3
+ type Props = {
5
4
  children?: Snippet;
6
5
  grip?: Snippet;
7
6
  targetRay?: Snippet;
@@ -9,7 +8,7 @@ declare const Controller: import("svelte").Component<{
9
8
  pointerCursor?: Snippet;
10
9
  teleportRay?: Snippet;
11
10
  teleportCursor?: Snippet;
12
- } & (XRControllerEvents & ({
11
+ } & XRControllerEvents & ({
13
12
  /** Whether the controller should be matched with the left hand. */
14
13
  left: true;
15
14
  right?: undefined;
@@ -21,8 +20,11 @@ declare const Controller: import("svelte").Component<{
21
20
  hand?: undefined;
22
21
  } | {
23
22
  /** Whether the controller should be matched with the left or right hand. */
24
- hand: "left" | "right";
23
+ hand: 'left' | 'right';
25
24
  left?: undefined;
26
25
  right?: undefined;
27
- })), {}, "">;
26
+ });
27
+ /** `<Controller />` represents a THREE.XRTargetRaySpace, a THREE.XRGripSpace, and a controller model. */
28
+ declare const Controller: import("svelte").Component<Props, {}, "">;
29
+ type Controller = ReturnType<typeof Controller>;
28
30
  export default Controller;
@@ -1,21 +1,11 @@
1
- <script
2
- lang="ts"
3
- module
4
- >
1
+ <script lang="ts">
5
2
  import { Group } from 'three'
6
3
  import { T, useThrelte, useTask } from '@threlte/core'
7
4
  import type { XRHandEvents } from '../types'
8
- import { isHandTracking, handEvents } from '../internal/stores'
9
- import { left as leftStore, right as rightStore } from '../hooks/useHand'
5
+ import { isHandTracking, handEvents } from '../internal/state.svelte'
6
+ import { hands } from '../hooks/useHand.svelte'
10
7
  import type { Snippet } from 'svelte'
11
8
 
12
- const stores = {
13
- left: leftStore,
14
- right: rightStore
15
- } as const
16
- </script>
17
-
18
- <script lang="ts">
19
9
  type Props = {
20
10
  children?: Snippet
21
11
  targetRay?: Snippet
@@ -56,19 +46,21 @@
56
46
  }: Props = $props()
57
47
 
58
48
  const { scene, renderer, scheduler, renderStage } = useThrelte()
59
- const { xr } = renderer
60
- const space = xr.getReferenceSpace()
61
49
 
62
50
  const handedness = $derived<'left' | 'right'>(left ? 'left' : right ? 'right' : hand ?? 'left')
63
51
 
64
- $effect.pre(() =>
65
- handEvents[handedness].set({
52
+ $effect.pre(() => {
53
+ handEvents[handedness] = {
66
54
  onconnected,
67
55
  ondisconnected,
68
56
  onpinchend,
69
57
  onpinchstart
70
- })
71
- )
58
+ }
59
+
60
+ return () => {
61
+ handEvents[handedness] = undefined
62
+ }
63
+ })
72
64
 
73
65
  const group = new Group()
74
66
 
@@ -82,7 +74,8 @@
82
74
  */
83
75
  const { start, stop } = useTask(
84
76
  () => {
85
- const frame = xr.getFrame()
77
+ const frame = renderer.xr.getFrame()
78
+ const space = renderer.xr.getReferenceSpace()
86
79
  const joint = inputSource?.get('wrist')
87
80
 
88
81
  if (joint === undefined || space === null) return
@@ -103,33 +96,36 @@
103
96
  )
104
97
 
105
98
  $effect.pre(() => {
106
- if ($isHandTracking && (wrist !== undefined || children !== undefined) && inputSource) {
99
+ if (isHandTracking.current && (wrist !== undefined || children !== undefined) && inputSource) {
107
100
  start()
108
101
  } else {
109
102
  stop()
110
103
  }
111
104
  })
112
105
 
113
- const store = $derived(stores[handedness])
114
- const inputSource = $derived($store?.inputSource)
115
- const model = $derived($store?.model)
106
+ const xrHand = $derived(hands[handedness])
107
+ const inputSource = $derived(xrHand?.inputSource)
108
+ const model = $derived(xrHand?.model)
116
109
  </script>
117
110
 
118
- {#if $store?.hand && $isHandTracking}
119
- <T is={$store.hand}>
111
+ {#if xrHand?.hand && isHandTracking.current}
112
+ <T
113
+ is={xrHand.hand}
114
+ attach={scene}
115
+ >
120
116
  {#if children === undefined}
121
117
  <T is={model} />
122
118
  {/if}
123
119
  </T>
124
120
 
125
121
  {#if targetRay !== undefined}
126
- <T is={$store.targetRay}>
122
+ <T is={xrHand.targetRay}>
127
123
  {@render targetRay()}
128
124
  </T>
129
125
  {/if}
130
126
  {/if}
131
127
 
132
- {#if $isHandTracking}
128
+ {#if isHandTracking.current}
133
129
  <T
134
130
  is={group}
135
131
  attach={scene}
@@ -1,10 +1,10 @@
1
1
  import type { XRHandEvents } from '../types';
2
2
  import type { Snippet } from 'svelte';
3
- declare const Hand: import("svelte").Component<{
3
+ type Props = {
4
4
  children?: Snippet;
5
5
  targetRay?: Snippet;
6
6
  wrist?: Snippet;
7
- } & (XRHandEvents & ({
7
+ } & XRHandEvents & ({
8
8
  /** Whether the XRHand should be matched with the left hand. */
9
9
  left: true;
10
10
  right?: undefined;
@@ -16,8 +16,10 @@ declare const Hand: import("svelte").Component<{
16
16
  hand?: undefined;
17
17
  } | {
18
18
  /** Whether the XRHand should be matched with the left or right hand. */
19
- hand: "left" | "right";
19
+ hand: 'left' | 'right';
20
20
  left?: undefined;
21
21
  right?: undefined;
22
- })), {}, "">;
22
+ });
23
+ declare const Hand: import("svelte").Component<Props, {}, "">;
24
+ type Hand = ReturnType<typeof Hand>;
23
25
  export default Hand;
@@ -1,8 +1,10 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { Group } from 'three';
3
- declare const Headset: import("svelte").Component<{
3
+ interface Props {
4
4
  children?: Snippet<[{
5
5
  ref: Group;
6
6
  }]>;
7
- }, {}, "">;
7
+ }
8
+ declare const Headset: import("svelte").Component<Props, {}, "">;
9
+ type Headset = ReturnType<typeof Headset>;
8
10
  export default Headset;
@@ -1,3 +1,6 @@
1
+ import type { ComponentProps } from 'svelte';
2
+ import XRButton from './XRButton.svelte';
3
+ type Props = Omit<ComponentProps<typeof XRButton>, 'mode' | 'sessionInit'>;
1
4
  /**
2
5
  * `<VRButton />` is an HTML `<button />` that can be used to init and display info about your immersive VR session.
3
6
  *
@@ -8,22 +11,6 @@
8
11
  * />
9
12
  * ```
10
13
  */
11
- declare const VrButton: import("svelte").Component<Omit<import("svelte/elements").HTMLButtonAttributes & {
12
- mode: XRSessionMode;
13
- sessionInit?: XRSessionInit & {
14
- domOverlay?: {
15
- root: HTMLElement;
16
- } | undefined;
17
- };
18
- force?: "enter" | "exit";
19
- styled?: boolean;
20
- children?: import("svelte").Snippet<[{
21
- state: "unsupported" | "insecure" | "blocked" | "supported";
22
- }]>;
23
- onclick?: (event: {
24
- state: "unsupported" | "insecure" | "blocked" | "supported";
25
- nativeEvent: MouseEvent;
26
- }) => void;
27
- onerror?: (error: Error) => void;
28
- }, "mode" | "sessionInit">, {}, "">;
14
+ declare const VrButton: import("svelte").Component<Props, {}, "">;
15
+ type VrButton = ReturnType<typeof VrButton>;
29
16
  export default VrButton;
@@ -18,18 +18,18 @@ This should be placed within a Threlte `<Canvas />`.
18
18
 
19
19
  -->
20
20
  <script lang="ts">
21
- import { onMount, type Snippet } from 'svelte'
22
- import { useThrelte, watch } from '@threlte/core'
21
+ import type { Snippet } from 'svelte'
22
+ import { useThrelte } from '@threlte/core'
23
23
  import type { XRSessionEvent } from '../types'
24
24
  import {
25
25
  isHandTracking,
26
26
  isPresenting,
27
27
  referenceSpaceType,
28
28
  session,
29
- xr as xrStore
30
- } from '../internal/stores'
31
- import { setupRaf } from '../internal/setupRaf'
32
- import { setupHeadset } from '../internal/setupHeadset'
29
+ xr
30
+ } from '../internal/state.svelte'
31
+ import { setupRaf } from '../internal/setupRaf.svelte'
32
+ import { setupHeadset } from '../internal/setupHeadset.svelte'
33
33
  import { setupControllers } from '../internal/setupControllers'
34
34
  import { setupHands } from '../internal/setupHands'
35
35
 
@@ -85,7 +85,6 @@ This should be placed within a Threlte `<Canvas />`.
85
85
  }: Props = $props()
86
86
 
87
87
  const { renderer, renderMode } = useThrelte()
88
- const { xr } = renderer
89
88
 
90
89
  let originalRenderMode = $renderMode
91
90
 
@@ -95,41 +94,35 @@ This should be placed within a Threlte `<Canvas />`.
95
94
  setupHands()
96
95
 
97
96
  const handleSessionStart = () => {
98
- isPresenting.set(true)
99
- onsessionstart?.({ type: 'sessionstart', target: $session } as any)
97
+ isPresenting.current = true
98
+ onsessionstart?.({ type: 'sessionstart', target: session.current } as any)
100
99
  }
101
100
 
102
101
  const handleSessionEnd = () => {
103
- onsessionend?.({ type: 'sessionend', target: $session } as any)
104
- isPresenting.set(false)
105
- session.set(undefined)
102
+ onsessionend?.({ type: 'sessionend', target: session.current } as any)
103
+ isPresenting.current = false
104
+ session.current = undefined
106
105
  }
107
106
 
108
107
  const handleVisibilityChange = (event: globalThis.XRSessionEvent) => {
109
- onvisibilitychange?.({ ...event, target: $session! })
108
+ onvisibilitychange?.({ ...event, target: session.current! })
110
109
  }
111
110
 
112
111
  const handleInputSourcesChange = (event: XRInputSourcesChangeEvent) => {
113
- $isHandTracking = Object.values(event.session.inputSources).some((source) => source.hand)
114
- oninputsourceschange?.({ ...event, target: $session! })
112
+ isHandTracking.current = Object.values(event.session.inputSources).some((source) => source.hand)
113
+ oninputsourceschange?.({ ...event, target: session.current! })
115
114
  }
116
115
 
117
116
  const handleFramerateChange = (event: globalThis.XRSessionEvent) => {
118
- onvisibilitychange?.({ ...event, target: $session! })
117
+ onvisibilitychange?.({ ...event, target: session.current! })
119
118
  }
120
119
 
121
- const updateTargetFrameRate = (frameRate?: number) => {
122
- if (frameRate === undefined) return
120
+ $effect(() => {
121
+ const currentSession = session.current
123
122
 
124
- try {
125
- $session?.updateTargetFrameRate(frameRate)
126
- } catch {
127
- // Do nothing
123
+ if (currentSession === undefined) {
124
+ return
128
125
  }
129
- }
130
-
131
- watch(session, (currentSession) => {
132
- if (currentSession === undefined) return
133
126
 
134
127
  currentSession.addEventListener('visibilitychange', handleVisibilityChange)
135
128
  currentSession.addEventListener('inputsourceschange', handleInputSourcesChange)
@@ -142,8 +135,8 @@ This should be placed within a Threlte `<Canvas />`.
142
135
  }
143
136
  })
144
137
 
145
- watch(isPresenting, (presenting) => {
146
- if (presenting) {
138
+ $effect.pre(() => {
139
+ if (isPresenting.current) {
147
140
  originalRenderMode = renderMode.current
148
141
  renderMode.set('always')
149
142
  } else {
@@ -151,38 +144,46 @@ This should be placed within a Threlte `<Canvas />`.
151
144
  }
152
145
  })
153
146
 
154
- onMount(() => {
155
- $xrStore = xr
156
- xr.enabled = true
157
- xr.addEventListener('sessionstart', handleSessionStart)
158
- xr.addEventListener('sessionend', handleSessionEnd)
147
+ $effect.pre(() => {
148
+ const currentSession = session.current
149
+
150
+ xr.current = renderer.xr
151
+ renderer.xr.enabled = true
152
+ renderer.xr.addEventListener('sessionstart', handleSessionStart)
153
+ renderer.xr.addEventListener('sessionend', handleSessionEnd)
159
154
 
160
155
  return () => {
161
- $xrStore = undefined
162
- xr.enabled = false
163
- xr.removeEventListener('sessionstart', handleSessionStart)
164
- xr.removeEventListener('sessionend', handleSessionEnd)
156
+ xr.current = undefined
157
+ renderer.xr.enabled = false
158
+ renderer.xr.removeEventListener('sessionstart', handleSessionStart)
159
+ renderer.xr.removeEventListener('sessionend', handleSessionEnd)
165
160
 
166
161
  // if unmounted while presenting (e.g. due to sveltekit navigation), end the session
167
- session.current?.end()
162
+ currentSession?.end()
168
163
  }
169
164
  })
170
165
 
171
166
  $effect.pre(() => {
172
- updateTargetFrameRate(frameRate)
167
+ if (frameRate === undefined) return
168
+
169
+ try {
170
+ session.current?.updateTargetFrameRate(frameRate)
171
+ } catch {
172
+ // Do nothing
173
+ }
173
174
  })
174
175
 
175
176
  $effect.pre(() => {
176
- xr.setFoveation(foveation)
177
+ renderer.xr.setFoveation(foveation)
177
178
  })
178
179
 
179
180
  $effect.pre(() => {
180
- xr.setReferenceSpaceType(referenceSpace)
181
- $referenceSpaceType = referenceSpace
181
+ renderer.xr.setReferenceSpaceType(referenceSpace)
182
+ referenceSpaceType.current = referenceSpace
182
183
  })
183
184
  </script>
184
185
 
185
- {#if $isPresenting}
186
+ {#if isPresenting.current}
186
187
  {@render children?.()}
187
188
  {:else}
188
189
  {@render fallback?.()}
@@ -1,23 +1,6 @@
1
- import { type Snippet } from 'svelte';
1
+ import type { Snippet } from 'svelte';
2
2
  import type { XRSessionEvent } from '../types';
3
- /**
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
- * onsessionstart={(event: XREvent<XRManagerEvent>) => {}}
14
- * onsessionend={(event: XREvent<XRManagerEvent>) => {}}
15
- * onvisibilitychange={(event: XREvent<XRSessionEvent>) => {}}
16
- * oninputsourceschange={(event: XREvent<XRSessionEvent>) => {}}
17
- * />
18
- * ```
19
- */
20
- declare const Xr: import("svelte").Component<{
3
+ interface Props {
21
4
  /**
22
5
  * Enables foveated rendering. Default is `1`, the three.js default.
23
6
  *
@@ -40,12 +23,31 @@ declare const Xr: import("svelte").Component<{
40
23
  fallback?: Snippet;
41
24
  children?: Snippet;
42
25
  /** Called as an XRSession is requested */
43
- onsessionstart?: (event: XRSessionEvent<"sessionstart">) => void;
26
+ onsessionstart?: (event: XRSessionEvent<'sessionstart'>) => void;
44
27
  /** Called after an XRSession is terminated */
45
- onsessionend?: (event: XRSessionEvent<"sessionend">) => void;
28
+ onsessionend?: (event: XRSessionEvent<'sessionend'>) => void;
46
29
  /** Called when an XRSession is hidden or unfocused. */
47
30
  onvisibilitychange?: (event: globalThis.XRSessionEvent) => void;
48
31
  /** Called when available inputsources change */
49
32
  oninputsourceschange?: (event: globalThis.XRSessionEvent) => void;
50
- }, {}, "">;
33
+ }
34
+ /**
35
+ * `<XR />` is a WebXR manager that configures your scene for XR rendering and interaction.
36
+ *
37
+ * This should be placed within a Threlte `<Canvas />`.
38
+ *
39
+ * ```svelte
40
+ * <XR
41
+ * foveation={1}
42
+ * frameRate={90}
43
+ * referenceSpace='local-floor'
44
+ * onsessionstart={(event: XREvent<XRManagerEvent>) => {}}
45
+ * onsessionend={(event: XREvent<XRManagerEvent>) => {}}
46
+ * onvisibilitychange={(event: XREvent<XRSessionEvent>) => {}}
47
+ * oninputsourceschange={(event: XREvent<XRSessionEvent>) => {}}
48
+ * />
49
+ * ```
50
+ */
51
+ declare const Xr: import("svelte").Component<Props, {}, "">;
52
+ type Xr = ReturnType<typeof Xr>;
51
53
  export default Xr;
@@ -21,7 +21,7 @@ display info about your WebXR session. This is aliased by `ARButton` and
21
21
  import type { HTMLButtonAttributes } from 'svelte/elements'
22
22
  import { getXRSupportState } from '../lib/getXRSupportState'
23
23
  import { toggleXRSession } from '../lib/toggleXRSession'
24
- import { session, xr } from '../internal/stores'
24
+ import { isPresenting, xr } from '../internal/state.svelte'
25
25
  import type { Snippet } from 'svelte'
26
26
 
27
27
  type Props = HTMLButtonAttributes & {
@@ -57,7 +57,7 @@ display info about your WebXR session. This is aliased by `ARButton` and
57
57
  type SupportState = 'unsupported' | 'insecure' | 'blocked' | 'supported'
58
58
 
59
59
  const handleButtonClick = async (nativeEvent: MouseEvent, state: SupportState) => {
60
- if (!$xr) {
60
+ if (!xr.current) {
61
61
  throw new Error(
62
62
  'The <XR> component was not created. This is required to start an XR session.'
63
63
  )
@@ -119,7 +119,7 @@ display info about your WebXR session. This is aliased by `ARButton` and
119
119
  {:else if state === 'blocked'}
120
120
  {modeText} blocked
121
121
  {:else if state === 'supported'}
122
- {$session ? 'Exit' : 'Enter'} {modeText}
122
+ {isPresenting.current ? 'Exit' : 'Enter'} {modeText}
123
123
  {/if}
124
124
  </button>
125
125
  {/await}
@@ -1,24 +1,7 @@
1
1
  import type { HTMLButtonAttributes } from 'svelte/elements';
2
2
  import type { Snippet } from 'svelte';
3
- /**
4
- * `<XRButton />` is an HTML `<button />` that can be used to init and
5
- * display info about your WebXR session. This is aliased by `ARButton` and
6
- * `VRButton` with sensible session defaults.
7
- *
8
- * ```svelte
9
- * <XRButton
10
- * mode={'immersive-ar' | 'immersive-vr' | 'inline'}
11
- * sessionInit={{
12
- * optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers']
13
- * }}
14
- * force={'enter' | 'exit' | undefined}
15
- * styled={'true' | 'false'}
16
- * onerror={(event) => {}}
17
- * onclick={(event) => {}}
18
- * />
19
- * ```
20
- */
21
- declare const XrButton: import("svelte").Component<HTMLButtonAttributes & {
3
+ type SupportState = 'unsupported' | 'insecure' | 'blocked' | 'supported';
4
+ type Props = HTMLButtonAttributes & {
22
5
  /** The type of `XRSession` to create */
23
6
  mode: XRSessionMode;
24
7
  /**
@@ -31,16 +14,36 @@ declare const XrButton: import("svelte").Component<HTMLButtonAttributes & {
31
14
  } | undefined;
32
15
  };
33
16
  /** Whether this button should only enter / exit an `XRSession`. Default is to toggle both ways */
34
- force?: "enter" | "exit";
17
+ force?: 'enter' | 'exit';
35
18
  /** Whether to apply automatic styling to the button. Set false to apply custom styles. Default is true. */
36
19
  styled?: boolean;
37
20
  children?: Snippet<[{
38
- state: "unsupported" | "insecure" | "blocked" | "supported";
21
+ state: SupportState;
39
22
  }]>;
40
23
  onclick?: (event: {
41
- state: "unsupported" | "insecure" | "blocked" | "supported";
24
+ state: SupportState;
42
25
  nativeEvent: MouseEvent;
43
26
  }) => void;
44
27
  onerror?: (error: Error) => void;
45
- }, {}, "">;
28
+ };
29
+ /**
30
+ * `<XRButton />` is an HTML `<button />` that can be used to init and
31
+ * display info about your WebXR session. This is aliased by `ARButton` and
32
+ * `VRButton` with sensible session defaults.
33
+ *
34
+ * ```svelte
35
+ * <XRButton
36
+ * mode={'immersive-ar' | 'immersive-vr' | 'inline'}
37
+ * sessionInit={{
38
+ * optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers']
39
+ * }}
40
+ * force={'enter' | 'exit' | undefined}
41
+ * styled={'true' | 'false'}
42
+ * onerror={(event) => {}}
43
+ * onclick={(event) => {}}
44
+ * />
45
+ * ```
46
+ */
47
+ declare const XrButton: import("svelte").Component<Props, {}, "">;
48
+ type XrButton = ReturnType<typeof XrButton>;
46
49
  export default XrButton;
@@ -1,7 +1,9 @@
1
1
  import { type ColorRepresentation } from 'three';
2
- declare const Cursor: import("svelte").Component<{
2
+ interface Props {
3
3
  color?: ColorRepresentation;
4
4
  size?: number;
5
5
  thickness?: number;
6
- }, {}, "">;
6
+ }
7
+ declare const Cursor: import("svelte").Component<Props, {}, "">;
8
+ type Cursor = ReturnType<typeof Cursor>;
7
9
  export default Cursor;