feat: 🎸 add useMotion hook

This commit is contained in:
streamich 2018-10-27 13:18:07 +02:00
parent eb40aca351
commit 91eb4ea465
5 changed files with 138 additions and 1 deletions

View File

@ -2,7 +2,7 @@
<h1>
<br/>
<br/>
🎣
👍
<br />
react-use
<br />
@ -23,6 +23,12 @@
</div>
## Install
<pre>
npm i <a href="https://www.npmjs.com/package/react-use">react-use</a>
</pre>
## Reference
@ -41,6 +47,7 @@
- [`useLocation`](./docs/useLocation.md) &mdash; tracks page navigation bar location state.
- [`useMedia`](./docs/useMedia.md) &mdash; tracks state of a CSS media query.
- [`useMediaDevices`](./docs/useMediaDevices.md) &mdash; tracks state of connected hardware devices.
- [`useMotion`](./docs/useMotion.md) &mdash; tracks state of device's motion sensor.
- [`useNetwork`](./docs/useNetwork.md) &mdash; tracks state of user's internet connection.
- [`useOrientation`](./docs/useOrientation.md) &mdash; tracks state of device's screen orientation.
- [`useSize`](./docs/useSize.md) &mdash; tracks some HTML element's dimensions.
@ -53,6 +60,12 @@
<br/>
## Usage
- You need to have React `16.7.0-alpha.0` or later installed to use Hooks API.
- You can import each hook individually `import useToggle from 'react-use/lib/useToggle'`.
## License
[Unlicense](./LICENSE) &mdash; public domain.

20
docs/useMotion.md Normal file
View File

@ -0,0 +1,20 @@
# `useMotion`
React sensor hook that uses device's acceleration sensor to track its motions.
## Usage
```jsx
import {useMotion} from 'react-use';
const Demo = () => {
const state = useMotion();
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
);
};
```

View File

@ -0,0 +1,18 @@
import * as React from 'react';
import {storiesOf} from '@storybook/react';
import {useMotion} from '..';
const Demo = () => {
const state = useMotion();
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
);
};
storiesOf('useMotion', module)
.add('Example', () =>
<Demo/>
)

View File

@ -8,6 +8,7 @@ import useLocation from './useLocation';
import useMap from './useMap';
import useMedia from './useMedia';
import useMediaDevices from './useMediaDevices';
import useMotion from './useMotion';
import useNetwork from './useNetwork';
import useOrientation from './useOrientation';
import useSize from './useSize';
@ -26,6 +27,7 @@ export {
useMap,
useMedia,
useMediaDevices,
useMotion,
useNetwork,
useOrientation,
useSize,

84
src/useMotion.ts Normal file
View File

@ -0,0 +1,84 @@
import {useState, useEffect} from './react';
import {on, off} from './util';
export interface MotionSensorState {
acceleration: {
x: number | null,
y: number | null,
z: number | null,
},
accelerationIncludingGravity: {
x: number | null,
y: number | null,
z: number | null,
},
rotationRate: {
alpha: number | null,
beta: number | null,
gamma: number | null,
},
interval: number | null,
}
const defaultState: MotionSensorState = {
acceleration: {
x: null,
y: null,
z: null,
},
accelerationIncludingGravity: {
x: null,
y: null,
z: null,
},
rotationRate: {
alpha: null,
beta: null,
gamma: null,
},
interval: 16,
};
const useMotion = (initialState: MotionSensorState = defaultState) => {
const [state, setState] = useState(initialState);
useEffect(() => {
const handler = (event) => {
const {
acceleration,
accelerationIncludingGravity,
rotationRate,
interval
} = event;
setState({
acceleration: {
x: acceleration.x,
y: acceleration.y,
z: acceleration.z
},
accelerationIncludingGravity: {
x: accelerationIncludingGravity.x,
y: accelerationIncludingGravity.y,
z: accelerationIncludingGravity.z
},
rotationRate: {
alpha: rotationRate.alpha,
beta: rotationRate.beta,
gamma: rotationRate.gamma,
},
interval
});
};
on(window, 'devicemotion', handler);
return () => {
off(window, 'devicemotion', handler);
};
}, [0]);
return state;
};
export default useMotion;