Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
1.6 kB · 80 lines
TypeScript
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081import { useState, useCallback, useLayoutEffect, startTransition } from "react";
export interface Dimensions { width: number; height: number; top: number; left: number; x: number; y: number; right: number; bottom: number;}function getDimensionObject<T extends HTMLElement | SVGElement>(node: T): Dimensions { const rect = node.getBoundingClientRect();
if (rect.toJSON) { return rect.toJSON(); } return { width: rect.width, height: rect.height, top: rect.top || rect.y, left: rect.left || rect.x, x: rect.x || rect.left, y: rect.y || rect.top, right: rect.right, bottom: rect.bottom, };}
function useMeasure<Element extends HTMLElement | SVGElement = HTMLElement>(): [ (node: Element) => void, Dimensions, () => void, Element | undefined,] { const [dimensions, setDimensions] = useState<Dimensions>({ width: 0, height: 0, top: 0, left: 0, x: 0, y: 0, right: 0, bottom: 0, }); const [node, setNode] = useState<Element>();
const ref = useCallback((node: Element) => { setNode(node); }, []);
const measure = useCallback(() => { if (node) { window.requestAnimationFrame(() => { startTransition(() => { setDimensions(getDimensionObject<Element>(node)); }); }); } }, [node]);
useLayoutEffect(() => { if (node) { measure();
window.addEventListener("resize", measure); window.addEventListener("scroll", measure);
return () => { window.removeEventListener("resize", measure); window.removeEventListener("scroll", measure); }; } }, [node, measure]);
return [ref, dimensions, measure, node];}
export default useMeasure;