From 28b5bc97d48ec1c4fc4ffbe821693b33dbcadffe Mon Sep 17 00:00:00 2001 From: Ward Oosterlijnck Date: Tue, 26 Mar 2019 13:44:23 +1100 Subject: [PATCH] useMouse whenHovered option --- src/__stories__/useMouse.story.tsx | 19 +++++++++++--- src/useMouse.ts | 40 ++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/__stories__/useMouse.story.tsx b/src/__stories__/useMouse.story.tsx index b699fea8..00f78ca3 100644 --- a/src/__stories__/useMouse.story.tsx +++ b/src/__stories__/useMouse.story.tsx @@ -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 ( <>
         {JSON.stringify(state, null, 2)}
       
+
- Move your mouse over me + + 🐭 +
); diff --git a/src/useMouse.ts b/src/useMouse.ts index c8b79efb..89b575b5 100644 --- a/src/useMouse.ts +++ b/src/useMouse.ts @@ -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): State => { +const useMouse = (ref: RefObject, whenHovered: boolean = false): State => { const frame = useRef(0); + const [active, setActive] = useToggle(false); const [state, setState] = useState({ docX: 0, docY: 0, @@ -25,11 +27,29 @@ const useMouse = (ref: RefObject): 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): 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; }