cover_image

一秒读懂|可视化大屏自适应方案

营运产研部 科技中通
2024年01月10日 08:27

图片



图片


随着物流行业的快速发展,用户对于快递送达时间的要求越来越高。于是,时效就成为了各家快递公司互相竞争的重要指标。影响快递时效的因素有很多,如自动化设备分拣效率,运输路由等,其中,现场管理也是影响时效的一个很重要因素。随着数字化的推广,现场管理由之前的实地管理,现场观察,逐步发展为现场可视化设备的实时监控、实时预警、实时干预、实时解决问题。那么如何把复杂的运营数据和现场实时场景呈现给现场管理者?如何在各种不同分辨率可视化投放工具上完美地展示数据,已经成为前端开发人员急需解决的问题。



图片


1、页面布局如何兼容各类不同分辨率设备


2、针对不同分辨率设备字体如何呈现


3、视频播放如何在不同分辨率设备上展示


4、如何实时监控屏幕分辨率的变化而自适应页面展示



图片


目前大多数的大屏适配解决方案多集中在以下3种方式:

1、vw/vh方案

原理:通过计算得出每个元素在屏幕中所占的百分比,1vw即为窗口的宽度的1%。

优缺点:优点是当屏幕比例和设计稿比例不同时,不会出现留白的情况,缺点是每个元素都需单独根据设计图尺寸做计算和适配,比较麻烦,效率低。


2、rem方案

原理:根据设计稿大小,设置一个 rem 的基准值 作为html根节点的font-size,所有元素的大小设置都是以rem为单位,且rem会根据屏幕的分辨率不同而变化。

优缺点:优点是适配简单,计算方便,缺点是适用于全新的项目,当对已有项目中的几个新页面做适配时,所有适配的页面都需做单独处理,否则会影响已有的页面,移动端项目大多数采用的是这种自适应方法。

3、scale属性等比缩放方案

原理:通过scale属性,按照比例自动缩放页面里面所有元素。

优缺点:优点是适配简单,不会改变原有的dom布局,不需要对单个元素做适配,背景图片和字体大均可以实现等比例缩放,缺点是当屏幕比例和设计稿比例不同时会出现留白区域。


上述3种方式可以实现不同分辨率的屏幕展示,但每种方式都有瑕疵,对于追求完美的前端来说,显然不是我们想要的效果。


最终解决方案为:结合grid布局和scale属性,监听窗口大小发生变化,根据窗口大小比例计算宽高分别需缩放的比例,补充留白区域,通过grid布局固定每个模块在大屏中所占的区域的比例,保证整体布局不发生变化。

grid布局:按照设计稿,将页面等分为3x2 共6个模块(可根据实际情况自行调整),每个业务板块根据自身的需求,可按照坐标抽方式设置该板块在大屏中所占的比例,例如横轴占一个模块,纵轴占两个模块可配置为{x:1,y:1,width:1,height:2}。

具体实现核心代码:

// dom 部分<div class="modules-list"><template v-for="component in options"><component:is="component.componentName":key="component.componentName"class="component-item":style="getPositionStyle(component)"></component></template></div>
...
// js部分
// 业务板块配置const options=[// 起始坐标以及宽度和高度占比{ x: 1, y: 1, width: 1, height: 2, componentName: 'module1',},...]// 根据options配置动态修改每个业务板块的占比const getPositionStyle = (module) => { return { 'grid-column-start': module.x, 'grid-column-end': Number(module.x + module.width), 'grid-row-start': module.y, 'grid-row-end': Number(module.y + module.height), }}
...
// css部分.modules-list { display: grid; // 3:2大屏 grid-gap: 20px; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); height: 100%; width: 100%;}


scale属性缩放:根据设计图尺寸和实际屏幕尺寸计算出需缩放的比例,对需要缩放的区域通过scale属性进行整体缩放。

具体实现核心代码:


// dom部分<div id="centerBigScreenParent" class="outer">    <div id="centerBigScreen" class="page-bg container">      <Header title="中心大屏" />      <div class="modules-container">        <div class="modules-list">          <template v-for="component in options">            <component              :is="component.componentName"              :key="component.componentName"              class="component-item"              :style="getPositionStyle(component)"            ></component>          </template>        </div>      </div>    </div>  </div>
...
// js部分keepFit() { const UIWidth = 1920 // 设计稿的宽度 const UIHeight = 1080 // 设计稿的高度 const scaleDom = document.getElementById('centerBigScreen') // 需要缩放的区域 const scaleDomParent = document.getElementById('centerBigScreenParent') // 需要缩放的区域父级元素 const scaleDomParentWidth = scaleDomParent.getBoundingClientRect().width // 父级元素的宽 const scaleDomParentHeight = scaleDomParent.getBoundingClientRect().height // 父级元素的高 let scale = 1 // 缩放比例 // 父级元素的宽高比例大于设计稿的宽高比例 则根据比例重新设置缩放区域的高度,反之则设置缩放区域的宽度 if (scaleDomParentWidth / scaleDomParentHeight < UIWidth / UIHeight) { scale = scaleDomParentWidth / UIWidth scaleDom.style.height = `${scaleDomParentHeight / scale}px` } else { scale = scaleDomParentHeight / UIHeight scaleDom.style.width = `${scaleDomParentWidth / scale}px` } scaleDom.style.transform = `scale(${scale})` scaleDom.style.transformOrigin = `0 0` // 指定缩放基准点,默认以中心点为基准点会导致缩放区域偏移}
....
// css部分// 父级元素根据实际情况调整.outer { width: 100%; height: 100%;}// 设计稿尺寸#centerBigScreen { width: 1920px; height: 1080px;}


注意事项:需监听父级元素的宽高变化,保证在父级元素大小发生变化时,缩放区域也可以实时变化。


实际效果:


图片



图片


未来我们还会有更多场景的接入,如装卸车现场的实时监控、超时的实时预警、各分拣线实时监测等,加强数字化建设,落地数字化工具,通过数字化手段来提升整体运单时效。转运中心和分拣场地也可以充分利用可视化大屏进行数字化管理,为现场管理者提供实时监测工具,及时有效地解决问题,提升运转效率,不断推动物流行业高质量发展,更好地实现货畅其流。



图片

图片

继续滑动看下一个
科技中通
向上滑动看下一个