import { useEffect, useState } from "react"; interface CanvasScaleOptions { width: number; height: number; maxScale: number; } function getViewportSize() { if (typeof window === "undefined") { return null; } return { width: window.visualViewport?.width ?? window.innerWidth, height: window.visualViewport?.height ?? window.innerHeight, }; } function calculateScale({ width, height, maxScale, }: CanvasScaleOptions): number { if (typeof window === "undefined") return maxScale; const viewport = getViewportSize(); if (!viewport) return maxScale; return Math.min(viewport.width / width, viewport.height / height, maxScale); } export function useCanvasScale({ width, height, maxScale, }: CanvasScaleOptions): number { const [scale, setScale] = useState(() => calculateScale({ width, height, maxScale }), ); useEffect(() => { const updateScale = () => setScale(calculateScale({ width, height, maxScale })); updateScale(); window.addEventListener("resize", updateScale); window.addEventListener("orientationchange", updateScale); window.visualViewport?.addEventListener("resize", updateScale); window.visualViewport?.addEventListener("scroll", updateScale); return () => { window.removeEventListener("resize", updateScale); window.removeEventListener("orientationchange", updateScale); window.visualViewport?.removeEventListener("resize", updateScale); window.visualViewport?.removeEventListener("scroll", updateScale); }; }, [height, maxScale, width]); return scale; }