forked from 77media/video-flow
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
|
|
interface SafeAreaInsets {
|
|
top: number;
|
|
right: number;
|
|
bottom: number;
|
|
left: number;
|
|
}
|
|
|
|
export function useSafeArea() {
|
|
const [safeAreaInsets, setSafeAreaInsets] = useState<SafeAreaInsets>({
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
left: 0
|
|
});
|
|
|
|
const [viewportHeight, setViewportHeight] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const updateSafeArea = () => {
|
|
// 获取 CSS 环境变量
|
|
const computedStyle = getComputedStyle(document.documentElement);
|
|
|
|
const top = parseInt(computedStyle.getPropertyValue('--sat').replace('px', '')) || 0;
|
|
const right = parseInt(computedStyle.getPropertyValue('--sar').replace('px', '')) || 0;
|
|
const bottom = parseInt(computedStyle.getPropertyValue('--sab').replace('px', '')) || 0;
|
|
const left = parseInt(computedStyle.getPropertyValue('--sal').replace('px', '')) || 0;
|
|
|
|
setSafeAreaInsets({ top, right, bottom, left });
|
|
|
|
// 设置动态视口高度
|
|
const vh = window.innerHeight;
|
|
setViewportHeight(vh);
|
|
document.documentElement.style.setProperty('--vh', `${vh * 0.01}px`);
|
|
};
|
|
|
|
updateSafeArea();
|
|
|
|
window.addEventListener('resize', updateSafeArea);
|
|
window.addEventListener('orientationchange', updateSafeArea);
|
|
|
|
// 延迟更新以处理移动端浏览器地址栏变化
|
|
const timeoutId = setTimeout(updateSafeArea, 500);
|
|
|
|
return () => {
|
|
window.removeEventListener('resize', updateSafeArea);
|
|
window.removeEventListener('orientationchange', updateSafeArea);
|
|
clearTimeout(timeoutId);
|
|
};
|
|
}, []);
|
|
|
|
return {
|
|
safeAreaInsets,
|
|
viewportHeight,
|
|
/** 获取考虑安全区域的样式 */
|
|
getSafeAreaStyle: (includeBottom = true) => ({
|
|
paddingTop: `max(1rem, ${safeAreaInsets.top}px)`,
|
|
paddingRight: `max(1rem, ${safeAreaInsets.right}px)`,
|
|
paddingBottom: includeBottom ? `max(1rem, ${safeAreaInsets.bottom}px)` : undefined,
|
|
paddingLeft: `max(1rem, ${safeAreaInsets.left}px)`,
|
|
})
|
|
};
|
|
}
|