Skip to content

Instantly share code, notes, and snippets.

@imp-dance
Last active September 15, 2020 10:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imp-dance/cf49f52fe0ba998821c4f07885ee8942 to your computer and use it in GitHub Desktop.
Save imp-dance/cf49f52fe0ba998821c4f07885ee8942 to your computer and use it in GitHub Desktop.
import React, { useState } from "react";
const getTotalOffset = (el: HTMLElement) => {
let a: any = el,
x = 0,
y = 0;
while (a) {
x += a.offsetLeft;
y += a.offsetTop;
a = a.offsetParent;
}
return { offsetX: x, offsetY: y };
};
function useMouseMove(
reference: React.RefObject<HTMLElement>
): [(e: React.MouseEvent) => void, React.CSSProperties] {
const [mousePointer, setMousePointer] = useState({ x: 0, y: 0 });
const mouseMove = (event: React.MouseEvent) => {
if (reference?.current) {
const { pageX, pageY } = event;
const { offsetX, offsetY } = getTotalOffset(reference.current);
const x = pageX - offsetX;
const y = pageY - offsetY;
setMousePointer({
x,
y,
});
}
};
const styles = {
"--x": mousePointer.x,
"--y": mousePointer.y,
} as React.CSSProperties;
return [mouseMove, styles];
}
export default useMouseMove;
@imp-dance
Copy link
Author

imp-dance commented Sep 15, 2020

What is this?

This is a hook that is used for tracking mouse movements relative to an element - returning coordinates as CSS variables in a react css style object.

Example of use

Component.tsx:

import React, { useRef } from "react";
import useMouseMove from "./useMouseMove";

const Component = () => {
 const buttonRef = React.useRef(null);
 const [onMouseMove, styles] = useMouseMove(buttonRef);

 return ( 
    <button
      ref={buttonRef}
      onMouseMove={onMouseMove} 
      style={styles}
     >
      Hover me
   </button>
  )
}

styles.css:

 button { 
   position: relative; 
   padding: 7px 12px;
   border:1px solid darkred;
   background: thistle;
 }
 button:after {
   content: "";
   position: absolute;
   background: radial-gradient(rgb(255, 255, 255), rgba(255, 255, 255, 0) 70%); /* White glow */
   width:2em; height: 2em;
   border-radius: 50%;

   top: calc(var(--y) * 1px); /* Use coordinates to do fancy styles */
   left: calc(var(--x) * 1px);

   transform: translate(-50%, -50%); /* Center circle around cursor */
 
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment