Files
shanghai-residences/src/hooks/usePageScale.ts
T
2025-12-29 19:19:10 +08:00

95 lines
2.3 KiB
TypeScript

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,
};
}