关于可视化大屏适配

一、目前市场上适配方案有两种;

vw、vh方案:

原理:按照设计稿的尺寸,将px按比例计算转为vw和vh;

优点:不会存在失真情况、可以动态计算图表的宽高,字体等,灵活性较高,当屏幕比例跟 ui 稿不一致时,不会出现两边留白情况;

缺点:类似第三方echart图表都需要单独做字体、间距、位移的适配,比较麻烦

核心代码以sass为例

css 复制代码
/*util.scss*/
@use 'sass:math';
//默认设计稿的宽度
$designWidth: 1920;
//默认设计稿的高度
$designHeight: 1080;

//px转为vw的函数
@function vw($px) {
  @return math.div($px, $designWidth) * 100vw;
}

//px转为vh的函数
@function vh($px) {
  @return math.div($px, $designHeight) * 100vh;
}

然后页面中引入util.scss、将20px更换为vh(20)

css 复制代码
@import '@/assets/style/util.scss';
 .dateText {
   padding-top: vh(20);
  }
 .weatherText {
    padding-top: vh(32);
  }

在js中使用到尺寸可以用下面这个工具方法去做转换

js 复制代码
const styleUtil = {
  // px转vw
  px2vw: function (_px, unit) {
    if (unit) {
      return (_px * 100.0) / designWidth + unit;
    }
    return (_px * 100.0) / designWidth + 'vw';
  },
  // px转vh
  px2vh: function (_px, unit) {
    if (unit) {
      return (_px * 100.0) / designHeight + unit;
    }
    return (_px * 100.0) / designHeight + 'vh';
  },
};

chart 图表中的适配用以下方法、需要注意的是、在resize的时候、让echart也resize一下

js 复制代码
const fitChartSize = (size, defaultHeight = 1080) => {
  // 默认宽高问设计
  let clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
  console.log('clientHeight::: ', clientHeight);
  if (!clientHeight) return size;

  let scale = clientHeight / defaultHeight;
  return Number((size * scale).toFixed(3));
};

缩放方案

原理:按照设计稿的尺寸布局,采用等比例缩放、在不同屏幕尺寸中将其通过放大缩小最外层的dom为一定比例、来保持原本布局;

优点:代码量少,适配简单 、一次处理后不需要在各个图表中再去单独适配;

缺点:如果缩放比例超过一定程度,字体图片等就会失真、会留白

核心代码

js 复制代码
  const usePreviewFitScale = (width, height, scaleDom, callback) => {
  // * 画布尺寸(px)
  const baseWidth = width;
  const baseHeight = height;

  // * 默认缩放值
  const scale = {
    width: 1,
    height: 1,
  };

  // * 需保持的比例
  const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5));
  const calcRate = () => {
    // 当前屏幕宽高比
    const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5));

    if (scaleDom) {
      if (currentRate > baseProportion) {
        // 表示更宽 以高度为基准 需要保持比例的宽
        scale.width = parseFloat(((window.innerHeight * baseProportion) / baseWidth).toFixed(5));
        scale.height = parseFloat((window.innerHeight / baseHeight).toFixed(5));
        const offsetW = ((window.innerWidth - window.innerHeight * baseProportion) / 2).toFixed(5);
        scaleDom.style.transform = `translateX(${offsetW}px) scale(${scale.width}, ${scale.height})`;
      } else {
        // 表示更高 以宽度为基准 需要保持比例的高
        scale.width = parseFloat((window.innerWidth / baseWidth).toFixed(5));
        scale.height = parseFloat((window.innerWidth / baseProportion / baseHeight).toFixed(5));
        scaleDom.style.transform = `translateX(0px) scale(${scale.width}, ${scale.height})`;
      }
      if (callback) callback(scale);
    }
  };

  const resize = throttle(() => {
    calcRate();
  }, 200);

  // * 改变窗口大小重新绘制
  const windowResize = () => {
    window.addEventListener('resize', resize);
  };

  // * 卸载监听
  const unWindowResize = () => {
    window.removeEventListener('resize', resize);
  };

  return {
    calcRate,
    windowResize,
    unWindowResize,
  };
};

至于还有流传rem + vw vh的方案(我是直接舍弃的)

这个rem的方案是根据单个宽度来计算的,只能适配宽度缩放、而大屏是一屏展示、而且在类似echart图表中,还需要做vw vh的单独适配、也是直接舍弃

有的同学还说有设计外层盒子百分比、盒子内部图表大小固定;

这种方式怎么说呢,那就得UI配合给我们设计出对应的样式、而且这种不用动脑子想也是很丑啊、还是直接pass吧、大屏本身就是要做的好看

二、我们先搞清楚可视化大屏适配与传统后台管理系统适配的区别

后台管理系统适配: 只适配宽、当宽超出则换行展示、类似的layout组件、Row组件、flex布局的都是采用只适配宽的方式、而且内部尺寸大小固定;

可视化大屏适配:宽高都需适配、而且没有滚动条、一屏展示;

三、当然不管采用那种方式我们都要一客户需求基点、然后分析出对应的解决方式

1、 嵌入管理系统内部展示: 多数情况以非全屏展示

这种情况如果使用缩放形式、其实也可以、那得需要UI出图为实际空间占比的UI、否则当我们写完代码,因为底部程序坞和浏览器窗口操作栏的高度,导致缩放比大、就会凸显失真情况的产生,而且有留白

一般情况UI给的图就是1920*1080的尺寸比、当然如果客户要求不高、采用这种方式当然是最省事;

但如果客户要求高、还是老老实实的使用vw、vh

2、纯全屏显示:多数情况给定尺寸为大屏尺寸、全屏展示、不考虑程序坞、浏览器上方操作栏;

这种场景呢,就比较适合缩放、因为一般适配屏幕大小不会差太多、没有很多情况、即使失真、多数也在客户考虑范围之内;

因为vw vh方式,如果是正常布局的vw、vh和echart 高度比计算得出来的尺寸位置,可能会存在对不齐的情况、当然具体情况具体分析;

相关推荐
WeiXiao_Hyy36 分钟前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡1 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone1 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09011 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king2 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳2 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵3 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星3 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js