Skip to content

大屏项目(二)

全局页面适配原理

方案 1:vw/vh[推荐]

实现:按照设计稿尺寸将px按比例转化为vwvh

优点:可以动态计算图表的宽高、字体,比较灵活;屏幕比例和 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
  • 如果需要兼容不同比例的大屏,且在不同比例下都有较好的效果,图表占满屏幕,类似于移动端的响应式,则可以采用方案 1vw/vh