前端大屏可视化项目之--大屏适配

3,219 阅读10分钟

1.认识大屏

1.1大屏的常见应用

在我们的生活中,经常会见到一些比较大的屏幕,比如:指挥大厅、展厅、展会中的大屏。这些设备就可以称之为大屏设备,当然1920 x 1080 和 3840 x 2160(4k 屏 )也可以说是属于大屏。大屏项目广泛应用于零售、物流、电力、水利、环保、交通、医疗等领域,一般都有着丰富炫酷的数据可视化效果,结合大屏展示,效果直接拉满,例如下图这种:

image.png

1.2大屏硬件设备

(1)拼接屏

拼接屏,顾名思义就是很多屏幕按照一定拼接方式拼接而成,如下图:

image.png

拼接方式取决于使用场景的需求,如下例子:

 1920px * 1080px,即 1 * 1 个 显示屏(16 : 9)

 3840 * 2160(4k 屏 ),即 2 * 2 个显示屏(16 : 9)

 5760 * 3240,即 3 * 3 个显示屏(16 : 9)

 7680 * 3240,即 4 * 3 个显示屏(64 : 27)

 9600 * 3240,即 5 * 3 个显示屏(80 : 27)

(2)LED屏

LED 也是现在大屏中常用的硬件,它是由若干单体屏幕模块组成的,它的像素点计算及拼接方式与拼接屏有很大区别。 LED 可以看成是矩形点阵,具体拼接方式也会根据现场实际情况有所不同,拼接方式的不同直接影响到设计的尺寸规则。

LED 屏有很多规格,各规格计算方法相同。

比如,我们用单体为 500 * 500 mm的作为标准计算,每个单体模块像素点横竖都为 128px

如下图,横向 12 块竖向 6 块,横向像素为 12812=1536px,竖向 1286=768px。可以使用横竖总像素去设计。

最终算出的屏幕尺寸:1536px * 768px

image.png

1.3 大屏设计稿尺寸

(1)拼接屏设计稿尺寸

大多数屏幕分辨率是 1920 * 1080。当然也会有一些大屏,比如6 * 3的拼接屏,横向分辨率为 6*1920=11520px。竖向分辨率为 3 * 1080=3240px。设计可以按照横竖计算后的总和(11520px * 3240px)作为设计尺寸。

补充:

尺寸过大那的就不太适合按原尺寸设计,怎么判断什么时候可以按照总和设计,什么时候最好不要按照总和设计。这有一个关键 的节点4K,超过 4K 后现有硬件会产生很多问题,例如:卡顿,GPU 压力过大,高负荷运行等等。

正常设计建议最好是保持在 4K 内,由于硬件问题,所以现在大家采用的都是输出 4K 及以下,既保证流畅度又能在视觉上清晰阅读。

所以设计时也要保持同样的规则。保持大屏的比例等比缩放即可。

注:最好是按照硬件的输出分辨率设计(关键),因为按照输出分辨率设计,一定不会出错。

举例:

1920px * 1080px( 1*1),设计搞尺寸 :1920px * 1080px 。

3840 * 2160( 2*2 4k 屏 ),设计搞尺寸 : 3840 * 2160 。

5760 * 3240( 3*3),设计搞尺寸 : 5760 * 3240 。

7680 * 3240( 4*3),设计搞尺寸 : ( 3840 * 1620 需要出 1倍图 和 2倍图, 7680 * 3240 )

9600 * 3240( 5*3),设计搞尺寸 : 比如:4800 * 1620,需要出 1倍图 和 2倍图

(2)LED屏设计稿尺寸

LED 大屏是由若干单体屏幕模块组成的,LED 屏有很多规格,但是规格计算方法相同。

比如:我们用单体为 500 * 500 的作为标准计算,每个单体模块像素点横竖都为 128px。

如图横向 12 块竖向 6 块,横向像素为 12812=1536px,竖向 1286=768px。可以使用横竖总像素去设计。

此处规则和之前的拼接屏一样,如果超过 4K 像素时可以等比缩放,建议尽量保持在 4k 及以下。

image.png

◼ 比如

1536px * 768px,设计搞尺寸 : 1536px * 768px 。

