
介绍
在数据大屏、可视化面板、全屏展示类项目中,固定比例、等比缩放、无拉伸变形是核心需求。传统的 rem、vw/vh 适配方案在大屏场景下容易出现布局错乱、文字模糊、比例失调等问题。
这里实现一个开箱即用、支持 4 种缩放模式的 React Hook:useScreenScale,一行代码实现大屏完美自适应,支持等比缩放、宽铺满、高铺满、强制拉伸四种模式,兼容窗口 resize,真正做到一次集成、全端适配。
需求背景
大屏项目通常基于设计稿固定尺寸开发(如 1920×1080、3840×2160),需要满足:
- 保持设计稿原始比例,不拉伸、不压缩
- 支持不同缩放策略(自适应、宽铺满、高铺满、强制铺满)
- 窗口大小变化时自动重新计算适配
- 居中展示,无滚动条 / 无溢出
基于以上需求,我们采用 CSS transform: scale 方案实现缩放,性能更好、适配更稳定、布局零侵入
实现方案
- 以设计稿宽高为基准(默认 1920×1080)
- 计算当前窗口与设计稿的缩放比例
- 使用 scale 对根容器进行缩放
- 配合 transformOrigin + 绝对居中实现完美居中
- 监听 resize 事件实时更新适配
hooks实现
javascript
import { useEffect } from 'react';
// adaptive (等比缩放,自适应比例展示) scrollX (宽度铺满,高度等比) scrollY (高度铺满,宽度等比) full (强制拉伸铺满)
type ScaleMode = 'adaptive' | 'scrollX' | 'scrollY' | 'full'
interface UseScreenScaleOptions {
width?: number
height?: number,
screenMode?: ScaleMode
}
export const useScreenScale = (options: UseScreenScaleOptions = {}) => {
const { width = 1920, height = 1080, screenMode = 'adaptive' } = options;
useEffect(() => {
function resize() {
const app = document.querySelector('#screen-root') as HTMLElement;
if (!app) return;
const clientW = window.innerWidth;
const clientH = window.innerHeight;
let scale = 1;
let compWidth = width;
let compHeight = height;
switch (screenMode) {
case 'adaptive':
scale = Math.min(clientW / width, clientH / height);
break;
case 'scrollX':
scale = clientW / width;
break;
case 'scrollY':
scale = clientH / height;
break;
case 'full':
compWidth = clientW;
compHeight = clientH;
scale = 1;
break;
}
app.style.width = `${compWidth}px`;
app.style.height = `${compHeight}px`;
app.style.transform = `scale(${scale}) translate(-50%, -50%)`;
app.style.transformOrigin = '0 0';
app.style.left = '50%';
app.style.top = '50%';
}
resize();
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
}, [width, height, screenMode]);
}
使用方式
javascript
import { useScreenScale } from '@/hooks/useScreenScale';
const BigScreen = () => {
// 启用自适应(默认 1920×1080,模式 adaptive)
useScreenScale();
// 自定义配置示例
// useScreenScale({ width: 3840, height: 2160, screenMode: 'scrollY' });
return (
{/* 必须设置 id="screen-root" */}
<div id="screen-root">
{/* 你的大屏内容 */}
<div className="screen-container">大屏内容区域</div>
</div>
);
};
export default BigScreen;
四种缩放模式详解
| 模式 | 说明 | 适用场景 |
|---|---|---|
| adaptive(默认) | 等比缩放,取最小比例,完整显示、居中无变形 | 等比缩放,取最小比例,完整显示、居中无变形 |
| scrollX | 宽度铺满窗口,高度等比缩放 | 横向内容优先、允许纵向滚动 |
| scrollY | 高度铺满窗口,宽度等比缩放 | 纵向内容优先、允许横向滚动 |
| full | 强制拉伸铺满窗口 | 不要求比例、必须铺满全屏场景 |
