import { useEffect, useState, useMemo } from "react"; /** * 等比例缩放Hook * 基于1920*1080设计稿进行等比例缩放 */ export function usePageScale() { // 设计稿尺寸 const DESIGN_WIDTH = 1920; const DESIGN_HEIGHT = 1080; // 当前窗口尺寸 const [windowWidth, setWindowWidth] = useState(window.innerWidth); const [windowHeight, setWindowHeight] = useState(window.innerHeight); // 是否移动端竖屏(需要旋转横屏展示) const isMobilePortrait = useMemo(() => { const ua = window.navigator.userAgent.toLowerCase(); const isMobile = /iphone|ipad|ipod|android|mobile/.test(ua); return isMobile && windowHeight > windowWidth; }, [windowHeight, windowWidth]); // 缩放比例 const scale = useMemo(() => { const baseWidth = DESIGN_WIDTH; const baseHeight = DESIGN_HEIGHT; const scaleX = windowWidth / baseWidth; const scaleY = windowHeight / baseHeight; return Math.min(scaleX, scaleY); }, [windowWidth, windowHeight]); // 缩放后的实际尺寸 const scaledWidth = useMemo(() => DESIGN_WIDTH * scale, [scale]); const scaledHeight = useMemo(() => DESIGN_HEIGHT * scale, [scale]); // 居中偏移量 const offsetX = useMemo( () => (windowWidth - scaledWidth) / 2, [windowWidth, scaledWidth] ); const offsetY = useMemo( () => (windowHeight - scaledHeight) / 2, [windowHeight, scaledHeight] ); // 缩放样式对象 const scaleStyle = useMemo( () => ({ position: "absolute" as const, width: `${DESIGN_WIDTH}px`, height: `${DESIGN_HEIGHT}px`, left: `${offsetX}px`, top: `${offsetY}px`, transform: `scale(${scale})`, transformOrigin: "top left", }), [scale, offsetX, offsetY] ); // 更新窗口尺寸 const updateWindowSize = () => { setWindowWidth(window.innerWidth); setWindowHeight(window.innerHeight); }; // 监听窗口大小变化 useEffect(() => { window.addEventListener("resize", updateWindowSize); updateWindowSize(); return () => { window.removeEventListener("resize", updateWindowSize); }; }, []); return { // 响应式数据 windowWidth, windowHeight, scale, scaledWidth, scaledHeight, offsetX, offsetY, // 样式对象 scaleStyle, isMobilePortrait, // 常量 DESIGN_WIDTH, DESIGN_HEIGHT, }; }