4608 * 3072,设计搞尺寸 : 4608 * 3072 。

9216 * 6144,设计搞尺寸 : 4608 * 3072,需要出 1倍图 和 2倍图

(3)移动端设计稿尺寸

对于移动端的大屏展示,基本按照实际尺寸设计即可,比如

750px * Auto,设计搞尺寸 : 750px * Auto 。

◼ 大屏设计稿尺寸的总结:

设计尺寸建议按照输出分辨率设计(重点)

拼接后像素在 4k 左右直接按照总和设计就行

总和设计建议不要超过 4k,可以按比例缩小设计搞(非固定,超过也是可以,只是强烈建议)

建议定设计搞尺寸前,先了解硬件及信号输入输出,确定设计搞的尺寸。

特殊尺寸,需到现场调试最佳设计搞的尺寸。

◼ 大屏适配方案的总结:

特殊尺寸不要考虑适配电脑屏幕又适配拼接屏,因为完全没有必要,也不可能一稿既适配电脑也适配各种尺寸大屏。

这种情况应该优先考虑目标屏幕的适配,要针对性设计,而在小屏根据等比例缩放显示,这才是最佳的解决方法

2.大屏适配方案

大屏的幕尺寸通常也是非常多的,很多时候我们是希望页面在不同的屏幕尺寸上显示不同的尺寸,那大屏的适配方案有

方案一:百分比设置;

方案二:rem 单位 + 动态设置 html 的 font-size;

方案三:vw 单位;

方案四:flex 弹性布局;

方案五:scale 等比例缩放(推荐)

这里重点介绍二、三、五这3个方案

2.1 适配方案一:rem + font-size

我们都知道,css中的单位有px、em、rem,px是固定的像素,一旦设置就不会动态变动,而em、rem则是相对单位,是相对于字体大小的,如果一个前端页面各个部分的宽高设置都用px,那页面就定死了,当窗口大小发生变化时,页面大小是不会动态改变的。如果宽高用的rem或者em这种相对单位,以rem为例,它是以根元素的字体大小为基础,例如根元素字体大小为20px,那么1rem就是20px,1.5rem就是30px,如果整个页面都用rem作为宽高单位,只要修改根元素的字体大小,那么整个页面就可实现动态伸缩。

综上,实现这种方案的做法是:

1.引入库,动态设置html根字体的大小

2.将之前的px 转写为rem

1.引入的代码如下:

(function flexible(window, document) {
  var docEl = document.documentElement;
  var dpr = window.devicePixelRatio || 1;

  function setBodyFontSize() {
    if (document.body) {
      // 1.body 字体大小默认为 16px
      document.body.style.fontSize = 16 * dpr + "px";
    } else {
      document.addEventListener("DOMContentLoaded", setBodyFontSize);
    }
  }
  setBodyFontSize();

  // 这里默认平均分成 10 等分(适用移动端)
  function setRemUnit() {
    // 2.这里改成了24,将网页分成 24 等份,这样每个 1rem 对应的为 80px
    // 3.为什么要分成 24份 ? 目的是让缩放的细腻度更小,比如 0.1rem -> 8px
    var rem = docEl.clientWidth / 24;
    docEl.style.fontSize = rem + "px";
  }

  setRemUnit();

  window.addEventListener("resize", setRemUnit);
  window.addEventListener("pageshow", function (e) {
    if (e.persisted) {
      setRemUnit();
    }
  });

  if (dpr >= 2) {
    var fakeBody = document.createElement("body");
    var testElement = document.createElement("div");
    testElement.style.border = ".5px solid transparent";
    fakeBody.appendChild(testElement);
    docEl.appendChild(fakeBody);
    if (testElement.offsetHeight === 1) {
      docEl.classList.add("hairlines");
    }
    docEl.removeChild(fakeBody);
  }
})(window, document);


  1. 如何方便地将写好的px转写为rem呢,可以借助VSCODE插件cssrem,并且在该插件的设置中,设置好根元素的字体大小,这里以80px为例

image.png

当我们鼠标放在1920px上面时,会自动出现转换后的rem值,输入新值时,还会弹窗让我们选择

image.png

2.2 适配方案二:vw

