大屏比例缩放

复制代码
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()
相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万2 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95272 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大2 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师2 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端