Skip to content

Instantly share code, notes, and snippets.

@KristofferEriksson
Created February 13, 2024 15:10
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KristofferEriksson/12a9878b40d7d47fabf4a376104284c2 to your computer and use it in GitHub Desktop.
Save KristofferEriksson/12a9878b40d7d47fabf4a376104284c2 to your computer and use it in GitHub Desktop.
A React Typescript hook that utilizes the DeviceOrientation API to provide real-time orientation data of a device in 3D space
import { useCallback, useEffect, useState } from "react";
interface DeviceOrientationState {
alpha: number | null;
beta: number | null;
gamma: number | null;
absolute: boolean;
}
// Define an extended interface for DeviceOrientationEvent including requestPermission
interface DeviceOrientationEventExtended extends DeviceOrientationEvent {
requestPermission?: () => Promise<"granted" | "denied">;
}
function useDeviceOrientation() {
const [orientation, setOrientation] = useState<DeviceOrientationState>({
alpha: null,
beta: null,
gamma: null,
absolute: false,
});
// Check if the DeviceOrientationEvent is supported - this will be true in most browsers (even desktop)
const isSupported = typeof window.DeviceOrientationEvent !== "undefined";
// Determine if we need to request permission (for iOS 13+)
const [isPermissionGranted, setIsPermissionGranted] = useState(
typeof (DeviceOrientationEvent as unknown as DeviceOrientationEventExtended)
.requestPermission !== "function",
);
const handleOrientation = useCallback((event: DeviceOrientationEvent) => {
setOrientation({
alpha: event.alpha,
beta: event.beta,
gamma: event.gamma,
absolute: event.absolute,
});
}, []);
useEffect(() => {
if (isPermissionGranted) {
window.addEventListener("deviceorientation", handleOrientation);
return () => {
window.removeEventListener("deviceorientation", handleOrientation);
};
}
}, [isPermissionGranted, handleOrientation]);
const requestPermission = useCallback(async () => {
const deviceOrientationEvent =
DeviceOrientationEvent as unknown as DeviceOrientationEventExtended;
if (typeof deviceOrientationEvent.requestPermission === "function") {
try {
const permissionState =
await deviceOrientationEvent.requestPermission();
setIsPermissionGranted(permissionState === "granted");
} catch (error) {
console.error("Error requesting device orientation permission:", error);
}
}
}, []);
return { orientation, requestPermission, isPermissionGranted, isSupported };
}
export default useDeviceOrientation;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment