UNPKG

@react-three/xr

Version:

VR/AR for react-three-fiber

115 lines (114 loc) 3.69 kB
import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'; import { useXR } from './xr.js'; export function useHover(ref, onChange) { let setHover; let hover; if (onChange == null) { // eslint-disable-next-line react-hooks/rules-of-hooks const [_hover, _setHover] = useState(false); setHover = _setHover; hover = _hover; } else { setHover = onChange; } useEffect(() => { const { current } = ref; if (current == null) { return; } const set = new Set(); const enter = (e) => { if (set.size === 0) { setHover(true, e); } set.add(e.pointerId); }; const leave = (e) => { set.delete(e.pointerId); if (set.size === 0) { setHover(false, e); } }; current.addEventListener('pointerenter', enter); current.addEventListener('pointerleave', leave); return () => { current.removeEventListener('pointerenter', enter); current.removeEventListener('pointerleave', leave); }; }, [ref, setHover]); return hover; } /** * Gets the visibility state of the XR session. * * @returns The visibility state of the XR session. */ export function useXRSessionVisibilityState() { return useXR((xr) => xr.visibilityState); } /** * Initilizes the room capture process. * * @returns A function to initiate room capture, or undefined if unavailable. */ export function useInitRoomCapture() { return useXR((xr) => xr.session?.initiateRoomCapture?.bind(xr.session)); } /** * Checks whether a specific XRSessionMode is supported or not * * @param {XRSessionMode} mode - The `XRSessionMode` to check against. * @param {(error: any) => void} [onError] - Callback executed when an error occurs. */ export function useXRSessionModeSupported(mode, onError) { const onErrorRef = useRef(onError); onErrorRef.current = onError; const [subscribe, getSnapshot] = useMemo(() => { let sessionSupported = undefined; return [ (onChange) => { let canceled = false; if (typeof navigator === 'undefined' || navigator.xr == null) { sessionSupported = false; return () => { }; } navigator.xr .isSessionSupported(mode) .then((isSupported) => { sessionSupported = isSupported; if (canceled) { return; } onChange(); }) .catch((e) => { if (canceled) { return; } onErrorRef.current?.(e); }); return () => (canceled = true); }, () => sessionSupported, ]; }, [mode]); return useSyncExternalStore(subscribe, getSnapshot); } /** * @deprecated use `useXRSessionModeSupported` instead */ export const useSessionModeSupported = useXRSessionModeSupported; /** * Checks if a specific XR session feature is enabled. * * @param {string} feature - The XR session feature to check against. * @returns {boolean} Whether the feature is enabled. */ export function useXRSessionFeatureEnabled(feature) { return useXR(({ session }) => session?.enabledFeatures?.includes(feature) ?? false); } /** * @deprecated use `useXRSessionFeatureEnabled` instead */ export const useSessionFeatureEnabled = useXRSessionFeatureEnabled;