Skip to content

Instantly share code, notes, and snippets.

@HaNdTriX
Created September 14, 2022 13:00
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 HaNdTriX/8ba8114ce206d6c61608a92415ed931d to your computer and use it in GitHub Desktop.
Save HaNdTriX/8ba8114ce206d6c61608a92415ed931d to your computer and use it in GitHub Desktop.
import { useEffect, useRef } from "react";
type ElementPickerProps = {
onPick: (event: MouseEvent, element: HTMLElement) => void;
};
export default function ElementPicker({ onPick }: ElementPickerProps) {
const lastSelectedRef = useRef<HTMLElement>();
const topRef = useRef<HTMLDivElement>(null);
const rightRef = useRef<HTMLDivElement>(null);
const bottomRef = useRef<HTMLDivElement>(null);
const leftRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleMouseMove = (event: MouseEvent) => {
const targetElement = document.elementFromPoint(
event.clientX,
event.clientY
);
if (targetElement === null) return;
if (topRef.current === null) return;
if (rightRef.current === null) return;
if (bottomRef.current === null) return;
if (leftRef.current === null) return;
const targetRect = targetElement.getBoundingClientRect();
if (!targetRect.width && !targetRect.height) return;
lastSelectedRef.current = targetElement as HTMLElement;
// Position topRef
topRef.current.style.height = `${targetRect.top}px`;
topRef.current.style.width = `${targetRect.width}px`;
topRef.current.style.left = `${targetRect.left}px`;
// Position rightRef
rightRef.current.style.width = `${
window.innerWidth - targetRect.left + targetRect.width
}px`;
// rightRef.current.style.height = `${targetRect.height}px`;
// rightRef.current.style.top = `${targetRect.top}px`;
rightRef.current.style.left = `${targetRect.left + targetRect.width}px`;
// Position bottomRef
bottomRef.current.style.height = `${
window.innerHeight - (targetRect.top + targetRect.height)
}px`;
bottomRef.current.style.width = `${targetRect.width}px`;
bottomRef.current.style.left = `${targetRect.left}px`;
// Position leftRef
leftRef.current.style.width = `${targetRect.left}px`;
};
window.addEventListener("mousemove", handleMouseMove);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, []);
useEffect(() => {
const handleClick = async (event: MouseEvent) => {
const target = lastSelectedRef.current;
if (target instanceof HTMLElement) {
onPick(event, target);
}
};
window.addEventListener("click", handleClick);
return () => {
window.removeEventListener("click", handleClick);
};
}, []);
return (
<>
<div
ref={topRef}
style={{
position: "fixed",
boxSizing: "border-box",
backgroundColor: "green",
top: 0,
right: 0,
height: 0,
width: 0,
pointerEvents: "none",
opacity: 0.3,
zIndex: 999999,
transition: "all 100ms",
}}
/>
<div
ref={rightRef}
style={{
position: "fixed",
boxSizing: "border-box",
backgroundColor: "green",
top: 0,
bottom: 0,
right: 0,
width: 0,
pointerEvents: "none",
opacity: 0.3,
zIndex: 999999,
transition: "all 100ms",
}}
/>
<div
ref={bottomRef}
style={{
position: "fixed",
boxSizing: "border-box",
backgroundColor: "green",
bottom: 0,
left: 0,
right: 0,
height: 0,
width: "100%",
pointerEvents: "none",
opacity: 0.3,
zIndex: 999999,
transition: "all 100ms",
}}
/>
<div
ref={leftRef}
style={{
position: "fixed",
boxSizing: "border-box",
backgroundColor: "green",
top: 0,
bottom: 0,
left: 0,
width: 0,
pointerEvents: "none",
opacity: 0.3,
zIndex: 999999,
transition: "all 100ms",
}}
/>
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment