Files
education/frontend/src/utils/adaptive.js
T

60 lines
2.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 全局视口等比缩放 —— 让整个系统在不同大小屏幕(桌面 1280~4K)下布局不崩塌。
*
* 原理:
* 以 DESIGN_WIDTH(1920)为设计基准宽度。将视口宽度与设计宽的比值作为缩放倍数,
* 作用到文档根节点 <html> 的 zoom 上:
* - 视口 < 设计宽(如 1280):zoom < 1,整体等比缩小,避免窄屏布局被撑破;
* - 视口 = 设计宽(1920):zoom = 1,原生 1:1 显示;
* - 视口 > 设计宽(如 4K 3840):zoom = 2,整体等比放大,大屏不再留白/字小。
* 缩放倍数被限制在 MIN_SCALE ~ MAX_SCALE 之间,MAX_SCALE=2 恰好覆盖 4K3840/1920)。
*
* 采用 zoom 挂在 documentElement 上,可覆盖包括 Element UI 挂载到 body 的
* 弹窗/提示/下拉选择在内的所有内容,保证整套界面一致缩放、不塌陷。
*
* 兼容性:modern Chromium / Edge / Safari 以及 Firefox(≥126) 均支持 zoom。
*/
let initialized = false
export const DEFAULT_DESIGN_WIDTH = 1920
// 最小缩放倍数:极窄视口的安全下限,避免文字过小/布局异常
export const MIN_SCALE = 0.5
// 最大缩放倍数:2 对应 4K(3840/1920=2),更高分辨率也封顶在此,避免过度放大
export const MAX_SCALE = 2
/**
* 初始化全局自适应。可在任意入口调用,重复调用幂等。
* @param {number} [designWidth] 设计基准宽度,默认 1920
*/
export function initAdaptive(designWidth = DEFAULT_DESIGN_WIDTH) {
if (initialized) {
return
}
initialized = true
let timer = null
const applyScale = () => {
const root = document.documentElement
if (!root) {
return
}
const width = root.clientWidth || window.innerWidth
const ratio = width / designWidth
// 收敛到 [MIN_SCALE, MAX_SCALE],规避极端宽高的异常比例
const scale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, ratio))
root.style.zoom = scale === 1 ? '' : String(scale)
}
const onResize = () => {
// 简单防抖,避免 resize 高频触发引起抖动
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(applyScale, 100)
}
applyScale()
window.addEventListener('resize', onResize)
}