@@ -2,64 +2,72 @@ import { useEffect, useRef, useState } from 'react';
2
2
3
3
import { throttle } from '@/utils/helpers' ;
4
4
5
- export interface DeviceMotionData {
5
+ export interface UseDeviceMotionReturn {
6
6
interval : DeviceMotionEvent [ 'interval' ] ;
7
- rotationRate : Exclude < DeviceMotionEvent [ 'rotationRate' ] , null > ;
8
- acceleration : Exclude < DeviceMotionEvent [ 'acceleration' ] , null > ;
9
- accelerationIncludingGravity : Exclude <
10
- DeviceMotionEvent [ 'accelerationIncludingGravity' ] ,
11
- null
12
- > ;
7
+ acceleration : DeviceMotionEventAcceleration
8
+ accelerationIncludingGravity : DeviceMotionEventAcceleration
9
+ rotationRate : DeviceMotionEventRotationRate
10
+ }
11
+
12
+ export interface UseDeviceMotionParams {
13
+ delay ?: number ;
14
+ callback ?: ( event : DeviceMotionEvent ) => void ;
15
+ enabled ?: boolean ;
13
16
}
14
17
15
18
/**
16
19
* @name useDeviceMotion
17
- * @description Hook that provides DeviceMotionEvent data
20
+ * @description Hook that work with device motion
18
21
* @category Utilities
19
22
*
20
- * @param {number } delay The data update delay
21
- * @param {Function } callback The event listener callback
22
- * @returns {DeviceMotionData } DeviceMotionEvent data
23
+ * @param {number } [delay=1000] The delay in milliseconds
24
+ * @param {(event: DeviceMotionEvent) => void } [callback] The callback function to be invoked
25
+ * @param {boolean } [enabled=true] Whether to enable the hook
26
+ * @returns {UseDeviceMotionReturn } The device motion data and interval
27
+ *
28
+ * @example
29
+ * const { interval, rotationRate, acceleration, accelerationIncludingGravity } = useDeviceMotion();
23
30
*/
24
- export const useDeviceMotion = (
25
- delay : number ,
26
- callback ?: ( event : DeviceMotionEvent ) => void
27
- ) => {
28
- const [ deviceMotionData , setDeviceMotionData ] = useState < DeviceMotionData > ( {
31
+ export const useDeviceMotion = ( params ?: UseDeviceMotionParams ) => {
32
+ const enabled = params ?. enabled ?? true ;
33
+ const delay = params ?. delay ?? 1000 ;
34
+ const [ deviceMotionData , setDeviceMotionData ] = useState < UseDeviceMotionReturn > ( {
29
35
interval : 0 ,
30
36
rotationRate : { alpha : null , beta : null , gamma : null } ,
31
37
acceleration : { x : null , y : null , z : null } ,
32
38
accelerationIncludingGravity : { x : null , y : null , z : null }
33
39
} ) ;
34
- const internalCallbackRef = useRef ( callback ) ;
35
- internalCallbackRef . current = callback ;
40
+ const internalCallbackRef = useRef ( params ?. callback ) ;
41
+ internalCallbackRef . current = params ?. callback ;
36
42
37
43
useEffect ( ( ) => {
44
+ if ( ! enabled ) return ;
45
+
38
46
const onDeviceMotion = throttle < [ DeviceMotionEvent ] > ( ( event ) => {
39
47
internalCallbackRef . current ?.( event ) ;
40
- setDeviceMotionData ( ( prevState ) => ( {
48
+ setDeviceMotionData ( {
41
49
interval : event . interval ,
42
50
rotationRate : {
43
- ...prevState . rotationRate ,
51
+ ...deviceMotionData . rotationRate ,
44
52
...event . rotationRate
45
53
} ,
46
54
acceleration : {
47
- ...prevState . acceleration ,
55
+ ...deviceMotionData . acceleration ,
48
56
...event . acceleration
49
57
} ,
50
58
accelerationIncludingGravity : {
51
- ...prevState . accelerationIncludingGravity ,
59
+ ...deviceMotionData . accelerationIncludingGravity ,
52
60
...event . accelerationIncludingGravity
53
61
}
54
- } ) ) ;
62
+ } ) ;
55
63
} , delay ) ;
56
64
57
65
window . addEventListener ( 'devicemotion' , onDeviceMotion ) ;
58
66
59
67
return ( ) => {
60
68
window . removeEventListener ( 'devicemotion' , onDeviceMotion ) ;
61
69
} ;
62
- } , [ delay ] ) ;
70
+ } , [ delay , enabled ] ) ;
63
71
64
72
return deviceMotionData ;
65
73
} ;
0 commit comments