File size: 1,603 Bytes
8608e55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
 * useZoom.js
 *
 * This custom React hook manages zoom functionality for UI elements such as images.
 * - Allows zooming in, zooming out, and setting exact zoom levels.
 * - Supports zoom via buttons, keyboard shortcuts (Ctrl/Cmd + +, -, 0), and mouse wheel.
 * - Enforces minimum and maximum zoom limits and configurable zoom step.
 */


import { useState, useEffect } from "react";

export default function useZoom({ min = 1, max = 3, step = 0.25 }) {
  const [zoom, setZoom] = useState(1);

  const clamp = (v) => Math.min(Math.max(v, min), max);

  const zoomIn = () => setZoom((z) => clamp(Number((z + step).toFixed(2))));
  const zoomOut = () => setZoom((z) => clamp(Number((z - step).toFixed(2))));
  const setZoomExact = (v) => setZoom(clamp(Number(v)));

  useEffect(() => {
    const handleKeyDown = (e) => {
      if (e.ctrlKey || e.metaKey) {
        if (e.key === "+" || e.key === "=") {
          e.preventDefault();
          zoomIn();
        } else if (e.key === "-") {
          e.preventDefault();
          zoomOut();
        } else if (e.key === "0") {
          e.preventDefault();
          setZoomExact(1);
        }
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, []);

  const handleWheel = (e) => {
    if (e.ctrlKey || e.metaKey) {
      e.preventDefault();
      const delta = -e.deltaY;
      const factor = delta > 0 ? 1 + step : 1 - step;
      setZoom((z) => clamp(Math.round(z * factor * 100) / 100));
    }
  };

  return { zoom, zoomIn, zoomOut, handleWheel };
}