vw ,就是根据窗口的宽度,分成100等份,100vw就表示满宽,50vw就表示一半宽。(vw 始终是针对窗口的宽),同理,vh则为窗口的高度。

这里的窗口分成几种情况:

  • 在桌面端,指的是浏览器的可视区域
  • 移动端指的就是布局视口

如果宽度为1920px,那么100vw = 1920px,1vw = 19.2px。

这里还是可以使用 cssrem 插件进行单位转换, body的宽高(1920px * 1080px)直接把px单位转vw单位

image.png

image.png

2.3适配方案3 scale (推荐方案)

举例子,设计稿是19201080,实际屏幕大小是38402160,此时 3840/1920 =2,说明将原设计稿的宽高直接放大2倍即可满足。所以直接用方案一是没问题的。 再举个例子,设计稿是19201080,76802160,宽度是1920的四倍,高度是1080的二倍,如果把设计稿的宽高直接X4放大,显然不合适,因为屏幕装不下1080*4 这样的宽度,这时候就得考虑方案2,动态调整缩放比例

方案一:直接根据宽度的比率进行缩放。(宽度比率=网页当前宽 / 设计稿宽)

    window.onload = function () {
        triggerScale();
        window.addEventListener("resize", function () {
          triggerScale();
        });
      };

      function triggerScale() {
        var targetX = 1920;
        var targetY = 1080;

        // 获取html的宽度和高度(不包含滚动条)
        var currentX =
          document.documentElement.clientWidth || document.body.clientWidth;
        // https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth
        var currentY =
          document.documentElement.clientHeight || document.body.clientHeight;

        // 1.缩放比例  3840 / 2160 => 2
        var ratio = currentX / targetX;

        var bodyEl = document.querySelector("body");
        // 2.需要修改缩放的原点
        bodyEl.setAttribute("style", `transform:scale(${ratio})`);
      }
  1. 方案二:动态计算网页宽高比,决定是是否按照宽度的比率进行缩放。
 window.onload = function () {
        triggerScale();
        window.addEventListener("resize", function () {
          triggerScale();
        });
      };

      function triggerScale() {
        var targetX = 1920;
        var targetY = 1080;
        var targetRatio = 16 / 9;
        var currentX =
          document.documentElement.clientWidth || document.body.clientWidth;
        var currentY =
          document.documentElement.clientHeight || document.body.clientHeight;

        // 1.缩放比例  3840 / 2160 => 2
        var ratio = currentX / targetX;
        var currentRatio = currentX / currentY;
        var transformStr = "";
        if (currentRatio > targetRatio) {
          ratio = currentY / targetY;
          transformStr = `transform:scale(${ratio}) translateX(-${
            targetX / 2
          }px); left:50%;`;
        } else {
          transformStr = `transform:scale(${ratio})`;
        }
        var bodyEl = document.querySelector("body");
        // 2.需要修改缩放的原点
        bodyEl.setAttribute("style", transformStr);
      }

三种适配方案的对比

  • vw 相比于 rem 的优势

    • 优势一:不需要去计算 htmlfont-size 大小,不需要给 html 设置 font-size,也不需要设置 bodyfont-size ,防止继承;
    • 优势二:因为不依赖 font-size 的尺寸,所以不用担心某些原因 htmlfont-size 尺寸被篡改,页面尺寸混乱;
    • 优势三vw 相比于 rem 更加语义化1vw1/100viewport 大小(即将屏幕分成 100 份); 并且具备 rem 之前所有的优点
  • vwrem 存在问题

    • 如果使用 remvw 单位时,在 JS 中添加样式时,单位需要手动设置 remvw
    • 第三方库的字体等默认的都是 px 单位,比如:elementecharts,因此通常需要层叠第三方库的样式。
    • 当大屏比例更大时,有些字体还需要相应的调整字号
  • scale 相比 vwrem 的优势

    • 优势一:相比于 vwrem,使用起来更加简单,不需要对单位进行转换。

    • 优势二:因为不需要对单位进行转换,在使用第三方库时,不需要考虑单位转换问题。

    • 优势三:由于浏览器的字体默认最小是不能小于 12px ,导致 remvw 无法设置小于 12 px的字体,缩放没有这个问题。