mirror of
https://github.com/streamich/react-use.git
synced 2026-01-18 14:06:52 +00:00
useMouse whenHovered option
This commit is contained in:
parent
f9c6dd9d94
commit
28b5bc97d4
@ -1,25 +1,38 @@
|
||||
import * as React from 'react';
|
||||
import {storiesOf} from '@storybook/react';
|
||||
import {useMouse} from '..';
|
||||
import {useMouse, useToggle} from '..';
|
||||
import ShowDocs from '../util/ShowDocs';
|
||||
|
||||
const Demo = () => {
|
||||
const [whenHovered, toggleWhenHovered] = useToggle(false);
|
||||
const ref = React.useRef(null);
|
||||
const state = useMouse(ref);
|
||||
const state = useMouse(ref, whenHovered)
|
||||
|
||||
return (
|
||||
<>
|
||||
<pre>
|
||||
{JSON.stringify(state, null, 2)}
|
||||
</pre>
|
||||
<label>
|
||||
<input type="checkbox" checked={whenHovered} onChange={() => toggleWhenHovered()} />
|
||||
When hovered
|
||||
</label>
|
||||
<div
|
||||
ref={ref}
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: '400px',
|
||||
height: '400px',
|
||||
backgroundColor: 'whitesmoke',
|
||||
}}>
|
||||
Move your mouse over me
|
||||
<span style={{
|
||||
position: 'absolute',
|
||||
left: `${state.elX}px`,
|
||||
top: `${state.elY}px`,
|
||||
pointerEvents: 'none',
|
||||
transform: 'scale(4)'}}>
|
||||
🐭
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import {useState, useEffect, useRef, RefObject} from 'react';
|
||||
import useToggle from "./useToggle";
|
||||
|
||||
export interface State {
|
||||
docX: number;
|
||||
@ -11,8 +12,9 @@ export interface State {
|
||||
elW: number;
|
||||
}
|
||||
|
||||
const useMouse = (ref: RefObject<HTMLElement>): State => {
|
||||
const useMouse = (ref: RefObject<HTMLElement>, whenHovered: boolean = false): State => {
|
||||
const frame = useRef(0);
|
||||
const [active, setActive] = useToggle(false);
|
||||
const [state, setState] = useState<State>({
|
||||
docX: 0,
|
||||
docY: 0,
|
||||
@ -25,11 +27,29 @@ const useMouse = (ref: RefObject<HTMLElement>): State => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (event: MouseEvent) => {
|
||||
cancelAnimationFrame(frame.current)
|
||||
const enterHandler = () => setActive(true)
|
||||
const leaveHandler = () => setActive(false)
|
||||
|
||||
if (whenHovered && ref && ref.current) {
|
||||
ref.current.addEventListener("mouseenter", enterHandler, false);
|
||||
ref.current.addEventListener("mouseleave", leaveHandler, false);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (whenHovered && ref && ref.current) {
|
||||
ref.current.removeEventListener("mouseenter", enterHandler);
|
||||
ref.current.removeEventListener("mouseleave", leaveHandler);
|
||||
}
|
||||
};
|
||||
}, [whenHovered, ref]);
|
||||
|
||||
useEffect(() => {
|
||||
const moveHandler = (event: MouseEvent) => {
|
||||
cancelAnimationFrame(frame.current);
|
||||
|
||||
frame.current = requestAnimationFrame(() => {
|
||||
if (ref && ref.current) {
|
||||
const {left, top, width, height} = ref.current.getBoundingClientRect()
|
||||
const {left, top, width, height} = ref.current.getBoundingClientRect();
|
||||
const posX = left + window.scrollX;
|
||||
const posY = top + window.scrollY;
|
||||
|
||||
@ -47,13 +67,17 @@ const useMouse = (ref: RefObject<HTMLElement>): State => {
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', handler);
|
||||
if (active || !whenHovered) {
|
||||
document.addEventListener('mousemove', moveHandler);
|
||||
}
|
||||
|
||||
return () => {
|
||||
cancelAnimationFrame(frame.current);
|
||||
document.removeEventListener('mousemove', handler);
|
||||
if (active || !whenHovered) {
|
||||
cancelAnimationFrame(frame.current);
|
||||
document.removeEventListener('mousemove', moveHandler);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
}, [active, whenHovered, ref])
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user