82 lines
2.5 KiB
JavaScript
82 lines
2.5 KiB
JavaScript
const DEFAULT_NAV_CONTENT_HEIGHT = 44
|
|
const DEFAULT_GAP = 8
|
|
const DEFAULT_HORIZONTAL_PADDING = 8
|
|
|
|
function getSystemInfo() {
|
|
try {
|
|
return uni.getSystemInfoSync() || {}
|
|
} catch (error) {
|
|
return {}
|
|
}
|
|
}
|
|
|
|
function getMenuButtonRect() {
|
|
try {
|
|
const rect = uni.getMenuButtonBoundingClientRect?.()
|
|
return rect && rect.width ? rect : null
|
|
} catch (error) {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export function computeSafeAreaMetrics() {
|
|
const systemInfo = getSystemInfo()
|
|
const menuRect = getMenuButtonRect()
|
|
const statusBarHeight = Number(systemInfo.statusBarHeight || 20)
|
|
const windowWidth = Number(systemInfo.windowWidth || 375)
|
|
|
|
let navContentHeight = DEFAULT_NAV_CONTENT_HEIGHT
|
|
let navTopGap = DEFAULT_GAP
|
|
let capsuleWidth = 0
|
|
let capsuleRightSafeWidth = 0
|
|
|
|
if (menuRect) {
|
|
navTopGap = Math.max(Number(menuRect.top || 0) - statusBarHeight, DEFAULT_GAP)
|
|
navContentHeight = Math.max(Number(menuRect.height || 0) + navTopGap * 2, DEFAULT_NAV_CONTENT_HEIGHT)
|
|
capsuleWidth = Number(menuRect.width || 0)
|
|
const rightInset = Math.max(windowWidth - Number(menuRect.right || windowWidth), 0)
|
|
capsuleRightSafeWidth = Math.max(capsuleWidth + rightInset + DEFAULT_HORIZONTAL_PADDING, 96)
|
|
} else {
|
|
// 无胶囊位(H5、无自定义导航栏等):不预留右侧占位;样式里已有 32rpx 水平内边距
|
|
capsuleRightSafeWidth = 0
|
|
}
|
|
|
|
const topSafeHeight = statusBarHeight
|
|
const headerHeight = topSafeHeight + navContentHeight
|
|
|
|
return {
|
|
statusBarHeight,
|
|
topSafeHeight,
|
|
navContentHeight,
|
|
headerHeight,
|
|
navTopGap,
|
|
capsuleWidth,
|
|
capsuleRightSafeWidth,
|
|
}
|
|
}
|
|
|
|
export function applySafeAreaCssVars(metrics) {
|
|
if (typeof document === 'undefined' || !document?.documentElement) return
|
|
const root = document.documentElement.style
|
|
root.setProperty('--sq-safe-top', `${metrics.topSafeHeight}px`)
|
|
root.setProperty('--sq-nav-height', `${metrics.navContentHeight}px`)
|
|
root.setProperty('--sq-header-height', `${metrics.headerHeight}px`)
|
|
root.setProperty('--sq-capsule-right-safe', `${metrics.capsuleRightSafeWidth}px`)
|
|
}
|
|
|
|
export function initGlobalSafeArea() {
|
|
const metrics = computeSafeAreaMetrics()
|
|
const app = getApp?.()
|
|
if (app) {
|
|
app.globalData = app.globalData || {}
|
|
app.globalData.safeArea = metrics
|
|
}
|
|
applySafeAreaCssVars(metrics)
|
|
return metrics
|
|
}
|
|
|
|
export function getGlobalSafeArea() {
|
|
const app = getApp?.()
|
|
return app?.globalData?.safeArea || computeSafeAreaMetrics()
|
|
}
|