赞
踩
在做可视化大屏项目的时候,适配不同分辨率屏幕的电脑是最头疼的问题,那么,有没有一种方案,可以解决大屏适配问题呢。
在不懈的努力查找以及总结后,得到了一套,个人认为比较科学的适配方案。
设计图宽高比例固定,并且跟随页面变化,等比例缩放
前端只需要按照设计图(px)单位设计开发即可,效果如图:
无论窗口缩放,屏幕放大缩小,我们的可视化界面都可以按照设计图比例正常展示,不会出现字体模块爆出,或者拉伸问题。这就是我想要的适配方案。
给最外层的盒子(body也行)加上标识(id, 或ref)
- <div id="appRef">
- xxx(反正就是整个可视化页面内容)
- </div>
这里仅展示id标识符的css样式
- #appRef {
- width: 1920px; /* 设计图宽 */
- height: 1080px; /* 设计图高 */
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- transform-origin: left top;
- overflow: hidden;
- }
为了方便copy一点,这里就把普通html开发的适配js写法直接奉上
- // * 默认缩放值
- const scale = {
- width: '1',
- height: '1',
- }
-
- // * 设计稿尺寸(px)
- const baseWidth = 1920
- const baseHeight = 1080
-
- // * 需保持的比例
- const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
-
- let drawTiming = null
- calcRate()
- window.addEventListener('resize', resize)
-
- // * 初始化页面比例
- function calcRate () {
- const appRef = document.getElementById("appRef")
- if (!appRef) return
- // 当前宽高比
- const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
- if (appRef) {
- if (currentRate > baseProportion) {
- // 表示更宽
- scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
- scale.height = (window.innerHeight / baseHeight).toFixed(5)
- appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
- } else {
- // 表示更高
- scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
- scale.width = (window.innerWidth / baseWidth).toFixed(5)
- appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
- }
- }
- }
-
- // * 窗口大小变化
- function resize () {
- clearTimeout(drawTiming)
- // 加延迟是为了更好的看到变化的过程,不需要的可以不用
- drawTiming = setTimeout(() => {
- calcRate()
- }, 200)
- }
vue开发的同理,为了方便copy,代码直接奉上
- // * 默认缩放值
- const scale = {
- width: '1',
- height: '1',
- }
-
- // * 设计稿尺寸(px)
- const baseWidth = 1920
- const baseHeight = 1080
-
- // * 需保持的比例
- const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5))
-
- export default {
- data() {
- return {
- drawTiming: null // 定时函数
- }
- },
- mounted () {
- this.calcRate()
- window.addEventListener('resize', this.resize)
- },
- methods: {
- // 初始化页面比例
- calcRate () {
- const appRef = this.$refs["appRef"]
- if (!appRef) return
- // 当前宽高比
- const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5))
- if (appRef) {
- if (currentRate > baseProportion) {
- // 表示更宽
- scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5)
- scale.height = (window.innerHeight / baseHeight).toFixed(5)
- appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
- } else {
- // 表示更高
- scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5)
- scale.width = (window.innerWidth / baseWidth).toFixed(5)
- appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`
- }
- }
- },
- // 窗口大小变化
- resize () {
- clearTimeout(this.drawTiming)
- this.drawTiming = setTimeout(() => {
- this.calcRate()
- }, 200)
- }
- },
- beforeDestroy () {
- window.removeEventListener('resize', this.resize)
- },
- }
在所有script的最后面引入就行,如图:
使用mixin混入引入(或者其他方式也行,个人习惯)
- <template>
- <div id="appRef" ref="appRef">xxx</div>
- </template>
- <script>
- import draw from "@/utils/draw"
- export default {
- mixins: [draw]
- }
- </script>
自适应全屏,不管屏幕宽高比如何,都以铺满全屏的形式进行展示。(适用于页面布局为百分比、或者flex自适应布局)
- const appRef = document.getElementById("appRef")
- // 初始化页面
- calcRate()
-
- window.addEventListener('resize', calcRate)
-
- function calcRate () {
- if (!appRef) return
- // 获取浏览器缩放比例
- const browserRoom = getZoom()
- /**
- * 1. 先将宽高乘上浏览器缩放倍数x
- * 2. 再将整个页面用scale缩放 1/x 倍
- * 在视觉上,就感觉页面没有缩放
- */
- // 宽高
- const w = window.innerWidth * browserRoom
- const h = window.innerHeight * browserRoom
- // scale缩放比例
- const scl = parseFloat((1 / browserRoom).toFixed(5))
-
- // 页面重绘处理
- appRef.style.width = `${w}px`
- appRef.style.height = `${h}px`
- appRef.style.transform = `scale(${scl}, ${scl}) translate(-50%, -50%)`
- // 页面重绘完成后,再进行echarts重绘,保证echarts图表的自适应性
- myChart.resize()
- myChart2.resize()
-
- }
-
- // 获取浏览器缩放比例
- function getZoom() {
- let ratio = 0,
- screen = window.screen,
- ua = navigator.userAgent.toLowerCase();
- if (window.devicePixelRatio !== undefined) {
- ratio = window.devicePixelRatio;
- } else if (~ua.indexOf('msie')) {
- if (screen.deviceXDPI && screen.logicalXDPI) {
- ratio = screen.deviceXDPI / screen.logicalXDPI;
- }
- } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
- ratio = window.outerWidth / window.innerWidth;
- }
- if (ratio){
- ratio = Math.round(ratio * 100);
- }
- return parseFloat(ratio/100).toFixed(2);
- }
- // * 默认缩放值
- const scale = {
- width: '1',
- height: '1',
- }
-
- export default {
- data() {
- return {
- drawTiming: null // 定时函数
- }
- },
- mounted () {
- this.calcRate()
- window.addEventListener('resize', this.resize)
- },
- methods: {
- // 初始化页面比例
- calcRate () {
- const appRef = this.$refs["appRef"]
- if (!appRef) return
- // 获取浏览器缩放比例
- const browserRoom = this.getZoom()
- // 当前宽高比
- /**
- * 1. 先将宽高乘上浏览器缩放倍数x
- * 2. 再将整个页面用scale缩放 1/x 倍
- * 在视觉上,就感觉页面没有缩放
- */
- // 宽高
- const w = window.innerWidth * browserRoom
- const h = window.innerHeight * browserRoom
- // scale缩放比例
- const scl = parseFloat((1 / browserRoom).toFixed(5))
-
- // 页面重绘处理
- appRef.style.width = `${w}px`
- appRef.style.height = `${h}px`
- appRef.style.transform = `scale(${scl}, ${scl}) translate(-50%, -50%)`
- // 页面重绘完成后,再进行echarts重绘,保证echarts图表的自适应性
- // myChart.resize()
- // myChart2.resize()
- },
- // 窗口大小变化
- resize () {
- clearTimeout(this.drawTiming)
- this.drawTiming = setTimeout(() => {
- this.calcRate()
- }, 200)
- },
- // 获取浏览器缩放比例
- getZoom() {
- let ratio = 0,
- screen = window.screen,
- ua = navigator.userAgent.toLowerCase();
- if (window.devicePixelRatio !== undefined) {
- ratio = window.devicePixelRatio;
- } else if (~ua.indexOf('msie')) {
- if (screen.deviceXDPI && screen.logicalXDPI) {
- ratio = screen.deviceXDPI / screen.logicalXDPI;
- }
- } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
- ratio = window.outerWidth / window.innerWidth;
- }
- if (ratio){
- ratio = Math.round(ratio * 100);
- }
- return parseFloat(ratio/100).toFixed(2);
- }
- },
- beforeDestroy () {
- window.removeEventListener('resize', this.resize)
- },
- }
总结:只要是按照设计图,正常开发的大屏项目,此方案基本都能很好的完成适配,切记别在项目中用rem单位就行,这玩意儿不行,拜拜~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。