随着物流行业的快速发展,用户对于快递送达时间的要求越来越高。于是,时效就成为了各家快递公司互相竞争的重要指标。影响快递时效的因素有很多,如自动化设备分拣效率,运输路由等,其中,现场管理也是影响时效的一个很重要因素。随着数字化的推广,现场管理由之前的实地管理,现场观察,逐步发展为现场可视化设备的实时监控、实时预警、实时干预、实时解决问题。那么如何把复杂的运营数据和现场实时场景呈现给现场管理者?如何在各种不同分辨率可视化投放工具上完美地展示数据,已经成为前端开发人员急需解决的问题。
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%;
}
// 设计稿尺寸
width: 1920px;
height: 1080px;
}
注意事项:需监听父级元素的宽高变化,保证在父级元素大小发生变化时,缩放区域也可以实时变化。
实际效果:
未来我们还会有更多场景的接入,如装卸车现场的实时监控、超时的实时预警、各分拣线实时监测等,加强数字化建设,落地数字化工具,通过数字化手段来提升整体运单时效。转运中心和分拣场地也可以充分利用可视化大屏进行数字化管理,为现场管理者提供实时监测工具,及时有效地解决问题,提升运转效率,不断推动物流行业高质量发展,更好地实现货畅其流。