index.jsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
  2. export function useResizeObserver(...refs) {
  3. const [dimensions, setDimensions] = useState(
  4. new Array(refs.length).fill({ width: 0, height: 0, x: -Infinity, y: -Infinity })
  5. );
  6. const resizeObserver = useMemo(
  7. () =>
  8. new ResizeObserver((entries) => {
  9. window.requestAnimationFrame(() => {
  10. setDimensions(entries.map((entry) => entry.contentRect));
  11. });
  12. }),
  13. []
  14. );
  15. useEffect(() => {
  16. refs.forEach((ref) => {
  17. resizeObserver.observe(ref.current);
  18. });
  19. return () => {
  20. refs.forEach((ref) => {
  21. resizeObserver.unobserve(ref.current);
  22. });
  23. };
  24. }, [refs, resizeObserver]);
  25. return dimensions;
  26. }
  27. export function useIntersectionObserver() {
  28. const [entry, setEntry] = useState({});
  29. const [node, setNode] = useState(null);
  30. const observer = useRef(null);
  31. useEffect(() => {
  32. if (observer.current) {
  33. observer.current.disconnect();
  34. }
  35. observer.current = new IntersectionObserver((entries) => {
  36. window.requestAnimationFrame(() => {
  37. setEntry(entries[0]);
  38. });
  39. });
  40. if (node) {
  41. observer.current.observe(node);
  42. }
  43. return () => {
  44. observer.current.disconnect();
  45. };
  46. }, [node]);
  47. return [entry, setNode];
  48. }