screenAdapter.ts
/**
* 大屏自适应方案 - transform scale + 固定设计稿尺寸
* 设计稿尺寸: 1920 x 1080 (16:9)
*
* 针对 1920x1080 屏幕优化:
* - 标准 16:9 屏幕:1:1 完美显示
* - 宽屏(>16:9):高度占满,左右居中留黑边
* - 窄屏(<16:9):宽度占满,上下居中留黑边
*/
// 设计稿尺寸
export const DESIGN_WIDTH = 1920;
export const DESIGN_HEIGHT = 1080;
export const DESIGN_RATIO = DESIGN_WIDTH / DESIGN_HEIGHT; // 16:9 = 1.777...
const getViewportSize = () => {
const width = window.innerWidth || document.documentElement.clientWidth || DESIGN_WIDTH;
const height = window.innerHeight || document.documentElement.clientHeight || DESIGN_HEIGHT;
return { width, height };
};
/**
* 初始化大屏自适应 - 针对 1920x1080 优化
* 自动检测屏幕比例,选择最佳缩放策略
*/
export function initScreenAdapter(): void {
const app = document.getElementById('app');
if (!app) return;
const refresh = (): void => {
// 使用浏览器可视区域尺寸(非全屏时也能适配)
const { width, height } = getViewportSize();
const screenRatio = width / height;
// 计算缩放比例 - contain 模式,完整显示内容,不溢出
const scaleX = width / DESIGN_WIDTH;
const scaleY = height / DESIGN_HEIGHT;
const scale = Math.min(scaleX, scaleY);
// 水平、垂直均居中
const offsetX = (width - DESIGN_WIDTH * scale) / 2;
const offsetY = (height - DESIGN_HEIGHT * scale) / 2;
// 设置 app 容器样式
app.style.width = DESIGN_WIDTH + 'px';
app.style.height = DESIGN_HEIGHT + 'px';
app.style.position = 'absolute';
app.style.transform = `scale(${scale})`;
app.style.transformOrigin = '0 0';
app.style.left = `${offsetX}px`;
app.style.top = `${offsetY}px`;
app.style.margin = '0';
// 禁止滚动 — 内容始终完整显示在视口内
document.documentElement.style.width = '100%';
document.documentElement.style.height = '100%';
document.documentElement.style.overflow = 'hidden';
document.documentElement.style.position = 'relative';
document.body.style.width = '100%';
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
document.body.style.position = 'relative';
document.body.style.margin = '0';
document.body.style.padding = '0';
// document.body.style.background = '#020924';
document.documentElement.style.fontSize = '16px';
console.log(`[ScreenAdapter] 屏幕: ${width}x${height}, 比例: ${screenRatio.toFixed(3)}, 缩放: ${scale.toFixed(4)}`);
};
refresh();
let resizeTimer: number | null = null;
window.addEventListener('resize', () => {
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer = window.setTimeout(refresh, 100);
});
}
/**
* 获取当前缩放比例
*/
export function getCurrentScale(): number {
const { width, height } = getViewportSize();
const scaleX = width / DESIGN_WIDTH;
const scaleY = height / DESIGN_HEIGHT;
return Math.min(scaleX, scaleY);
}
/**
* 将设计稿 px 转换为实际 px
*/
export function px(designPx: number): number {
return Math.round(designPx * getCurrentScale());
}
/**
* @deprecated 旧版 rem 适配,已废弃
*/
export function setRem(): void {
console.warn('[ScreenAdapter] setRem is deprecated, use initScreenAdapter() instead');
}
/**
* @deprecated 旧版 scale 适配,已废弃
*/
export function setScale(): void {
console.warn('[ScreenAdapter] setScale is deprecated, use initScreenAdapter() instead');
}
main.ts引入:
app.mount('#app')
import { initScreenAdapter } from './utils/screenAdapter'
// 大屏自适应 - 1920x1080 等比例缩放
// 针对 1920x1080 屏幕优化:完整显示内容,保持比例
initScreenAdapter()