0


可视化大屏自适应方案

前言

最近在做可视化大屏项目,遇到自适应的问题,这边做下记录。

方案

方案一:利用css的transform属性构造组件以及设计百分比以及scal()方法:

第一步:先写一个组件,width = 100vw,height = 100%,作为大屏展示的背景

<template><divclass="screen-large"><divclass="screen-large_wrap"><slot/></div></div></template><stylelang="scss">.screen-large{width: 100vw;min-height: 100%;max-height: 100vh;overflow: hidden;background: #567789;}</style>

第二步:根据设计同学提供的设计图可以计算出每部分区域的百分比,例如总尺寸是w*h,其中一个图标宽高是w1 * h1,实现常规切图,此时由1–>2可得:

<template><divclass="screen-large"><divclass="screen-large_wrap":style="style"><slot/></div></div></template><script>exportdefault{name:'Screen',data(){return{style:{width:`${this.w}px`,height:`${this.h}px`,transform:'scale(1) translate(-50%, -50%)',// 默认不缩放,垂直水平居中},};},props:{w:{// 设计图尺寸宽type: Number,default:1920,},h:{// 设计图尺寸高type: Number,default:1080,},},};</script><stylelang="scss">.screen-large{width: 100vw;min-height: 100%;max-height: 100vh;overflow: hidden;background: #567789;.screen-large_wrap{transform-origin: 0 0;position: absolute;top: 50%;left: 50%;padding: 18px 64px;}}</style>

第三步:基于第二步,需要根据大屏具体尺寸计算缩放比例,以及设置缩放比例,需要注意的是,绑定resize事件一定别忘了防抖,页面销毁别忘了移除监听事件:

<template><divclass="screen-large"><divclass="screen-large_wrap":style="style"><slot/></div></div></template><script>exportdefault{name:'Screen',data(){return{style:{width:`${this.w}px`,height:`${this.h}px`,transform:'scale(1) translate(-50%, -50%)',// 默认不缩放,垂直水平居中},};},props:{w:{// 设计图尺寸宽type: Number,default:1600,},h:{// 设计图尺寸高type: Number,default:1200,},},mounted(){this.setScale();this.onresize =this.debounce(()=>this.setScale(),100);
      window.addEventListener('resize',this.onresize);},methods:{// 防抖debounce(fn, t){const delay = t ||500;let timer;// eslint-disable-next-line func-namesreturnfunction(){// eslint-disable-next-line prefer-rest-paramsconst args = arguments;if(timer){clearTimeout(timer);}const context =this;
          timer =setTimeout(()=>{
            timer =null;fn.apply(context, args);}, delay);};},// 获取缩放比例getScale(){const w = window.innerWidth /this.w;const h = window.innerHeight /this.h;return w < h ? w : h;},// 设置缩放比例setScale(){this.style.transform =`scale(${this.getScale()}) translate(-50%, -50%)`;},},beforeDestroy(){
      window.removeEventListener('resize',this.onresize);},};</script><stylelang="scss">.screen-large{width: 100vw;min-height: 100%;max-height: 100vh;overflow: hidden;background: #567789;.screen-large_wrap{transform-origin: 0 0;position: absolute;top: 50%;left: 50%;padding: 18px 64px;}}</style>

引用方式和最终呈现效果


非常规尺寸可能会更具长宽比导致左右或者上下留出空白,这里需要采用

@media

媒介查询解决

方案二:大屏vw和vh适配方案:

按照设计稿的尺寸,将

px

按比例计算转为

vw

vh

假设设计稿尺寸为

1920*1080

(做之前一定问清楚UI设计稿的尺寸),即: 网页宽度=1920px,网页高度=1080px;我们都知道,网页宽度=100vw,网页宽度=100vh。
所以,在1920x*1080px的屏幕分辨率下1920px = 100vw,1080px = 100vh。这样一来,以一个宽300px和200px的div来说,其作所占的宽高,以vw和vh为单位,计算方式如下:

vwDiv = (300px / 1920px ) * 100vw;
vhDiv = (200px / 1080px ) * 100vh;

所以,就在

1920*1080

的屏幕分辨率下,计算出了单个div的宽高当屏幕放大或者缩小时,div还是以vw和vh作为宽高的,就会自动适应不同分辨率的屏幕。

但是每次都手动计算时不现实的,所以,需要封装一个方法,让它帮我自动计算:

// 使用scss的math函数,https://sass-lang.com/documentation/breaking-changes/slash-div
@use"sass:math";

//默认设计稿的宽度
$designWidth: 1920;
//默认设计稿的高度
$designHeight: 1080;

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

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

vue.config.js(只展示了与本方法有关的配置)

module.exports ={...,css:{loaderOptions:{//全局配置utils.scss,详细配置参考vue-cli官网sass:{prependData:'@import "@/styles/utils.scss";',}},},};

**.vue**

文件中使用

<script>exportdefault{name:"Index",}</script><stylelang="scss"scoped="scoped">/* 直接使用vw和vh函数,将像素值传进去,得到的就是具体的vw vh单位*/.chart-wrapper{width:vw(400);height:vh(300);font-size:vh(16);background-color: black;margin:vw(20);border:vh(2) solid red;}</style>

特殊的使用情况

有的时候可能不仅在

.vue

文件中使用,比如在js中动态创建的DOM元素
它可能是直接渲染到html里面的

let oDiv = document.createElement('div')
document.body.appendChild(oDiv)

这样的话,我用了以下两种处理方式,来给创建的div设置样式
1. 定义一些全局的class
新建一个

global.scss

文件,在

main.js

中引入
global.scss

.global-div{width:vw(300);height:vw(200);background-color: green;}

main.js

import'./styles/global.scss'

使用时,给创建的div设置className,

let oDiv = document.createElement('div')
oDiv.className ="global-div"

还有echarts图表可能会需要自适应字体

/* Echarts图表尺寸自适应 */exportconstfitChartFontSize=(size, defaultWidth =1920)=>{let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;if(!clientWidth)return size;let scale =(clientWidth / defaultWidth);returnNumber((size*scale).toFixed(3));}

使用

// Options.js//坐标轴刻度标签的相关设置yAxis:{axisLabel:{textStyle:{color:"rgba(255, 255, 255, 0.3)"},fontSize:fitChartFontSize(10)},},

2. 第三方自动适配插件库Postcss + 转换成vw的插件

一、安装postcss
npminstall postcss -S

二、使用npm/yarn安装postcss插件
$ npminstall postcss-px-to-viewport --save-dev
$ yarnadd-D postcss-px-to-viewport

配置参数

//默认参数options:{unitToConvert:'px',//(String) 需要转换的单位,默认为"px"viewportWidth:320,//(Number) 设计稿的视口宽度unitPrecision:5,//(Number) 单位转换后保留的精度propList:['*'],//(Array) 能转化为vw的属性列表viewportUnit:'vw',//(String) 希望使用的视口单位fontViewportUnit:'vw',//(String) 字体使用的视口单位selectorBlackList:[],// (Array) 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。minPixelValue:1,mediaQuery:false,replace:true,//(Boolean)是否直接更换属性值,而不添加备用属性exclude:undefined,//(Array or Regexp) 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件include:undefined,//(Array or Regexp) 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件 (include: /\/src\/mobile\//)landscape:false,landscapeUnit:'vw',landscapeWidth:568}

示例

/* example input: */.class{/* px-to-viewport-ignore-next */width: 10px;padding: 10px;height: 10px;/* px-to-viewport-ignore */border: solid 2px #000;/* px-to-viewport-ignore */}/* example output: */.class{width: 10px;padding: 3.125vw;height: 10px;border: solid 2px #000;}

使用PostCss配置文件时,在

postcss.config.js

添加如下配置

module.exports ={plugins:{// ...'postcss-px-to-viewport':{// options}}}

方案三:可视化图形可以使用DataV

根据固定的比例开发,界面显示用100%的开发方式,内部字体和尺寸都可以函数方法适配,其实就是另一种方式的transform适配方案

// 使用标签
<dv-full-screen-container>
  ...插入内容
  <div></div></dv-full-screen-container>

方案四:采用

amfe-flexible

结合

postcss

插件(postcss-pxtorem):

postcss.config.js

添加如下配置

module.exports ={plugins:{// ...'postcss-pxtorem':{rootValue:192,//PC端(1920的UI图)——换算基数(分辨率÷10)propList:['*'],unitPrecision:5,//保留rem小数点多少位exclude:/(node_module)///默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值selectorBlackList:['.el-'],//要忽略并保留为px的选择器replace:false,// (布尔值)替换包含REM的规则,而不是添加回退。mediaQuery:false,//媒体查询( @media screen 之类的)中不生效minPixelValue:12,//px小于12的不会被转换},}}

如果个别属性不想px转化rem,可以写成14

Px

或者14

PX

的单位

// 安装amfe-flexible
npminstall amfe-flexible -S# 主要作用是设置更目录fontsize大小 rem才会有基数计算

或者也可以手动写

utilRem.js
// 动态获取实际文档宽高并设置body缩放系数// 基准大小const baseSize =14// 设置 rem 函数functionsetRem(){// 当前页面宽度相对于 1920宽的缩放比例,可根据自己需要修改。const scale = document.documentElement.clientWidth /1920// 设置页面根节点字体大小
  document.documentElement.style.fontSize =(baseSize * Math.min(scale,2))+'px'}// 初始化setRem()// 改变窗口大小时重新设置 rem
window.onresize=function(){setRem()}
标签: css 前端 javascript

本文转载自: https://blog.csdn.net/Pentoncos/article/details/128000854
版权归原作者 J.P_P 所有, 如有侵权,请联系我们删除。

“可视化大屏自适应方案”的评论:

还没有评论