mirror of
https://github.com/streamich/react-use.git
synced 2026-01-25 14:17:16 +00:00
useMouse hook
This commit is contained in:
parent
74cbb1eaca
commit
e8b43ea95c
@ -42,6 +42,7 @@
|
||||
- [`useMedia`](./docs/useMedia.md) — tracks state of a CSS media query. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usemedia--demo)
|
||||
- [`useMediaDevices`](./docs/useMediaDevices.md) — tracks state of connected hardware devices.
|
||||
- [`useMotion`](./docs/useMotion.md) — tracks state of device's motion sensor.
|
||||
- [`useMouse`](./docs/useMouse.md) — tracks state of mouse position. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usemouse--docs)
|
||||
- [`useNetwork`](./docs/useNetwork.md) — tracks state of user's internet connection.
|
||||
- [`useOrientation`](./docs/useOrientation.md) — tracks state of device's screen orientation.
|
||||
- [`useScroll`](./docs/useScroll.md) — tracks some HTML element's scroll position. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/sensors-usescroll--docs)
|
||||
|
||||
23
docs/useMouse.md
Normal file
23
docs/useMouse.md
Normal file
@ -0,0 +1,23 @@
|
||||
# `useMouse`
|
||||
|
||||
React sensor hook that re-renders on mouse position changes.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
import {useMouse} from 'react-use';
|
||||
|
||||
const Demo = () => {
|
||||
const ref = React.useRef(null);
|
||||
const {docX, docY, posX, posY, elX, elY, elW, elH} = useScroll(ref);
|
||||
|
||||
return (
|
||||
<div ref={element}>
|
||||
<div>Mouse position in document - x:{docX} y:{docY}</div>
|
||||
<div>Mouse position in element - x:{posX} y:{posY}</div>
|
||||
<div>Element position - x:{elX} y:{elY}</div>
|
||||
<div>Element dimensions - {elW}x{elH}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
32
src/__stories__/useMouse.story.tsx
Normal file
32
src/__stories__/useMouse.story.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import {storiesOf} from '@storybook/react';
|
||||
import {useMouse} from '..';
|
||||
import ShowDocs from '../util/ShowDocs';
|
||||
|
||||
const Demo = () => {
|
||||
const ref = React.useRef(null);
|
||||
const state = useMouse(ref);
|
||||
|
||||
return (
|
||||
<>
|
||||
<pre>
|
||||
{JSON.stringify(state, null, 2)}
|
||||
</pre>
|
||||
<div
|
||||
ref={ref}
|
||||
style={{
|
||||
width: '400px',
|
||||
height: '400px',
|
||||
backgroundColor: 'whitesmoke',
|
||||
}}>
|
||||
Move your mouse over me
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
storiesOf('Sensors|useMouse', module)
|
||||
.add('Docs', () => <ShowDocs md={require('../../docs/useMouse.md')} />)
|
||||
.add('Demo', () =>
|
||||
<Demo/>
|
||||
)
|
||||
@ -27,6 +27,7 @@ import useMedia from './useMedia';
|
||||
import useMediaDevices from './useMediaDevices';
|
||||
import useMotion from './useMotion';
|
||||
import useMount from './useMount';
|
||||
import useMouse from './useMouse';
|
||||
import useNetwork from './useNetwork';
|
||||
import useNumber from './useNumber';
|
||||
import useObservable from './useObservable';
|
||||
@ -84,6 +85,7 @@ export {
|
||||
useMediaDevices,
|
||||
useMotion,
|
||||
useMount,
|
||||
useMouse,
|
||||
useNetwork,
|
||||
useNumber,
|
||||
useObservable,
|
||||
|
||||
63
src/useMouse.ts
Normal file
63
src/useMouse.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import {useState, useEffect, useRef, RefObject} from 'react';
|
||||
|
||||
export interface State {
|
||||
docX: number;
|
||||
docY: number;
|
||||
posX: number;
|
||||
posY: number;
|
||||
elX: number;
|
||||
elY: number;
|
||||
elH: number;
|
||||
elW: number;
|
||||
}
|
||||
|
||||
const useMouse = (ref: RefObject<HTMLElement>): State => {
|
||||
const frame = useRef(0);
|
||||
const [state, setState] = useState<State>({
|
||||
docX: 0,
|
||||
docY: 0,
|
||||
posX: 0,
|
||||
posY: 0,
|
||||
elX: 0,
|
||||
elY: 0,
|
||||
elH: 0,
|
||||
elW: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (event: MouseEvent) => {
|
||||
frame.current = requestAnimationFrame(() => {
|
||||
if (ref && ref.current) {
|
||||
const {left, top} = ref.current.getBoundingClientRect()
|
||||
const posX = left + window.scrollX;
|
||||
const posY = top + window.scrollY;
|
||||
|
||||
setState({
|
||||
docX: event.pageX,
|
||||
docY: event.pageY,
|
||||
posX,
|
||||
posY,
|
||||
elX: event.pageX - posX,
|
||||
elY: event.pageY - posY,
|
||||
elH: ref.current.offsetHeight,
|
||||
elW: ref.current.offsetWidth,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', handler);
|
||||
|
||||
return () => {
|
||||
if (frame.current) {
|
||||
cancelAnimationFrame(frame.current);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', handler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
export default useMouse
|
||||
Loading…
x
Reference in New Issue
Block a user