大屏项目(二)
全局页面适配原理
方案 1:vw/vh[推荐]
实现:按照设计稿尺寸将px按比例转化为vw和vh
优点:可以动态计算图表的宽高、字体,比较灵活;屏幕比例和 ui 不一致的时候不会出现两边留白的场景
缺点:每个图表都需要单独做字体、间距、位移的适配
less
// 设计稿尺寸(默认1920x1080)
@designWidth: 1920;
@designHeight: 1080;
// px转vw:宽度相关属性
.px2vw(@px) {
width: (@px / @designWidth) * 100vw;
}
//less中使用
.box2 {
.px2w(1800);
}
//组件使用需要重写一个js方法处理,但逻辑是一样的js
export const fitChartSize = (size: number, defaultWidth = 1920) => {
const clientWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (!clientWidth) return size;
const scale = clientWidth / defaultWidth;
return Number((size * scale).toFixed(3));
};这个方法存在个问题:屏幕尺寸变化后,需要手动刷新页面才能完成自适应调整,所以我们需要在每个图表内添加一个事件监听器监听resize,每次监听到的时候执行chart.resize(),在清理函数里移除监听器
方案 2:scale
实现:通过 scale 属性,根据屏幕大小对图表进行整体的等比缩放,达到自适应效果
优点:代码量少,适配简单;一次处理后不需要在各个图表单独适配
缺点:由于根据 ui 等比缩放,所以大屏和 ui 比例不一致的情况下会出现周边留白;缩放比例过大会导致字体略微模糊,且事件热区偏移
tsx
import { useEffect, useState } from "react";
import "./App.css";
import Header from "./components/Header";
import { scale } from "./utils";
function App() {
const [scaleLevel, setScaleLevel] = useState < number > 1;
useEffect(() => {
const handleResize = () => {
setScaleLevel(scale());
};
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return (
<>
<div
className="app"
style={{ transform: `scale(${scaleLevel}) translate(-50%,-50%)` }}
>
<Header />
</div>
</>
);
}
export default App;css
.app {
width: 1920px;
height: 1080px;
transform-origin: 0 0;
position: absolute;
left: 50%;
top: 50%;
}ts
export const scale = () => {
// 设计稿的宽高
const designWidth = 1920;
const designHeight = 1080;
const scaleX = document.documentElement.clientWidth / designWidth;
const scaleY = document.documentElement.clientHeight / designHeight;
return Math.min(scaleX, scaleY);
};TIP
- 如果想要实现简单,且客户同意留白,直接使用方案 2
scale - 如果需要兼容不同比例的大屏,且在不同比例下都有较好的效果,图表占满屏幕,类似于移动端的响应式,则可以采用方案 1
vw/vh